2016-08-05 164 views
0

这个问题有几个变种,但我一直无法解决这个问题。尝试在PHP和Delphi中加密/解密 我假设我错过了Delphi中的一些设置,它使用UTF-8德尔福/ PHP LockBox加密AES ECB

使用http://aesencryption.net/作为PHP示例我们试图获得的结果。图片吹
密码= 123
重点=测试
128位
加密到uuIikEZSC9Sa1HAt/XKfGQ ==

我希望能够在Delphi
来解密方法这个 我用Delphi XE5
https://github.com/SeanBDurkin/tplockbox
我可以得到加密/ DeCrypt在德尔福工作,但PHP加密版本字符串是不同的

德尔福加密123 vpdeLlfnxTGrSsa2TpbFvg ==

这里是德尔福加密

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作为加密参考,因为它使用了不良模式(ECB),一个坏的填充(零填充)和不支持认证。 –

+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)。最好是对密文进行身份验证,以便像[padding oracle attack](http://crypto.stackexchange.com/q/18185/13022)这样的攻击是不可能的。这可以通过验证模式(如GCM或EAX)或[加密 - 然后MAC](http://crypto.stackexchange.com/q/202/13022)方案完成。 –

+0

我无法让Cbc或任何其他人匹配。我以为我会试着先让容易的人先走,然后看看是否与其他人不相同的原因 – Dangas56

回答

0

不知道什么是错的密码箱,但这里是代码aesencryption使用OpenSSL匹配,OverbyteIcsLibeay单位是从ICS库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. 

而且目前不包括在OverbyteIcsLibeay f_EVP_aes_128_ecb功能,所以您需要将此行添加到接口部分

f_EVP_aes_128_ecb   : function: PEVP_CIPHER; cdecl = nil; 

和这些行LoadLibeay程序

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');