如何在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);
}
}
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
