2016-08-05 9 views
0

이 질문에 대한 몇 가지 변형이 있지만 주변 문제를 해결할 수는 없습니다. PHP와 Delphi에서 암호화/암호화 해제 시도 중 내가 델파이의 일부 설정을 놓쳤다 고 가정하고 UTF-8과 관련이 있다고 가정합니다.Delphi/PHP LockBox 암호화 AES ECB

http://aesencryption.net/을 PHP 예제로 사용하여 얻으려는 결과입니다. 이미지 불어
암호 = 123
키 = 시험
128 비트
내가 델파이
이 암호화되지 않은 수 있도록하려면/XKfGQ ==

uuIikEZSC9Sa1HAt하는 암호화 델파이 XE5
을 사용하고 있습니다 https://github.com/SeanBDurkin/tplockbox
와 내가 얻을 해독 델파이 내부에서 작업하지만, PHP 암호화 된 버전 문자열은

델파이를 암호화 다른/암호화 할 수 있습니다 vpdeLlfnxTGrSsa2TpbFvg 123 여기


를 == 델파이 암호화

function TForm3.EncryptV2(plainText: UTF8String): String; 
var CipherText : string; 
    FLibrary: TCryptographicLibrary; 
    FCodec: TCodec; 
begin 
    mmo1.Lines.Add('plaintext = ' + plainText); 

FLibrary := TCryptographicLibrary.Create(Self); 
    try 
    FCodec := TCodec.Create(Self); 
    try 
     FCodec.CryptoLibrary := FLibrary; 
     FCodec.StreamCipherId := BlockCipher_ProgId; 
     FCodec.BlockCipherId := Format(AES_ProgId, [256]); 
     FCodec.ChainModeId := ECB_ProgId; ; 
     FCodec.UTF8Password := 'test'; 
     FCodec.EncryptString(plainText, CipherText, Tencoding.UTF8); 
     FCodec.Burn; 

     result := CipherText; 
    finally 
     FCodec.Free; 
    end; 
    finally 
    FLibrary.Free; 
    end; 
end; 

해독

function TForm3.DecryptV2(encryptedText: UTF8String): String; 
    var plainText : string; 
    FLibrary: TCryptographicLibrary; 
    FCodec: TCodec; 
begin 
    FLibrary := TCryptographicLibrary.Create(Self); 
    try 
    FCodec := TCodec.Create(Self); 
    try 
     FCodec.CryptoLibrary := FLibrary; 
     FCodec.StreamCipherId := BlockCipher_ProgId; 
     FCodec.BlockCipherId := Format(AES_ProgId, [256]); 
     FCodec.ChainModeId := ECB_ProgId; ; 
     FCodec.UTF8Password := 'test'; 

     mmo1.Lines.Add('Encrypted Text = ' + encryptedText); 
     FCodec.DecryptString(plainText, encryptedText,Tencoding.UTF8); 
     mmo1.Lines.Add('DeCrypted Text = ' + plainText); 
     result := plainText; 
    finally 
     FCodec.Free; 
    end; 
    finally 
    FLibrary.Free; 
    end; 
end; 

사람의 간단한 예를 들어 어떤 제안이 무엇입니까?

enter image description here

+1

, 암호화에 대한 참조로 aesencryption.net 사용하지 마십시오 . –

+1

