I'm trying to sign XML in Delphi with certificate, but all I'm getting are some unrecognized characters. I'm using this function
var
xmlData, signature: PByte; data: array[0..0] of PByte;
msgCert: array[0..0] of PCCERT_CONTEXT;
dwDataSizeArray: array[0..0] of DWORD;
sigParams: CRYPT_SIGN_MESSAGE_PARA;
cbSignedBlob: DWORD;
begin
if PCertContext = nil then
Exit;
GetMem(xmlData, Length(AXml));
try
system.Move(Pointer(AXml)^, xmlData^, Length(AXml));
ZeroMemory(@sigParams, SizeOf(CRYPT_SIGN_MESSAGE_PARA));
sigParams.cbSize := SizeOf(CRYPT_SIGN_MESSAGE_PARA);
sigParams.dwMsgEncodingType := (X509_ASN_ENCODING or PKCS_7_ASN_ENCODING);
sigParams.pSigningCert := PCertContext;
sigParams.HashAlgorithm.pszObjId := szOID_RSA_MD5;
//SigParams.cAuthAttr := 0;
//SigParams.dwInnerContentType := 0;
//SigParams.cMsgCrl := 0;
//SigParams.cUnauthAttr := 0;
//SigParams.dwFlags := 0;
//SigParams.pvHashAuxInfo := nil;
//SigParams.rgAuthAttr := nil; }
data[0] := xmlData;
dwDataSizeArray[0] := Length(AXml);
cbSignedBlob := 0;
CryptSignMessage(@sigParams, True, 1, @data[0], @dwDataSizeArray[0], nil, @cbSignedBlob);
GetMem(signature, cbSignedBlob);
try
CryptSignMessage(@sigParams, True, 1, @data[0], @dwDataSizeArray[0], signature, @cbSignedBlob);
SetLength(Result, cbSignedBlob);
system.Move(signature^, Pointer(Result)^, cbSignedBlob);
finally
FreeMem(signature);
end;
finally
FreeMem(xmlData);
end;
end
but all I get is:
'舰餁आ蘪虈'#$0DF7'܁ꀂƂりƂʆāัర'#$0806'蘪虈'#$0DF7'Ԃ'#5'ରआ蘪虈'#$0DF7'܁'#$3101'ƂぢƂɞā㠰 〰
'#$0B31'र̆ѕጆ匂ㅉ『،唃'#$0A04'ԓ佐呓ㅁ】؏唃'#$0B04#$0813'佐呓牁䅃Ђ䤾Eర'#$0806'蘪虈'#$0DF7'Ԃ'#5'രआ蘪虈'#$0DF7'āԁЀƂ堀묥䮡悕㈒古虺̐昇⠹꺶힊覬왧䮽㕺⢂꺇宬䝄'#$07B3'䲠'#$D868'㶙㌱㟜'#$DAF2'#$2B83#$1C'ity-1.0.xsd" wsu:Id="Timestamp-3c7c79b4-2afa-4184-9d2c-8f5e721c8421">2014-01-13T11:26:52Z2014-01-13T11:31:52Z'#0' OTRRC.PTT'
and there is alot more data that need to be in signed XML. In C# this was solved like this
AsymmetricAlgorithm rsa = signCertificate.PrivateKey;
// Read provided document, find the signature element ...
MemoryStream documentStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(document));
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.Load(new XmlTextReader(documentStream));
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("ds", dsigURI);
XmlNode sig = doc.SelectSingleNode("//*[@Id='" + signatureID + "']", nsmgr);
XmlNode after = sig.PreviousSibling;
XmlNode parent = sig.ParentNode;
SignedXml signedXml = new SignedXml(doc);
parent.RemoveChild(sig);
Reference r = new Reference();
r.Uri = "";
r.AddTransform(new XmlDsigEnvelopedSignatureTransform());
signedXml.AddReference(r);
X509Certificate cert1 = new X509Certificate(signCertificate.GetRawCertData());
KeyInfo ki = new KeyInfo();
ki.AddClause(new KeyInfoX509Data(cert1));
signedXml.KeyInfo = ki;
signedXml.Signature.Id = signatureID;
signedXml.SigningKey = rsa;
signedXml.ComputeSignature();
XmlNode signature = doc.ImportNode(signedXml.GetXml(), true);
parent.InsertAfter(signature, after);
return doc.OuterXml;
Thanks for help in advance!