Delphi Encryption Compendium (DEC) 5.2 for D2009 released

Hi,

I’ve recently released an updated version of the Delphi Encryption Compendium (DEC) compatible with Delphi versions up to 2009. A code example of using it with Unicode strings is included in the library.

This libary was updated and released with permisson of the original author Hagen Reddman who developed the versions DEC 3 and DEC 5.1.

The Delphi Encryption Compendium supports several hashes, ciphers and text encodings and is imho one of the best libraries for strong cryptography in Delphi. And the best: It is free of charge!

It is available at Torry: http://www.torry.net

Thanks to Michael Puff (a.k.a. Luckie) for hosting the library on his server!

Due to the request here are the hashes for the file DEC_v5.2.zip linked at Torry / Michael’s Server:

<dec_v5.2.zip>

MD5: af599125809e4258597138a7c4496b80
RipeMD128: 9e2717abecbcd20623ebb05a04a70143
RipeMD160: fe25c2d89c2487412c4c7b9d04a2f4a9eaf792df
SHA1: cda26284cd4099a30bd7c32e2076bac0cd1b9f32
SHA256: cdec0862005a6da637d3f7d9277d2cb65f0c3eb58f5a02866989e9b56879f999

Advertisements

53 thoughts on “Delphi Encryption Compendium (DEC) 5.2 for D2009 released

  1. Thanks!

    Would it be possible for you to publish the SHA256 hash of DEC 5.2 package, so we can verify the version downloaded from Torry is not modified?

    Thanks again! And keep up the great work!

  2. Hi Arvid,

    Speaking about encryption, do you know if the DCP library (Delphi Ciphers and Hashs) works under D2009 ? I use them under D2007 with great success, and I’m planning to upgrade soon… Thanks.

  3. Hi Adrien,

    as far as I know Dave’s DCP library has not been updated (yet?). I haven’t tested it as I am knowing of two working libraries so far (my DEC and TP LockBox ported by Sebastian Zierer available at http://www.songbeamer.com/delphi/).

    Checking Dave’s page it seems that the DCP is stuck at the D2005 level somehow but I would expect some problems using it in D2009 without additional changes.

    Best is to contact Dave and ask for an updated version.

    Regards
    Arvid

  4. Hi Arvid.

    It seems that the downloads at torry.net do not match the MD5 and SHA256-haashes (I did not test the others). However, the download from Luckie’s page works fine and the hashes are correct.

  5. Hi Thomas,

    @Thomas
    Torry missed the last update from Michael’s Website so the checksum was different. I started an update process for the Torry entry but this will take some time as it has to be reviewed by them.

    Thank you for pointing to this!

    Cheers,
    Arvid

  6. Hi!

    I want to upgrade to Delphi 2009 and I need to use the Cipher tools. And the components uploaded in Torry’s page are uncompleted. Where can I download the correct version? Any link?

    Thanks!!

  7. @Jordi
    Hi Jordi,

    the package is complete.

    The DEC 5 is a complete rewrite of the DEC 3.x. You will likely experience incompatibilities, especially when talking about the proprietary block chaining modes and the CipherManager components you’d mentioned.

    Hagen already removed the CipherManager wrapper components in the year 2006. I cannot port something to Delphi 2009 what isn’t there.

    Cheers,
    Arvid

    P.S.: The 2006 version is found here: http://www.michael-puff.de/Developer/Delphi/Importe/Hagen_Reddmann/Archiv/

  8. Hi !

    Is there any forum support / help for DEC 5.2 ?

    A used 2.2 version of DEC, but impossible to decrypt 2.2 crypted material with 5.2 routines.

    Here is my Encode routine for 2.2 :

    with TCipher_Blowfish.Create do
    try
    IncludeHashKey := True;
    InitKey(AnsiString(myKey), nil);
    try
    DecodeStream(InputStream, OutputStream, InputStream.Size – Hash.DigestKeySize);
    except
    Result := False;
    end;

    2.2 version uses SHA1 default class for key, and include it at begining of crypted stream, so I’ve try (and a lot of others ways) someting like this with DEC 5.2 :

    Buf := AllocMem(20); // Size of Hash.Digest in 2.2
    InputStream.Read(Buf^, 20);

    with DECCipher.TCipher_Blowfish.Create do
    try
    Mode := cmCBCx; // CTSx doesn’t work
    Init(Buf); // Init(THash_SHA1.KDFx(myKey, RandomBinary(16), Context.KeySize) doesn’t work better
    DecodeStream(InputStream, OutputStream, InputStream.Size – 20);
    finally
    Free;
    end;

    Nothing is working, i’m desperate…
    Someone to help me ?
    Thanks…

    • Hi figo,

      I already considered setting up a project page for the DEC. Check back to my blog, I’ll publish it here as soon as I am ready.

      But: Regarding your current problem there is no one-step solution. The DEC 3 had been out for several years, even the DEC 5.1 was available since ~ 2004 iirc. There are so many breaking changes which where made long before I had taken care of the source, so every compatibility issue is a time-consuming challange on it’s own. Sorry to say that.

      Cheers,
      Arvid

  9. Is it possible, and if so how, to calculate MD5 and SHA1 keys to confirm if the downloaded file is identical with a published SHA1 and/or MD5 hash?

    I tried using DEC V5.2 but got incorrect results (perhaps misunderstanding the code…)

    E.g. I tried the file from http://sourceforge.net/projects/clonezilla/files/clonezilla_live_stable/clonezilla-live-1.2.3-27.iso/download
    and compared with the checksums herein
    http://clonezilla.org/download/sourceforge/stable/checksums.php
    but the results for both were incorrect

    This is my code I used:
    FHash:=THash_MD5.Create;
    // or FHash:=THash_SHA1.Create;
    with FHash do begin
    try
    Init;
    CalcFile(FFName, TFormat_HEXL);
    Done;
    finally
    mmo.Lines.Add(Format(‘File: %s’, [edFName.Text]));
    mmo.Lines.Add(DigestStr(TFormat_HEX)]));
    Free;
    end;

    What is wrong as with another package (DCPcrypt package) I got the correct/same answers.

    • Hi maestro3,

      I forgot to answer, sorry! You are using CalcFile wrong, it’s already a class method, so the following code will work fine (just tested):


      var
      str: string;
      begin
      str := THash_MD5.CalcFile('C:Developmentclonezilla-live-1.2.6-59-i686.zip', TFormat_HEXL);
      memo1.Lines.Add(str);
      end;

      The result is 28c950c8086210fa9e31c4cfb9e41736, the website mentions exactly this code. Your approach creates a secondary Hash instance and discards the result from CalcFile. DigestStr then returns just the result of the empty buffer which was filled with pseudo-random data.

      Please have a look at the Source, DECHash.pas and step into TDECHash.CalcFile > TDECHash.CalcStream which in turn calls Init, Calc, Done and DigestStr on it’s own.

      Cheers,
      Arvid

  10. I am attempting to match a SHA1 hash created in PHP, but no luck. I have installed DEC 5.2 for Delphi 5 and am trying a very simple task:

    Self.lblHash1.Caption := DECHash.THash_SHA1.CalcBinary, Self.editPassword.Text, TFormat_HEXL);

    Self.editPassword.Text contains the original password whose hash I am attempting to match.

    Also, what function is used (and could you please explain the parameters for that function) to re-create the original password once I use CalcBinary to create the hash?

    Thank you.
    Scott Gast

  11. @Scott Gast
    Hello Scott,

    first of all let me say that I am sorry that I missed your comment posted on my blog back in July. I’ll send you my answer via E-Mail too, just to ensure you’ll get notified about.

    Regarding your question: What Delphi Version are you using? It is likely an issue with the Unicode conversion.

    If CalcBinary doesn’t suite your needs you can try using THash_SHA1.CalcBuffer() instead working directly on an array of chars. Please specify the length as second parameter.

    It should look something like that:

    Result := THash_SHA1.CalcBuffer(mystring[1], length(mystring));

    Regarding your 2nd part of the question: There is no way in re-creating the original password from a Hash. That’s what Hashes are all about, please have a look at

    http://en.wikipedia.org/wiki/Cryptographic_hash_function

    If you want to encode/decode you will have to use Cryptographic Ciphers instead of hashes.

    By the way: The Delphi Encryption Compendium has a new home at http://code.google.com/p/delphidec/. I am going to publish a new release later this year, which includes new functions for easier ansi/unicode usage.

    Best regards,
    Arvid

  12. @Thomas Anderson

    the TChiperManager has been removed by the original author several years ago with the release of the DEC 5.1 back in 2006. DEC 5 was a redesigned, improved release with several security and performance enhancements. The TCipherManager has been deprecated with 5.1 and so it is still not included in my updated versions like 5.2.

    There are also some known incompatibilities between some padding algorithms in the DEC 3 and the DEC 5, which I am going to circumvent in a future release planned for 2011.

  13. Hello,

    PLEASE HELP.
    I’m lost in how to use this library.
    I need to use SHA512-hash to encrypt user password.
    I get unicode pass_string from editbox, add a salt from database uid.
    This code is not properly.
    >>

    procedure TForm2.TestHash;
    var
    Count: Integer;
    Hash: TDECHash;
    TextToHash:string;
    begin
    TextToHash:=edit1.Text+ SALT;
    Hash:=THash_SHA512.Create;
    Hash.Init;
    count:= Length(TextToHash);
    Hash.Calc(TextToHash[1], count);
    Hash.Done;
    memo1.Clear;
    memo1.Lines.Add(Hash.DigestStr(TFormat_HEXL));
    Hash.Free;
    end;

  14. @Lubo

    I don’t know what you mean by “this code is not properly”. Probably you’re mixing up Unicode and Ansi Strings? If you compare the results from websites like e.g http://www.fileformat.info/tool/hash.htm you will see that you’ll likely need to use Ansi Strings with existing data.

    An example for doing this correctly:

    var
    TextToHash: AnsiString;
    begin
    TextToHash := edit1.Text + Salt;
    Hash := THash_SHA512.Create;
    try
    Hash.Init;
    Count := Length(TextToHash);
    Hash.Calc(TextToHash[1], Count * SizeOf(TextToHash[1]));
    Hash.Done;
    memo1.Clear;
    memo1.Lines.Add(Hash.DigestStr(TFormat_HEXL));
    finally
    Hash.Free;
    end;

    Note the use of SizeOf() inside the 2nd Calc() parameter and the (alternate) declaration of TextToHash as AnsiString. The SizeOf() is only needed when dealing with the UnicodeString type as in Delphi 2009 and newer, but I think changing TextToHash to AnsiString should already be sufficient in your case.

    I just tried it and received correct results compared to the above mentioned website.

    Cheers,
    Arvid

  15. @Arvid
    Hi
    “this code is not properly”.>> sorry,I was meaning:code is not working properly.With using ansistring, everything was fine.I was also comparing results to website http://www.fileformat.info.

    But I ‘ve missed to post more precisely informations:
    >> I’m working in Delphi XE.
    >> I need hash Unicode strings.

    example:Trying to hash this character: “Đ”
    I used your code.But no matter if I put TextToHash: AnsiString; or String, results compared to site mentioned above,was incorrect.

    Thanks,
    Lubo

    Ps:I’m sorry for my english.

    • Hello Lubo,

      that’s not a bug but you’re comparing apples and oranges 😉 the mentioned website encodes Unicode data as UTF8 before calculating the hash. Just do the same if needed.

      Example:

      var
      MyUTF8String: UTF8String;
      HashString: string;
      begin
      MyUTF8String := 'Đ'; // Delphi 2009+ converts on the fly
      HashString := THash_SHA512.CalcBuffer(MyUTF8String[1], Length(MyUTF8String), TFormat_HEXL);
      Memo1.Lines.Add(HashString);

      Also have a look at the THash and TCipher classes: There are class methods available. I just used THash_SHA512.CalcBuffer() which is a class method and does all the Init, Done etc for you. No need to extract the DigestStr on your own when using those methods.

      Cheers,
      Arvid

  16. Hi Arvid,
    First of all I would like to thank you for your work on the Encryption Compendium! It’s a great package and it does its job very well. I enjoy working with it, although I don’t understand all the details.
    I have a question: is it possible to use a TDECCipherClass to “stream-encode” and “stream-decode”. I mean:
    1. Create an object, for example TCipher_Twofish.Create
    2. Initialize Salt, obtain a Pass using THash_Whirlpool.KDFx
    3. Call once Init
    4. And then call multiple times Encode or Decode
    I’m trying to encode large volumes of data and I don’t want to load them entirely into memory and then encode, I would rather encode them piece by piece.

    Regards,
    Simon.

  17. Hello Arvid. I think I may have come across a bug. I have been experimenting with hashing some large blocks of data. I have found that when calling CalcBuffer with a size greater than or equal to 32 MiB (33554432 bytes) the result is incorrect. This also occurs when creating an object and calling Calc directly rather than using CalcBuffer. However, if I use CalcStream, the result is correct because CalcStream breaks the input into smaller chunks. I inspected the code some and the Increment8 method looked suspicious:

    procedure Increment8(var Value; Add: LongWord);
    // Value := Value + 8 * Add
    // Value: array[0..7] of LongWord
    asm
    MOV ECX,EDX
    LEA EDX,[EDX * 8]
    SHR ECX,25
    ADD [EAX].DWord[ 0],EDX
    ADC [EAX].DWord[ 4],ECX
    ADC [EAX].DWord[ 8],0
    ADC [EAX].DWord[12],0
    ADC [EAX].DWord[16],0
    ADC [EAX].DWord[20],0
    ADC [EAX].DWord[24],0
    ADC [EAX].DWord[28],0
    JC HashingOverflowError
    end;

    I am mystified by what ECX is being used for. Incidentally,

    SHR ECX,25

    divides by 33554432, which is the same number I mentioned above.

    I experimented by changing the line:
    ADC [EAX].DWord[ 4],ECX
    to:
    ADC [EAX].DWord[ 4],0
    and I then got the correct result.

    • Hi Chad,

      thanks for reporting. I’ll have a look at, that fix is likely not to be released before the next version is made public. Additionally I was thinking about replacing the asm code with PurePascal code at all to keep the library as compatible as possible (i.e. thinking about upcoming x64 on Delphi’s side).

      Cheers,
      Arvid

      • Hi Andreas,

        sorry for the late reply, busy with work and conferences… No, not yet. I’ll start porting the suite later this year.

        Cheers,
        Arvid

      • Hi Arvid,

        Define “later this year” 😉

        We use DEC in our product and are now starting to port it to x64.
        That means we need DEC compiling and running on Delphi XE2 64bit mode. If you didn’t have time to port it yet, we will do it (at least these parts we need), but in this case it would be helpful if we could base on the latest code. Therefore I’d kindly ask you if it is possible to use/fill the SVN repository on Google Code with the latest code?

        Thank you and best regards
        Andreas

      • Hello,
        how could I help to generate a pure pascal version of DEV 5.2?
        I’d like to use it in some Android project and I’d be willing to help a bit if that helps getting this done. I tried to replace DEC 5.2 with DCPCrypt in some demp program, but the libraries I had built and wanted to reuse use a 18 byte key. DCPCrypt enforces a rule that the key must be 4 or a multiple of that. So I’d rather have some Android compatible version of DEC.
        I also made a post about it here:
        https://forums.embarcadero.com/thread.jspa?messageID=781052&tstart=0#781052

        Cheers
        Markus

    • you are right, thats a bug.

      We want to add a LongWord value multiplied by 8 to a large 256Bit unsigned integer. We multiply it by 8 because we want to count the Bits computed out of Bytes. Some Hash functions need to include the processed length of data streams in Bits into they computation. I had the choice to add the bytes processed into a large integer and finally multiply this large integer by 8, or to do this directly in this addition function. Later is faster and don’t need a separate multiply function to implement.

      The mistake I made is in SHR,25 and must be SHR ECX,29.

      ECX:EDX contains first our parameter Add and must be multiplied by 8. Thus we load EDX with LEA EDX,[EDX*8] = EDX *8. This lost the most three bits. We had loaded prior ECX with parameter Add and have to divide it with 2^32/8 = 2^32/2^3 = 2^(32-3) = SHR ECX,29 to correct these lost three most significant bits.

      Simply change 25 to 29.

      A pascal version of this code is complicated because we can’t access to the CPUs Carry flag in Pascal. Thats used in the assembler version to get the right mathematical result. In i386 assembler there is easily the possibility to chain multiple additions/subtractions of each 32bit in size to get a addition of arbitrary integer sizes, like this function does.

      Best regards, Hagen

      • Thanks for the explanation! I appreciate it. By the way, I was curious: what is the reason for using LEA to multiply by 8 instead of just SHL EDX,3? The latter seems more natural, especially considering the other half of the operation is done with SHR.

        Thank you for all the hard work you have put in!

  18. Hi Arvid,
    I found a asymetric code sample in the DEC_52 which is cut off… Why?
    I need the mathematical counting to create public/private key.

    • Hi Tang,

      if it’s part of DEC Part II (see the name of the folder) it’s not included. This is not my decision as the original author, Hagen Reddmann, never published the sources of those mathematical functions (e.g. Elliptic Curves). They are just kept as experimental DCUs for Delphi 5 to 7 iirc.

      Sorry, nothing I can do about.

      Cheers,
      Arvid

      • no problem… thx anyway for the hard work.

        the only thing i can do is just using a pre-compiled binary version… sad.

  19. Hello

    I made a SHA1 verifier and it worked, but I can’t guess how to deal with a stream cipher.
    Any help on how to do it ?

    Thanks

  20. Hello again.
    I have two questions: What does “IVector” on Init method. May I leave it unused?
    What is TCipherMode, and what is Salt?

    Many thanks, bye

  21. Hi Arvid,
    Excellent work on DEC 52.
    I would like to know where I can download the latest version as I cannot find it on Torry anymore and I seem to have a problem with the version I have – Error message detailed below…

    TDECHashClass does not contain a member ‘Register’ at line 444

    • Hi Dave,

      I have a project page at Google Code:
      http://code.google.com/p/delphidec/

      Give me some weeks, hopefully I’ll have finished a new release next month. Currently I don’t know if my idea is going to work, so don’t expect anything – but please stay tuned 🙂

      Cheers,
      Arvid

      P.S.: Sorry don’t have time to look into old errors. Looks like something related to ver.inc, best to check which conditional compilation is correct for your delphi.

  22. Hi Arvid,

    I understand that you are most probably maintaining DEC in your spare time, but do you have any sort of ETA for a 64 bit version? I only ask as I am under pressure to release a 64 bit version myself and I use DEC. Depending on your answer I may have to use a different solution.

    Thanks,
    Steve

  23. Pingback: Woher bekomme ich das DEC? - Delphi-PRAXiS

  24. VERYY NEED HELPP!!
    before I was confused how to use the DEC 5.2, but thanks to this blog helped me, thank you very much to Arvid’s.
    I want to encrypt a string 0-9, az, AZ and spaces with whirlpool hash, this is my program code:
    var
    TextToHash,HashString: string;
    begin
    TextToHash:=edit1.Text;
    HashString := THash_Whirlpool.CalcBuffer(TextToHash[1], Length(TextToHash), TFormat_HEX);
    memo1.Clear;
    Memo1.Lines.Add(HashString);
    label1.Caption:=inttostr(length(HashString));
    end;
    results are not the same as what I want.
    my code result: 6332FE8438C351B1B03C8558A8B4BF78C6BBF59DA25D601197EEED8CB670C509BDA18AFAACADA9707C3EFFFA9E07FE7BBE0CA0F4233F5F5384D6392C138AC1EF
    result that i want (http://www.hash.spugesoft.com):
    2f9959b230a44678dd2dc29f037ba1159f233aa9ab183ce3a0678eaae002e5aa6f27f47144a1a4365116d3db1b58ec47896623b92d85cb2f191705daf11858b8 (lowercase isn’t problem)
    thank’s for everything Arvid, i very hope i get reply soon

  25. Hi everyone, great product. I’m using it in Delphi XE3. I’m using the example functions. Everything works, but compiler is giving me a warning about string types:

    [dcc32 Warning] : W1058 Implicit string cast with potential data loss from ‘string’ to ‘RawByteString’

    And it’s on the decrypt function that uses :String as all the parameters. The line it’s complaining about is:

    ASalt := ValidFormat(ATextFormat).Decode(AText);

    Specifically the “AText” parameter.

    I don’t dare touch any of your code for fear of making it malfunction. Is there a type cast I can do that will make the compiler stop complaining, and still allow your code to work correctly?

    • Currently it’s best just to ignore the warning. Later this year I hope to have some time to continue working on an update which fixes those issues.

      • Ok, Thank you! Also, in the examples, can you show how to use DEC to encrypt/decrypt a file? I very much appreciate your work on this.

      • Thank you, you’re welcome! Yes, sure. I am planning to include a sample application showing the common implementation.

    • No 64 bit updates available yet. But you still might want to stay tuned here. If you look at the DEC code you’ll see that it contains quite a bit of assembler which cannot be ported 1:1 to 64 bit. Any volunteers for working on the DEC code?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s