** 절대로 [ECB 모드] (http://crypto.stackexchange.com/q/14487/13022) **를 사용하지 마십시오. 결정 론적이며 따라서 의미 론적으로 안전하지 않습니다. 적어도 CBC (http://crypto.stackexchange.com/q/22260/13022) 또는 [CTR] (http://crypto.stackexchange.com/a/2378/)와 같은 무작위 모드를 사용해야합니다. 13022). [패딩 오라클 공격] (http://crypto.stackexchange.com/q/18185/13022)과 같은 공격이 불가능하도록 암호문을 인증하는 것이 좋습니다. GCM 또는 EAX와 같은 인증 된 모드 나 [암호화 후 MAC] (http://crypto.stackexchange.com/q/202/13022) 구성표를 사용하여이 작업을 수행 할 수 있습니다. –

+0

나는 CBC 나 다른 것들도 일치시킬 수 없었다. 내가 시도해보고 쉬운 것을 먼저 얻은 다음 다른 것들과 일치하지 않는 동일한 이유인지 확인하십시오 – Dangas56

답변

0

확실하지 록 박스에 무슨 일이지만, 여기에는 OpenSSL을 사용하여 aesencryption 일치 코드, OverbyteIcsLibeay 장치는 http://wiki.overbyte.be/wiki/index.php/ICS_Download

{$APPTYPE CONSOLE} 
program aestest; 

uses System.SysUtils, System.NetEncoding, OverbyteIcsLibeay; 

type 
    TKey128 = packed array [0..15] of byte; 
    TIV128 = packed array [0..15] of byte; 

function AES128EncryptDecrypt(var Source: TBytes; const Key: TKey128; 
    const InitializationVector: TIV128; Encrypt: boolean): boolean; 
var 
    IV: TIV128; 
    CipherCtx: PEVP_CIPHER_CTX; 
    Dest: TBytes; 
    OutLen: Integer; 
begin 
    Result := False; 
    IV := InitializationVector; 
    LoadLibeayEx; 
    SetLength(Dest, Length(Source) + Length(Key)); 
    CipherCtx := f_EVP_CIPHER_CTX_new; 
    try 
    f_EVP_CIPHER_CTX_init(CipherCtx); 
    if Encrypt then 
    begin 
     if f_EVP_EncryptInit_ex(CipherCtx, f_EVP_aes_128_ecb(), nil, @Key[0], @IV[0]) then 
     begin 
     Result := f_EVP_EncryptUpdate(CipherCtx, @Dest[Low(Dest)], OutLen, @Source[Low(Source)], Length(Source)); 
     if Result then 
      Source := Copy(Dest, Low(Dest), OutLen); 
     end; 
    end 
    else 
    begin 
     if f_EVP_DecryptInit_ex(CipherCtx, f_EVP_aes_128_ecb(), nil, @Key[0], @IV[0]) then 
     begin 
     SetLength(Source, Length(Source) + Length(Key)); 
     Result := f_EVP_DecryptUpdate(CipherCtx, @Dest[Low(Dest)], OutLen, @Source[Low(Source)], Length(Source)); 
     if Result then 
      Source := Copy(Dest, Low(Dest), OutLen); 
     end; 
    end; 
    f_EVP_CIPHER_CTX_cleanup(CipherCtx); 
    finally 
    f_EVP_CIPHER_CTX_free(CipherCtx); 
    end; 
end; 

function AES128Encrypt(var Source: TBytes; const Key: TKey128; 
    const InitializationVector: TIV128): boolean; 
begin 
    Result := AES128EncryptDecrypt(Source, Key, InitializationVector, True); 
end; 

function AES128Decrypt(var Source: TBytes; const Key: TKey128; 
    const InitializationVector: TIV128): boolean; 
begin 
    Result := AES128EncryptDecrypt(Source, Key, InitializationVector, False); 
end; 

const 
    DefaultInitializationVector: TIV128 = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 

var 
    B: TBytes; 
    KeyBytes: TBytes; 
    KeyPass: TKey128; 
begin 
    // padding text with zeroes up to 16 bytes 
    B := TEncoding.UTF8.GetBytes('123'#0#0#0#0#0#0#0#0#0#0#0#0#0); 

    // encrypting 
    KeyBytes := TEncoding.UTF8.GetBytes('test'); 
    Move(KeyBytes[0], KeyPass[0], Length(KeyBytes)); 
    AES128Encrypt(B, KeyPass, DefaultInitializationVector); 
    Writeln(TNetEncoding.Base64.EncodeBytesToString(B)); 

    // decrypting 
    AES128Decrypt(B, KeyPass, DefaultInitializationVector); 
    Writeln(TEncoding.UTF8.GetString(B)); 
end. 

는 또한 f_EVP_aes_128_ecb 기능이 현재 OverbyteIcsLibeay에 포함되지 ICS 라이브러리입니다 인터페이스 섹션에이 줄을 추가해야합니다.

f_EVP_aes_128_ecb   : function: PEVP_CIPHER; cdecl = nil; 

및 LoadLibeay 절차에 다음 행이 나쁜 모드 (ECB), 나쁜 패딩 (제로 패딩)을 사용하며 인증을 지원하지 않기 때문에

f_EVP_aes_128_ecb := GetProcAddress(GLIBEAY_DLL_Handle, 'EVP_aes_128_ecb'); 
if not Assigned(f_EVP_aes_128_ecb) then 
    raise Exception.Create(Msg + 'EVP_aes_128_ecb');