xml = '<?xml version="1.0" encoding="UTF-8"?>
<User>
<Uer id="user_id">
<Code>1111</Code>
<ID>0000000111</ID>
</Uer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference Type="http://www.w3.org/2000/09/xmldsig#Object" URI="#user_id">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>mwsSKYG+Q/krE54kcNpEGtXnQ+w=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>???????????????????</SignatureValue>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
.........
</X509Data>
</KeyInfo>
</Signature>
</User>'
@xml = Nokogiri::XML.parse(xml)
I have a xml, need xml signature. the <DigestValue> like this
Base64.encode64(OpenSSL::Digest::SHA1.digest(@xml.search("[id=#{user_id}]").to_html)).chop
and the result is OK.
When I calculate the <SignatureValue> value i get trouble, like this
p = OpenSSL::PKCS12.new(File.read("/Path/signCert.p12"),"123456")
Base64.encode64(OpenSSL::PKey::RSA.new(p.key).sign(OpenSSL::Digest::SHA1.new, tmpxml.search("SignedInfo").to_html))
and this value is wrong.
Computing the signature value for an XML signature is way more complicated than simply signing the HTML contents, unfortunately. You have to be sure to apply Canonicalization, for example. The gory details can be found in the W3C spec.
I'm not aware of something being available in Ruby right now that would allow you to do proper XML signature creation and verification, your best option is probably to either whip up your own based on Nokogiri (be prepared for a world of pain implementing the spec) or to switch to JRuby and from there, integrate the Java library available by default.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With