如何在Delphi中使用密码对AES-128加密字符串并在C#中解密?
发布时间:2020-12-15 09:44:58 所属栏目:大数据 来源:网络整理
导读:我想用AES-128用密码加密Delphi中的字符串.我想将它上传到我的服务器,并能够在C#中使用相同的密码进行解密. 在Delphi中,我使用的是TurboPower LockBox 3: function EncryptText_AES_128(input: string; password: string): string;var Codec: TCodec; Ciphe
我想用AES-128用密码加密Delphi中的字符串.我想将它上传到我的服务器,并能够在C#中使用相同的密码进行解密.
在Delphi中,我使用的是TurboPower LockBox 3: function EncryptText_AES_128(input: string; password: string): string; var Codec: TCodec; CipherText: AnsiString; begin Codec := TCodec.Create(nil); try Codec.CryptoLibrary := TCryptographicLibrary.Create(Codec); // Codec.StreamCipherId := BlockCipher_ProgID; Codec.BlockCipherId := Format(AES_ProgId,[128]); Codec.ChainModeId := CBC_ProgId; // Codec.Password := Password; Codec.EncryptString(input,CipherText); // Result := string(CipherText); finally Codec.Free; end; end; 如何在C#中解密生成的字符串?我可以改变Delphi代码.什么都没有生产.我甚至没有坚持使用LockBox.但是,我想避免将它放在P / Invoke的DLL中. (我的例子表明我的加密序列本身就是一个字符串.这对我来说不是必需的.字节流很好.) 解决方法
我终于找到了Delphi和C#之间用于AES-128的兼容解决方案.它也适用于Wine.这是我的Delphi代码:
unit TntLXCryptoUtils; interface function AES128_Encrypt(Value,Password: string): string; function AES128_Decrypt(Value,Password: string): string; implementation uses SysUtils,Windows,IdCoderMIME,TntLXUtils; //------------------------------------------------------------------------------------------------------------------------- // Base64 Encode/Decode //------------------------------------------------------------------------------------------------------------------------- function Base64_Encode(Value: TBytes): string; var Encoder: TIdEncoderMIME; begin Encoder := TIdEncoderMIME.Create(nil); try Result := Encoder.EncodeBytes(Value); finally Encoder.Free; end; end; function Base64_Decode(Value: string): TBytes; var Encoder: TIdDecoderMIME; begin Encoder := TIdDecoderMIME.Create(nil); try Result := Encoder.DecodeBytes(Value); finally Encoder.Free; end; end; //------------------------------------------------------------------------------------------------------------------------- // WinCrypt.h //------------------------------------------------------------------------------------------------------------------------- type HCRYPTPROV = Cardinal; HCRYPTKEY = Cardinal; ALG_ID = Cardinal; HCRYPTHASH = Cardinal; const _lib_ADVAPI32 = 'ADVAPI32.dll'; CALG_SHA_256 = 32780; CALG_AES_128 = 26126; CRYPT_NEWKEYSET = $00000008; PROV_RSA_AES = 24; KP_MODE = 4; CRYPT_MODE_CBC = 1; function CryptAcquireContext(var Prov: HCRYPTPROV; Container: PChar; Provider: PChar; ProvType: LongWord; Flags: LongWord): LongBool; stdcall; external _lib_ADVAPI32 name 'CryptAcquireContextW'; function CryptDeriveKey(Prov: HCRYPTPROV; Algid: ALG_ID; BaseData: HCRYPTHASH; Flags: LongWord; var Key: HCRYPTKEY): LongBool; stdcall; external _lib_ADVAPI32 name 'CryptDeriveKey'; function CryptSetKeyParam(hKey: HCRYPTKEY; dwParam: LongInt; pbData: PBYTE; dwFlags: LongInt): LongBool stdcall; stdcall; external _lib_ADVAPI32 name 'CryptSetKeyParam'; function CryptEncrypt(Key: HCRYPTKEY; Hash: HCRYPTHASH; Final: LongBool; Flags: LongWord; pbData: PBYTE; var Len: LongInt; BufLen: LongInt): LongBool;stdcall;external _lib_ADVAPI32 name 'CryptEncrypt'; function CryptDecrypt(Key: HCRYPTKEY; Hash: HCRYPTHASH; Final: LongBool; Flags: LongWord; pbData: PBYTE; var Len: LongInt): LongBool; stdcall; external _lib_ADVAPI32 name 'CryptDecrypt'; function CryptCreateHash(Prov: HCRYPTPROV; Algid: ALG_ID; Key: HCRYPTKEY; Flags: LongWord; var Hash: HCRYPTHASH): LongBool; stdcall; external _lib_ADVAPI32 name 'CryptCreateHash'; function CryptHashData(Hash: HCRYPTHASH; Data: PChar; DataLen: LongWord; Flags: LongWord): LongBool; stdcall; external _lib_ADVAPI32 name 'CryptHashData'; function CryptReleaseContext(hProv: HCRYPTPROV; dwFlags: LongWord): LongBool; stdcall; external _lib_ADVAPI32 name 'CryptReleaseContext'; function CryptDestroyHash(hHash: HCRYPTHASH): LongBool; stdcall; external _lib_ADVAPI32 name 'CryptDestroyHash'; function CryptDestroyKey(hKey: HCRYPTKEY): LongBool; stdcall; external _lib_ADVAPI32 name 'CryptDestroyKey'; //------------------------------------------------------------------------------------------------------------------------- {$WARN SYMBOL_PLATFORM OFF} function __CryptAcquireContext(ProviderType: Integer): HCRYPTPROV; begin if (not CryptAcquireContext(Result,nil,ProviderType,0)) then begin if HRESULT(GetLastError) = NTE_BAD_KEYSET then Win32Check(CryptAcquireContext(Result,CRYPT_NEWKEYSET)) else RaiseLastOSError; end; end; function __AES128_DeriveKeyFromPassword(m_hProv: HCRYPTPROV; Password: string): HCRYPTKEY; var hHash: HCRYPTHASH; Mode: DWORD; begin Win32Check(CryptCreateHash(m_hProv,CALG_SHA_256,hHash)); try Win32Check(CryptHashData(hHash,PChar(Password),Length(Password) * SizeOf(Char),0)); Win32Check(CryptDeriveKey(m_hProv,CALG_AES_128,hHash,Result)); // Wine uses a different default mode of CRYPT_MODE_EBC Mode := CRYPT_MODE_CBC; Win32Check(CryptSetKeyParam(Result,KP_MODE,Pointer(@Mode),0)); finally CryptDestroyHash(hHash); end; end; function AES128_Encrypt(Value,Password: string): string; var hCProv: HCRYPTPROV; hKey: HCRYPTKEY; lul_datalen: Integer; lul_buflen: Integer; Buffer: TBytes; begin Assert(Password <> ''); if (Value = '') then Result := '' else begin hCProv := __CryptAcquireContext(PROV_RSA_AES); try hKey := __AES128_DeriveKeyFromPassword(hCProv,Password); try // allocate buffer space lul_datalen := Length(Value) * SizeOf(Char); Buffer := TEncoding.Unicode.GetBytes(Value + ' '); lul_buflen := Length(Buffer); // encrypt to buffer Win32Check(CryptEncrypt(hKey,True,@Buffer[0],lul_datalen,lul_buflen)); SetLength(Buffer,lul_datalen); // base 64 result Result := Base64_Encode(Buffer); finally CryptDestroyKey(hKey); end; finally CryptReleaseContext(hCProv,0); end; end; end; function AES128_Decrypt(Value,Password: string): string; var hCProv: HCRYPTPROV; hKey: HCRYPTKEY; lul_datalen: Integer; Buffer: TBytes; begin Assert(Password <> ''); if Value = '' then Result := '' else begin hCProv := __CryptAcquireContext(PROV_RSA_AES); try hKey := __AES128_DeriveKeyFromPassword(hCProv,Password); try // decode base64 Buffer := Base64_Decode(Value); // allocate buffer space lul_datalen := Length(Buffer); // decrypt buffer to to string Win32Check(CryptDecrypt(hKey,lul_datalen)); Result := TEncoding.Unicode.GetString(Buffer,lul_datalen); finally CryptDestroyKey(hKey); end; finally CryptReleaseContext(hCProv,0); end; end; end; end. 这是我的C#代码: public class TntCryptoUtils { private static ICryptoTransform __Get_AES128_Transform(string password,bool AsDecryptor) { const int KEY_SIZE = 16; var sha256CryptoServiceProvider = new SHA256CryptoServiceProvider(); var hash = sha256CryptoServiceProvider.ComputeHash(Encoding.Unicode.GetBytes(password)); var key = new byte[KEY_SIZE]; var iv = new byte[KEY_SIZE]; Buffer.BlockCopy(hash,key,KEY_SIZE); //Buffer.BlockCopy(hash,KEY_SIZE,iv,KEY_SIZE); // On the Windows side,the IV is always 0 (zero) // if (AsDecryptor) return new AesCryptoServiceProvider().CreateDecryptor(key,iv); else return new AesCryptoServiceProvider().CreateEncryptor(key,iv); } public static string AES128_Encrypt(string Value,string Password) { byte[] Buffer = Encoding.Unicode.GetBytes(Value); // using (ICryptoTransform transform = __Get_AES128_Transform(Password,false)) { byte[] encyptedBlob = transform.TransformFinalBlock(Buffer,Buffer.Length); return Convert.ToBase64String(encyptedBlob); } } public static string AES128_Decrypt(string Value,string Password) { byte[] Buffer = Convert.FromBase64String(Value); // using (ICryptoTransform transform = __Get_AES128_Transform(Password,true)) { byte[] decyptedBlob = transform.TransformFinalBlock(Buffer,Buffer.Length); return Encoding.Unicode.GetString(decyptedBlob); } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |