Einzelnen Beitrag anzeigen

ToFaceTeKilla

Registriert seit: 17. Mai 2006
Ort: Leipzig
283 Beiträge
 
Delphi XE2 Professional
 
#21

AW: DEC 5.2 mit Vector deccipher Umbau von DOT net auf Delphi

  Alt 25. Mär 2013, 13: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
  Mit Zitat antworten Zitat