Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > шифрование


Автор: bagos 4.11.2010, 02:10
Надо разобраться с функцией cryptprotectdata и cryptpunrotectdata, нашел код на дельфи, но он не работает не понимаю почему.
Может кто работал с этими функциями?
Код

unit Unit2;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
 
const
  CRYPTPROTECT_LOCAL_MACHINE = 4; // ??
 
type
  TForm2 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
  TCharArray = Array[0..1023] Of Char;
  _TOKEN_USER = record
    User: SID_AND_ATTRIBUTES;
  end;
  TOKEN_USER = _TOKEN_USER;
  TTokenUser = TOKEN_USER;
  PTokenUser = ^TOKEN_USER;
  _CREDENTIAL_ATTRIBUTEA = record
    Keyword: LPSTR;
    Flags: DWORD;
    ValueSize: DWORD;
    Value: PBYTE;
  end;
  PCREDENTIAL_ATTRIBUTE = ^_CREDENTIAL_ATTRIBUTEA;
_CREDENTIALA = record
    Flags: DWORD;
    Type_: DWORD;
    TargetName: LPSTR;
    Comment: LPSTR;
    LastWritten: FILETIME;
    CredentialBlobSize: DWORD;
    CredentialBlob: PBYTE;
    Persist: DWORD;
    AttributeCount: DWORD;
    Attributes: PCREDENTIAL_ATTRIBUTE;
    TargetAlias: LPSTR;
    UserName: LPSTR;
  end;
  PCREDENTIAL = array of ^_CREDENTIALA;
  _CRYPTPROTECT_PROMPTSTRUCT = record
    cbSize: DWORD;
    dwPromptFlags: DWORD;
    hwndApp: HWND;
    szPrompt: LPCWSTR;
  end;
  PCRYPTPROTECT_PROMPTSTRUCT = ^_CRYPTPROTECT_PROMPTSTRUCT;
  _CRYPTOAPI_BLOB = record
    cbData: DWORD;
    pbData: PBYTE;
  end;
  DATA_BLOB = _CRYPTOAPI_BLOB;
  PDATA_BLOB = ^DATA_BLOB; // ??
 
 
var
  Form2: TForm2;
 
{
CryptProtectData
http://msdn.microsoft.com/en-us/library/aa380261%28VS.85%29.aspx
BOOL WINAPI CryptProtectData(
  __in      DATA_BLOB *pDataIn,
  __in      LPCWSTR szDataDescr,
  __in      DATA_BLOB *pOptionalEntropy,
  __in      PVOID pvReserved,
  __in_opt  CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct,
  __in      DWORD dwFlags,
  __out     DATA_BLOB *pDataOut
);
 
CryptUnprotectData
http://msdn.microsoft.com/en-us/library/aa380882%28VS.85%29.aspx
BOOL WINAPI CryptUnprotectData(
  __in       DATA_BLOB *pDataIn,
  __out_opt  LPWSTR *ppszDataDescr,
  __in_opt   DATA_BLOB *pOptionalEntropy,
  __in       PVOID pvReserved,
  __in_opt   CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct,
  __in       DWORD dwFlags,
  __out      DATA_BLOB *pDataOut
);
}
 
 
function CryptProtectData(pDataIn: PDATABLOB;
                          ppszDataDescr: PLPCWSTR;//?? Error
                          pOptionalEntropy: PDATA_BLOB;
                          pvReserved: Pointer;
                          pPromptStruct: PCRYPTPROTECT_PROMPTSTRUCT;
                          dwFlags: DWORD;
                          pDataOut: PDATA_BLOB)
                          : BOOL;
                          stdcall;
                          external 'crypt32.dll' Name 'CryptProtectData';
 
function CryptUnprotectData(pDataIn: PDATA_BLOB;
                            ppszDataDescr: PLPWSTR;
                            pOptionalEntropy: PDATA_BLOB;
                            pvReserved: Pointer;
                            pPromptStruct: PCRYPTPROTECT_PROMPTSTRUCT;
                            dwFlags: DWORD;
                            pDataOut: PDATA_BLOB)
                            : BOOL;
                            stdcall;
                            external 'crypt32.dll' Name 'CryptUnprotectData';
 
 
implementation
 
{$R *.dfm}
 
 
function EncryptPassword(Password: string): string;
var
  DataIn: DATA_BLOB;
  dwFlags: DWORD;
  DataOut: DATA_BLOB;
  I: Integer;
  P: PByte;
begin
  Result := '';
  DataIn.cbData := Length(Password);
  DataIn.pbData := Pointer(PChar(Password));
  dwFlags := CRYPTPROTECT_LOCAL_MACHINE;
  if CryptProtectData(@DataIn, 'Password', nil, nil, nil, dwFlags, DataOut) then begin
    P := DataOut.pbData;
    I := DataOut.cbData;
    Result := IntToHex(I, 8);
    while (I > 0) do begin
      Dec(I);
      Result := Result + IntToHex(P^, 2);
      Inc(P);
    end;
    LocalFree(Cardinal(DataOut.pbData));
  end;
end;
 
function DecryptPassword(Password: string): string;
var
  DataIn: DATA_BLOB;
  dwFlags: DWORD;
  DataOut: DATA_BLOB;
  I, J: Integer;
  P: PByte;
  DataDescr: LPWSTR;
begin
  Result := '';
  if (Length(Password) > 0) then begin
    DataIn.cbData := StrToIntDef('$' + Copy(Password, 1, 8), 0);
    if (DataIn.cbData > 0) then begin
      GetMem(DataIn.pbData, DataIn.cbData);
      I := DataIn.cbData;
      J := 9;
      P := DataIn.pbData;
      while (I > 0) and (J < Length(Password)) do begin
        Dec(I);
        P^ := StrToInt('$' + Copy(Password, J, 2));
        Inc(P);
        Inc(J, 2);
      end;
      dwFlags := CRYPTPROTECT_LOCAL_MACHINE;
      if CryptUnprotectData(@DataIn, DataDescr, nil, nil, nil, dwFlags, DataOut) then begin
        Result := Copy(string(DataOut.pbData), 0, DataOut.cbData);
        LocalFree(Cardinal(DataOut.pbData));
      end;
    end;
  end;
end;
 

Автор: kami 4.11.2010, 21:23
http://sourceforge.net/projects/jedi-apilib/files/ не помогут? (в частности - jwaWinCrypt)

Автор: bagos 4.11.2010, 22:06
можно поподробней что это?

Автор: Snowy 9.11.2010, 12:38
Цитата(bagos @  4.11.2010,  02:10 Найти цитируемый пост)
нашел код на дельфи, но он не работает не понимаю почему.
наверное потому, что это код для Delphi < 2009, а у тебя >= 2009
Для дельфи от 2009 и выше, нужно старый код дорабатывать напильником с поправкой на юникод.
Простой способ - замена string на AnsiString.
В коде явное присвоение стрингу массива байт. А для юникода это ошибка.
На будущее - указывай версию дельфи.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)