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: CallbackFilter
A component to monitor and control disk activity, track file and directory operations (create, read, write, rename etc.), alter file data, encrypt files, create virtual files.

Reply

Statistics

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