EldoS | Feel safer!

Software components for data protection, secure storage and transfer

How to calculate the digestvalue for xml signature?

Also by EldoS: CallbackRegistry
A component to monitor and control Windows registry access and create virtual registry keys.
#27110
Posted: 11/05/2013 03:29:18
by Jacob jvandiermen (Standard support level)
Joined: 08/09/2013
Posts: 55

Hello Eldos,

For a xml signature I have to calculate a value for the digestvalue element in the Reference node. This value is a SHA-1 with a Base 64 encoding. The SHA-1 value is first calculated with a standard SHA-1 function. Then I use the SBEncoding.Base64EncodeString. This gives me a output value of 56 characters.
Actually I expect a value with 28 characters!
When I use the TElXMLSigner object to sign. This object also calculates a value for the digestvalue element in the Reference node with 28 characters.
How do I apply the Base64 encoding so that the output value is 28 characters long?

Regards,

Jacob
#27111
Posted: 11/05/2013 03:33:17
by Vsevolod Ievgiienko (EldoS Corp.)

Thank you for contacting us.

Indeed 56 characters is too much for 20 byte hash. Could you post here your code that calculates the hash and wraps it into Base64. Most likelly there is a bug in this code.
#27112
Posted: 11/05/2013 03:37:18
by Eugene Mayevski (EldoS Corp.)

EncodeString encodes a string. Binary hash is 20 bytes, but it's not a string. I don't know what you encode - if you convert 20 bytes to a string using Base16 and then you base64-encode this 40 bytes, then you get 56 bytes. And if you encode a unicode string (which is 40 bytes for a 20-character value), then you again get 56 bytes, but you DONT have a string in the first place, so use of EncodeString is wrong.


Sincerely yours
Eugene Mayevski
#27121
Posted: 11/05/2013 04:58:13
by Jacob jvandiermen (Standard support level)
Joined: 08/09/2013
Posts: 55

Hello Vsevolod & Eugene,

Vsevolod I don't think there is a bug. Eugene's information got me thinking.

The function that I use:
Code
function encryptStringWithSHA1Hash(strValue: AnsiString): AnsiString;
var
  index: Integer;
  DCP_sha1: TDCP_sha1;
  digest: array[0..19] of byte;  // SHA-1 produces a 160bit (20byte) output
begin
  try
    begin
      try
        DCP_sha1:= TDCP_sha1.Create(nil);
        DCP_sha1.Init;
        DCP_sha1.UpdateStr(strValue);
        DCP_sha1.Final(digest);
        for index:= low(digest) to high(digest) do
          begin
            result:= result + IntToHex(digest[index],2);
          end;
      except
        on E : Exception do
          result:= '';
      end;
    end
  finally
    DCP_sha1.Burn;
    FreeAndNil(DCP_sha1);
  end;
end;


I used the output value of the encryptStringWithSHA1Hash function to encode it to base64 with SBEncoding.Base64EncodeString. But that isn't the right way to do it!
I made some changes in the function encryptStringWithSHA1Hash and renamed it to encryptStringWithSHA1HasBase64Encoding.

Code

function encryptStringWithSHA1HashBase64Encoding(strValue: AnsiString): AnsiString;
var
  index: Integer;
  DCP_sha1: TDCP_sha1;
  digest: array[0..19] of byte;  // SHA-1 produces a 160bit (20byte) output
  digest4Base64: ByteArray;
begin
  try
    begin
      try
        DCP_sha1:= TDCP_sha1.Create(nil);
        DCP_sha1.Init;
        DCP_sha1.UpdateStr(strValue);
        DCP_sha1.Final(digest);
        SetLength(digest4Base64,succ(High(digest)));
        for index:= low(digest) to high(digest) do
          begin
            digest4Base64[index]:= digest[index];
          end;
        result:= SBEncoding.Base64EncodeArray(digest4Base64,True);
      except
        on E : Exception do
          result:= '';
      end;
    end
  finally
    DCP_sha1.Burn;
    FreeAndNil(DCP_sha1);
  end;
end;


Now the output is 28 characters. But is this correct?

Regards,

Jacob
#27123
Posted: 11/05/2013 05:03:05
by Vsevolod Ievgiienko (EldoS Corp.)

The 2nd variant is correct.
#27124
Posted: 11/05/2013 05:09:11
by Jacob jvandiermen (Standard support level)
Joined: 08/09/2013
Posts: 55

Hello Vsevolod and Eugene,

Thank you for the support!

Regards,

Faroek
Also by EldoS: CallbackProcess
A component to control process creation and termination in Windows and .NET applications.

Reply

Statistics

Topic viewed 1556 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!