EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Signing XML

Also by EldoS: CallbackProcess
A component to control process creation and termination in Windows and .NET applications.
#14258
Posted: 08/20/2010 12:18:48
by Eduardo Helminsky (Standard support level)
Joined: 08/20/2010
Posts: 102

I am evaluating SecureBlackBox package. Now I am using Delphi 6 SP 2. There are two things I am interest: XML signing and SSL client. I was using other solution to sign XML files (MSXML) but when I sign using XML signer I got a different situation. The message digest is the same in both files. I don´t know what am I doing wrong (or missing). Following the code I am using to sign it and attached the XML files (base, oldversion and newversion).

function AssinarXML(cXml: WideString; cUri: WideString): WideString;
var Signer : TElXMLSigner;
X509KeyData : TElXMLKeyInfoX509Data;
Cert : TElX509Certificate;
SigNode : TElXMLDOMNode;
Ref : TElXMLReference;
Refs : TElXMLReferenceList;
FXMLDocument : ElXMLDOMDocument;
WinCertStorage: TElWinCertStorage;
nI: Integer;
S: TStringStream;
begin
Refs := TElXMLReferenceList.Create;
try
FXMLDocument := TElXMLDOMDocument.Create;
S := TStringStream.Create('');
try
S.WriteString(cXml);
S.Position := 0;
FXMLDocument.LoadFromStream(S);
finally
S.Free;
end;

Ref := TElXMLReference.Create;
Ref.URINode := FXMLDocument.DocumentElement.FindNode('infNFe');
Ref.URI := '#NFe' + cUri;
Ref.TransformChain.Add(TElXMLEnvelopedSignatureTransform.Create);
Ref.TransformChain.Add(TElXMLC14NTransform.Create);
Refs.Add(Ref);

Signer := TElXMLSigner.Create(nil);
try
Signer.SignatureType := xstEnveloped;
Signer.CanonicalizationMethod := xcmCanon;
Signer.SignatureMethodType := xmtSig;
Signer.SignatureMethod := xsmRSA_SHA1;
Signer.MACMethod := xmmHMAC_SHA1;
Signer.References := Refs;
Signer.IncludeKey := True;

Cert := nil;
WinCertStorage := TElWinCertStorage.Create(nil);
WinCertStorage.SystemStores.Text := 'MY';
for nI := 0 to WinCertStorage.Count-1 do begin
Cert := WinCertStorage.Certificates[nI];
if BinaryToString(Cert.SerialNumber) = '5AEF9AC3A29E2628' then begin
break;
end;
end;

if Assigned(Cert) and Cert.PrivateKeyExists then begin
X509KeyData := TElXMLKeyInfoX509Data.Create(False);
X509KeyData.IncludeDataParams := [xkidX509Certificate, xkidX509CRL];
X509KeyData.IncludeKeyValue := False;
X509KeyData.Certificate := Cert;
Signer.KeyData := X509KeyData;
end;

Signer.UpdateReferencesDigest;
Signer.Sign;

SigNode := FXMLDocument.DocumentElement;
Signer.Save(SigNode);
Form1.M.Text := FXMLDocument.OuterXML;
Form1.M.Lines.SaveToFile('c:\assinarxml\teste.xml');
finally
FreeAndNil(Signer);
FreeAndNil(X509KeyData);
end;
finally
FreeAndNil(Refs);
end;
end;

procedure TForm1.HProButton1Click(Sender: TObject);
var S: TStringList;
cA: WideString;
nI: Integer;
begin
S := TStringList.Create;
try
S.LoadFromFile('base.xml');
cA := S.Text;
finally
S.Free;
end;
nI := Pos('?>',cA);
if nI > 0 then begin
// cA := Copy(cA,nI+2,Length(cA));
end;
AssinarXML(cA,'35080599999090910270550010000000015180051273');
end;

Thanks for any comment


[ Download ]
#14259
Posted: 08/20/2010 12:23:32
by Eugene Mayevski (EldoS Corp.)

I am not sure that I understood, what exactly your problem is. Can you please elaborate on this?


Sincerely yours
Eugene Mayevski
#14260
Posted: 08/20/2010 14:55:39
by Eduardo Helminsky (Standard support level)
Joined: 08/20/2010
Posts: 102

Eugene

I am a beginner in these issues (XML and certificates) and my doubt is:

The both XML I have sent you (in ZIP) should be the same, IOW, if I am using the same certificate but two ways to sign I presume the final work should be the same.

I am using the same BASE file to sign. One I am using MSXML and the other I am using SecureBlackBox. I don´t know if you have seen the files but if you say that both are correct no problem, of course I would like to know why. The only thing I can find are little differences between old.xml and new.xml in areas outside the signature. These could be the problem ?

Could you drive me to get some materials to study more about XML or I have to buy a book ?

Thanks for your support
Eduardo
#14261
Posted: 08/20/2010 17:04:42
by Dmytro Bogatskyy (EldoS Corp.)

Both xml files (old and new) are well-formed and have a valid signature.
Except:
"New" file saved in UTF-16 encoding, because you are using FXMLDocument.OuterXML property that returns a WideString. Then it is saved as ANSI, because you are using SaveToFile method that uses AnsiString in Delphi 6. As you don't have non-latin characters a signature still valid. But other programs may have problems to open such document with encoding="utf-16" in a header.
You should use:
Code
F := TFileStream.Create('c:\assinarxml\teste.xml', fmCreate or fmOpenWrite);
try
  FXMLDocument.SaveToStream(F);
finally
  F.Free;
end;

or you can use:
Text := UTF8Encode(FXMLDocument.DocumentElement.OuterXML);

Second, I noticed the only one difference between those signatures is a namespace declaration: xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
It really doesn't matter much.
But if you worry about it, you can remove it, see the article:
https://www.eldos.com/security/articles/6092.php
In your case you'll need to specify:
Code
Signer.Sign;
Signer.Signature.SignaturePrefix := “#default";
#14284
Posted: 08/24/2010 13:58:32
by Eduardo Helminsky (Standard support level)
Joined: 08/20/2010
Posts: 102

Dmytro Bogatskyy

Thank you very much for your explanation.

I have changed my code and now both files are the same.

Now I will add another thread in the forum about SSL connection.
Also by EldoS: RawDisk
Access locked and protected files in Windows, read and write disks and partitions and more.

Reply

Statistics

Topic viewed 2521 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!