|
Registriert seit: 28. Mär 2009 73 Beiträge Delphi XE6 Professional |
#9
Wow, erstmal Danke das sich so viele daran beteiligen.
Problem Beschreibung: Ein FileStream der nur aus Sonderzeichen besteht(gecryptet) hat unterschiedliche Hash-Werte im russischen und im deutschen Windows. Dh. die Streams sind unterschiedlich. Der Hash dient mir dazu um die entschlüsselten Daten auf ihre Korrektheit zu überprüfen. Hier meine Methode wie ich den Hash-Werte bilde:
Delphi-Quellcode:
Nicht gecryptete Zeichenketten sind gleich da keine Sonderzeichen enthalten sind.
Function GetHashFromStream(AFileStream: TFileStream): String ;
Var AHash: TDCP_Hash ; i, Read, allreaded, willread: Integer ; s: String ; Buffer: Array [0 .. 16383] Of byte ; Begin Result := '' ; AHash := TDCP_Hash(TDCP_SHA512) ; AHash.Init ; Try Read := 0 ; allreaded := 0 ; AFileStream.Position := 0 ; Repeat // read into the buffer willread := AFileStream.Size - AFileStream.Position ; If willread > High(Buffer) Then Read := AFileStream.Read(Buffer[0], High(Buffer) + 1) Else Read := AFileStream.Read(Buffer[0], willread) ; inc(allreaded, Read) ; // hash the buffer with each of the selected hashes AHash.Update(Buffer, Read) ; Until allreaded >= AFileStream.Size ; SetLength(HashDigest, AHash.GetHashSize Div 8) ; AHash.Final(HashDigest[0]) ; // get the output // cast HashDigest to String (ByteToStr) Result := HashDigestToStr ; Except On Exception Do Raise ECryptGetHash ; End ; End ; ![]() Dann könnte es also doch am Unicode liegen, oder genauer gesagt vermutlich irgendwo an einer Ansi<>Unicodeumwandlung, bei welcher die die aktuelle CodePage des Systems verwendet wird.
![]() Das wäre allerdings eine völlige Bankrotterklärung für Verschlüsselungstechniken! Wenn Du jedoch meinst, daß Delphi-Programmierer mit ihrer häufigen Stringfixierung so etwas produzieren, kann man zu stimmen. Die Abhilfe ist allerdings auch schon lange bekannt: Ver/entschlüsselt werden nur Binärdaten, was ja wohl gerade bei Dateien auch kein großes Problem ist.
Hier noch meine Ent- und Verschlüsselungsmethoden: Die Funktionen stammen aus einer Klasse, es kann also durchaus sein das einige Variablen nicht initialisert sind, da ich das in anderen Methoden schon getan habe. Die Funktionen funktionieren auch einwandfrei in einem deutsch sprachigen Windows.
Delphi-Quellcode:
Den einzigen Strings die ich bei den Methoden verwende sind die Passphrase(Zum testen im Quellcode also Unicode) und der HashWert der ans Dateiende geschrieben wird ist auch im RU-Win gleich.
Procedure EnCryptStream(Var InFStream, OutFStream: TFileStream ;
Passphrase: String) ; Var AHashValue, TmpFile: String ; Buffer: TBytes ; i: Integer ; Begin InFStream.Position := 0 ; OutFStream.Position := 0 ; Try AHashValue := GetHashFromStream(InFStream) ; // CreateSalt; For i := 0 To 7 Do Begin // just fill the salt with random values // (crypto secure PRNG would be better but not _really_ necessary) Salt[i] := 1 + Random(255) ; End ; // InitHashDiggest; HashType.Init ; // hash the salt HashType.Update(Self.Salt[ Low(Salt)], High(Self.Salt) + 1) ; HashType.UpdateStr(Passphrase) ; // and the passphrase // store the output in HashDigest HashType.Final(Self.HashDigest[0]) ; // write the salt so we can encrypt! OutFStream.WriteBuffer(Self.Salt[ Low(Salt)], High(Self.Salt) + 1) ; // init the cipher with the hash // if the cipher is a block cipher we need an initialisation vector(IV) If (CipherType Is TDCP_blockcipher) Then Begin SetLength(CipherIV, TDCP_blockcipher(CipherType).BlockSize Div 8); // create random values for the IV For i := 0 To High(Self.CipherIV) Do Self.CipherIV[i] := 1 + Random(255) ; // write the IVector OutFStream.WriteBuffer(Self.CipherIV[0], High(Self.CipherIV) + 1) ; // initialise the cipher with the hash as key CipherType.Init(Self.HashDigest[0], Min(CipherType.MaxKeySize, HashType.HashSize), Self.CipherIV) ; // use CBC chaining when encrypting TDCP_blockcipher(CipherType).CipherMode := cmCBC ; End Else // initialise the cipher with the hash as key CipherType.Init(Self.HashDigest[0], Min(CipherType.MaxKeySize, HashType.HashSize), Nil) ; // encrypt the entire file CipherType.EnCryptStream(InFStream, OutFStream, InFStream.Size) ; CipherType.Burn ; // important! get rid of keying information // write the hash of the not encrypted stream to check Buffer := BytesOf(AHashValue) ; OutFStream.WriteBuffer(Buffer[ Low(Buffer)], length(AHashValue)) ; Except On Exception Do Raise ECryptEncryptStream ; End ; End ; Function DeCryptStream(Var AFStream: TFileStream ; Passphrase: String): TStringList ; Var TempStream: TFileStream ; HashOfStream, HashInStream, TmpFile: String ; HashLength, PositionOfData, MinLengthStream: Cardinal ; Buffer: Array Of byte ; AByte: byte ; Begin Try AFStream.Position := 0 ; // Get hash length with 2 diggits(hex value) HashLength := HashType.GetHashSize Div 8 * 2 ; MinLengthStream := HashLength + ( High(Salt) + 1) + ( High(CipherIV) + 1) ; If MinLengthStream > AFStream.Size Then Raise ECryptNoCryptedFile ; // Search a free file and return the filename TmpFile := TFuncs.GetUnusedTempFile(TempFile) ; TempStream := TFileStream.Create(TmpFile, fmCreate) ; // read the importend values from the stream AFStream.ReadBuffer(Self.Salt[ Low(Salt)], High(Self.Salt) + 1); InitHashDiggest(Passphrase) ; SetLength(CipherIV, TDCP_blockcipher(CipherType).BlockSize Div 8); AFStream.ReadBuffer(Self.CipherIV[ Low(CipherIV)], High (Self.CipherIV) + 1) ; InitCipher ; // decrypt! TempStream.Position := 0; CipherType.DeCryptStream(AFStream, TempStream, AFStream.Size - HashLength - AFStream.Position) ; CipherType.Burn ; // Read the hash in the stream AFStream.Position := AFStream.Size - HashLength ; // hash at the EOF SetLength(Buffer, HashLength) ; AFStream.ReadBuffer(Pointer(Buffer)^, HashLength) ; HashInStream := '' ; HashInStream := TFuncs.ByteArrayToStr(Buffer) ; // get and check the hash in stream with the aktual hash of the stream TempStream.Position := 0; HashOfStream := Self.GetHashFromStream(TempStream) ; // Auskommentiert um heraus zu finden ob es am Hash liegt ist auch keine gute // gute Methode um eine sicher Entschlüsselung zu gewährleisten //If HashInStream = HashOfStream Then //Begin HashWert := HashOfStream ; Result := TStringList.Create ; TempStream.Position := 0 ; Result.LoadFromStream(TempStream, TEncoding.Unicode) ; FreeAndNil(TempStream) ; If FileExists(TmpFile) Then DeleteFile(TmpFile) ; {End else begin FreeAndNil(TempStream) ; If FileExists(TmpFile) Then DeleteFile(TmpFile) ; end;} Except On Exception Do Begin FreeAndNil(TempStream) ; If FileExists(TmpFile) Then DeleteFile(TmpFile) ; FreeAndNil(Result) ; ECryptDecryptStream.Message := ECryptDecryptStream.Message + #13#10 + ExceptObject.ToString ; Raise Exception.Create(ECryptDecryptStream.Message) ; End ; End ; End ;
Jan
Ein neuer Tag bringt so einiges mit sich. Was auch immer es ist, es bleibt ein kleines Abenteuer. |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |