Generate XML Signature
Tue Jul 05 2022 14:57:47 GMT+0000 (Coordinated Universal Time)
public static String generateXMLSignature(String docBodyString){
// 1. Apply the Transforms, as determined by the application, to the data object.
// (no transforms are done, since the body should be delivered in canonicalized form (Force.com offers no canonicalization algorithm))
// 2. Calculate the digest value over the resulting data object.
Blob bodyDigest = Crypto.generateDigest('SHA1',Blob.valueOf(docBodyString));
// 3. Create a Reference element, including the (optional) identification of the data object, any (optional) transform elements, the digest algorithm and the DigestValue.
// (Note, it is the canonical form of these references that are signed and validated in next steps.)
String referenceString = '';
referenceString += '';
referenceString += '<ds:Reference URI="#msgBody">';
referenceString += '<ds:Transforms>';
referenceString += '<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>';
referenceString += '<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform>';
referenceString += '</ds:Transforms>';
referenceString += '<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>';
referenceString += '<ds:DigestValue>'+EncodingUtil.base64Encode(bodyDigest)+'</ds:DigestValue>';
referenceString += '</ds:Reference>';
// 4. Create SignedInfo element with SignatureMethod, CanonicalizationMethod and Reference(s).
String signedInfoString = '';
signedInfoString += '<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">';
signedInfoString += '<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>';
signedInfoString += '<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>';
signedInfoString += referenceString;
signedInfoString += '</ds:SignedInfo>';
// 5. Canonicalize and then calculate the SignatureValue over SignedInfo based on algorithms specified in SignedInfo.
// (no canonicalization is done, since the signedinfo element should be delivered in canonicalized form (Force.com offers no canonicalization algorithm))
String algorithmName = 'RSA-SHA1';
// decrypted private key pkcs8 format from certificate
String key = '[decryptedPrivateKeypkcs8formatfromcertificate]';
Blob privateKey = EncodingUtil.base64Decode(key);
Blob siBlob = Blob.valueOf(signedInfoString);
Blob signatureValue = Crypto.sign(algorithmName, siBlob, privateKey);
String signatureValueString = EncodingUtil.base64Encode(signatureValue);
// 6. Construct the Signature element that includes SignedInfo, Object(s) (if desired, encoding may be different than that used for signing), KeyInfo (if required), and SignatureValue.
String signatureString = '';
signatureString += '<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">';
signatureString += signedInfoString;
signatureString += '<ds:SignatureValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">'+signatureValueString+'</ds:SignatureValue>';
signatureString += '<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">';
signatureString += '<ds:X509Data xmlns:ds="http://www.w3.org/2000/09/xmldsig#">';
signatureString += '<ds:X509Certificate xmlns:ds="http://www.w3.org/2000/09/xmldsig#">[the certificate used for signing]</ds:X509Certificate>';
signatureString += '</ds:X509Data>';
signatureString += '</ds:KeyInfo>';
signatureString += '</ds:Signature>';
return signatureString;
}



Comments