I am using Soap

<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#id-4453123">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>'.$ssDigest.'</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...How to calculate Signature Value.....</ds:SignatureValue>

..............

Thanks in advance

Dani AI

Generated

was correct that canonicalization matters. The important distinction to make here (and the cause of the "Hash values do not match" errors seen by ) is that the Reference/DigestValue and the SignatureValue are different things: DigestValue is the base64 of the digest of a referenced node after its transforms; SignatureValue is the base64 of the RSA signature over the canonicalized <SignedInfo> element (using the algorithm named in SignatureMethod, e.g. rsa-sha1), not a direct "encrypt of DigestValue."

Recommended steps (high level):

  1. Produce and place each Reference/DigestValue as you already do.
  2. Serialize/canonicalize the exact <SignedInfo> element using the CanonicalizationMethod specified (exclusive C14N in the snippet shown).
  3. Sign that canonicalized SignedInfo with the private key using the SignatureMethod (RSA+SHA1 here). The raw signature bytes are then base64-encoded to form SignatureValue.

Example (PHP, minimal):

openssl_sign($canonicalSignedInfo, $signature, $privateKeyPem, OPENSSL_ALGO_SHA1);
$sigValue = base64_encode($signature);

Troubleshooting checklist:

  • Canonicalize exactly the SignedInfo element as it will appear in the final XML (namespaces matter).
  • Do not try to "encrypt" the Reference DigestValue; sign SignedInfo instead.
  • Use openssl_sign (not openssl_private_encrypt) so the hash+RSA padding are correct.
  • Ensure private key format and passphrase handling are correct, and the signature is base64-encoded from raw bytes.
  • Verify locally with openssl_verify (or equivalent) against the public key to confirm the same canonical input.

Recommended Answers

All 4 Replies

This should be described in the documentation of the soap service you're using.

If it is sha1 and you're using php, then sha1('something here') should do it.

Thanks a lot Brother.

But i have already use sha1.....but facing error.
[faultstring] => Hash values do not match. (from client)

i have also referance site like :
http://www.cryptosys.net/pki/xmldsig-ChileSII.html#creatingxmldsig

But i cann't generate my Signature Value and facing error......Hash Values do not match..plz help me

You should have a look at the demos on that page. sha1() is not enough, you need to canonicalize the data as described.

you are right brother........

$dom = new DOMDocument();
$dom->loadXML($myXMLData);
$canonicalized = $dom->C14N(); // for the whole document

$ssDigest = base64_encode(pack("H*", sha1($canonicalized)));

from above code we easily get a DigestValue...and i have read in somewhere....encrypt of Digestvalue is SignatureValue.

i try manytimes but not get a solution....

how to get SignatureValue from DigestValue ??

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.