1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| //---------------------------------------------------------------------------
function TTestWebSocketsForm.MakeAES(const Input, Key: AnsiString; out Confirm: AnsiString; AESFinal: boolean): AnsiString;
var
pbContent: PByte;
pbResult: PByte;
pbConfirm: PByte;
hCryptProvider: HCRYPTPROV;
KeyBlob: packed record
Header: BLOBHEADER;
Size: DWORD;
Data: array[0..15] of Byte;
end;
hKey, hEncryptKey, hDecryptKey: HCRYPTKEY;
dwKeyCypherMode: DWORD;
InputLen, ResultLen: DWORD;
const
PROV_RSA_AES = 24;
CALG_AES_128 = $0000660e;
begin
pbContent := Pointer(PAnsiChar(Input));
Result := '';
// MS_ENH_RSA_AES_PROV
if CryptAcquireContext(@hCryptProvider, nil, nil, PROV_RSA_AES, CRYPT_VERIFYCONTEXT) then
begin
KeyBlob.Header.bType := PLAINTEXTKEYBLOB;
keyBlob.Header.bVersion := CUR_BLOB_VERSION;
keyBlob.Header.reserved := 0;
keyBlob.Header.aiKeyAlg := CALG_AES_128;
keyBlob.Size := Length(Key) * SizeOf(AnsiChar);
CopyMemory(@keyBlob.Data[0], @Key[1], keyBlob.Size);
if CryptImportKey(hCryptProvider, @KeyBlob, SizeOf(KeyBlob), 0, 0, @hKey) then
begin
if CryptDuplicateKey(hKey, nil, 0, @hEncryptKey) then
begin
if CryptDuplicateKey(hKey, nil, 0, @hDecryptKey) then
begin
// Très important, une clé pour Encrypt et une autre pour Decrypt sinon cela fausse le calcul, curieux en ECB cela ne devrait pas, en CBC ou CFB semble tout à fait logique puisque le bloc précédent est utilisé pour le chiffrage du suivant ...
dwKeyCypherMode := CRYPT_MODE_ECB;
CryptSetKeyParam(hEncryptKey, KP_MODE, @dwKeyCypherMode, 0);
CryptSetKeyParam(hDecryptKey, KP_MODE, @dwKeyCypherMode, 0);
Result := Input;
InputLen := Length(Result) * SizeOf(AnsiChar);
ResultLen := InputLen;
if CryptEncrypt(hEncryptKey, 0, AESFinal, 0, nil, @ResultLen, 0) then
begin
SetLength(Result, ResultLen);
pbResult := Pointer(PAnsiChar(Result));
if CryptEncrypt(hEncryptKey, 0, AESFinal, 0, pbResult, @InputLen, ResultLen) then
begin
SetLength(Confirm, ResultLen);
pbConfirm := Pointer(PAnsiChar(Confirm));
CopyMemory(pbConfirm, pbResult, ResultLen);
if CryptDecrypt(hDecryptKey, 0, AESFinal, 0, pbConfirm, @InputLen) then
SetLength(Confirm, InputLen)
else
Confirm := IntToStr(GetLastError());
end
else
Result := IntToStr(GetLastError());
end;
CryptDestroyKey(hDecryptKey);
end;
CryptDestroyKey(hEncryptKey);
end;
CryptDestroyKey(hKey);
end;
CryptReleaseContext(hCryptProvider, 0);
end;
end; |