Registriert seit: 17. Mai 2006
Ort: Leipzig
283 Beiträge
Delphi XE2 Professional
|
AW: DEC 5.2 mit Vector deccipher Umbau von DOT net auf Delphi
25. Mär 2013, 14:52
Soo da ich es jetzt hinbekommen habe, lasse ich die Allgemeinheit mal an der Lösung teilhaben:
Zum einen musste der C#-Code angepasst werden, da die KDF sich nicht standardkonform verhält:
Code:
public static string Encrypt(string PlainText, string Password, string InitialVector)
{
if (string.IsNullOrEmpty(PlainText))
return "";
byte[] InitialVectorBytes = new byte[16];
Encoding.ASCII.GetBytes(InitialVector, 0, 16, InitialVectorBytes, 0);
byte[] SaltValueBytes = Encoding.ASCII.GetBytes(Salt);
byte[] PlainTextBytes = Encoding.UTF8.GetBytes(PlainText);
Rfc2898DeriveBytes DerivedPassword = new Rfc2898DeriveBytes(Password, SaltValueBytes, PasswordIterations); //formals PasswordDeriveBytes
byte[] KeyBytes = DerivedPassword.GetBytes(KeySize / 8);
RijndaelManaged SymmetricKey = new RijndaelManaged();
SymmetricKey.Mode = CipherMode.CBC;
byte[] CipherTextBytes = null;
using (ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes))
{
using (MemoryStream MemStream = new MemoryStream())
{
using (CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write))
{
CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
CryptoStream.FlushFinalBlock();
CipherTextBytes = MemStream.ToArray();
MemStream.Close();
CryptoStream.Close();
}
}
}
SymmetricKey.Clear();
return Convert.ToBase64String(CipherTextBytes);
}
Da wir einen hier einen Timestamp (z.B. 2013-03-13 11:10:04.500) als IV benutzen, nehmen wir nur die ersten 16 Bytes für den IV (InitialVectorBytes).
Und die Entschlüsselungs-Funktion in Delphi sieht dann so aus:
Delphi-Quellcode:
uses
kdf, hash, sha1, aes_cbc, aes_type, DECFmt;
function DecryptBase64Str(const CipherText_Base64: Binary; const Password: Binary; const Salt: Binary; const InitVector: RawByteString): RawByteString;
var
hash: PHashDesc;
key: array[0..31] of byte;
ctx: TAESContext;
aesblck: TAESBlock;
decodedTxt: RawByteString;
i: Integer;
lastByte: Byte;
resLength: Integer;
isPadded: Boolean;
begin
hash:= FindHash_by_ID(_SHA1);
pbkdf2(hash,@Password[1], Length(password),@Salt[1],Length(Salt),2,key,32);
for i := 1 to 16 do
aesblck[i-1]:= Byte(initvector[i]);
decodedTxt:= TFormat_MIME64.Decode(CipherText_Base64);
Result:= decodedTxt;
ctx.IV:= aesblck;
AES_CBC_Init_Decr(key,256,aesblck,ctx);
AES_CBC_Decrypt(@decodedTxt[1],@result[1],length(decodedTxt),ctx);
//PKCS#7-Padding umkehren
resLength:= Length(Result);
lastByte:= Byte(Result[resLength]);
isPadded:= True;
for i := resLength downto resLength-lastByte+1 do
if Byte(Result[i]) = lastByte then
Continue
else
begin
isPadded:= False;
Break;
end;
if isPadded then
Result:= Copy(Result,1,resLength-lastByte);
end;
Credits gehen an gammatester für seine Geduld mit mir (Danke dafür) und natürlich für seine Crypto-Lib
Billy Gerwitz "Bei der Softwareentwicklung suchen wir nicht den richtigen Weg, sondern den am wenigsten falschen." - frei nach V. Hillmann
|