Skip to content

Instantly share code, notes, and snippets.

@mattlevine
Last active May 16, 2023 20:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattlevine/7fb8651ac9d69134d89a61921e4a4fc6 to your computer and use it in GitHub Desktop.
Save mattlevine/7fb8651ac9d69134d89a61921e4a4fc6 to your computer and use it in GitHub Desktop.
Create certificate and use it to sign an xml document
<cfscript>
/*
Required Jars need to be downloaded from https://www.bouncycastle.org/
bcpkix-jdk18on-173.jar
bcprov-ext-jdk18on-173.jar
bcutil-jdk18on-173.jar
*/
KeyFactory = createObject("java", "java.security.KeyFactory");
PKCS8EncodedKeySpec = createObject("java", "java.security.spec.PKCS8EncodedKeySpec");
keyPairGenerator = createObject( "java", "java.security.KeyPairGenerator" ).getInstance( "RSA" );
x500Name = createObject("java", "org.bouncycastle.asn1.x500.X500Name");
bigInteger = createObject("java", "java.math.BigInteger");
x509v3CertificateBuilder = createObject("java", "org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder");
jcaContentSignerBuilder = createObject("java", "org.bouncycastle.operator.jcajce.JcaContentSignerBuilder");
jcaCertificateConverter= createObject("java", "org.bouncycastle.cert.jcajce.JcaX509CertificateConverter");
// Generate a new RSA key pair
keyPairGenerator.initialize(2048);
keyPair = keyPairGenerator.genKeyPair();
// Build a self-signed certificate
issuer = subject = x500Name.init("CN=Testing");
notBefore = now();
notAfter = dateAdd("yyyy", 1, notBefore); // 1 year validity
serial = bigInteger.valueOf(randRange(1, 99999999));
certificateBuilder = x509v3CertificateBuilder.init(issuer, serial, notBefore, notAfter, subject, keyPair.getPublic());
// Sign the certificate
signatureAlgorithm = "SHA256WithRSAEncryption";
contentSigner = jcaContentSignerBuilder.init(signatureAlgorithm).build(keyPair.getPrivate());
certificateHolder = certificateBuilder.build(contentSigner);
certificate=jcaCertificateConverter.init().getCertificate(certificateHolder).getEncoded();
privateKey = KeyFactory.getInstance("RSA").generatePrivate(PKCS8EncodedKeySpec.init(binaryDecode(tobase64(keyPair.getPrivate().getEncoded()),'base64')));
</cfscript>
<cfoutput>
<h2>Certificate String</h2>
<textarea>#tobase64(certificate)#</textarea>
<h2>Private Key String</h2>
<textarea>#tobase64(keyPair.getPrivate().getEncoded())#</textarea>
</cfoutput>
<cfscript>
privateKeyString = "PRIVATE KEY STRING";
certString = "CERTIFICATE STRING";
xmlString=fileRead("assert.xml");
xmlDoc = XMLParse(xmlString);
KeyFactory = createObject("java", "java.security.KeyFactory");
SecInit = CreateObject("Java", "org.apache.xml.security.Init").Init().init();
SignatureConstants=CreateObject("Java", "org.apache.xml.security.utils.Constants");
SignatureSpecNS = SignatureConstants.SignatureSpecNS;
PKCS8EncodedKeySpec = createObject("java", "java.security.spec.PKCS8EncodedKeySpec");
privateKey = KeyFactory.getInstance("RSA").generatePrivate(PKCS8EncodedKeySpec.init(binaryDecode(privateKeyString, "base64")));
CertificateFactory = createObject("java", "java.security.cert.CertificateFactory");
ByteArrayInputStream = createObject("java", "java.io.ByteArrayInputStream");
certificate = CertificateFactory.getInstance("X.509").generateCertificate(ByteArrayInputStream.init(binaryDecode(certString, "base64")));
XMLSignatureFactory = createObject("java", "javax.xml.crypto.dsig.XMLSignatureFactory");
reference = XMLSignatureFactory.getInstance("DOM").newReference(
"",
XMLSignatureFactory.getInstance("DOM").newDigestMethod("http://www.w3.org/2000/09/xmldsig##sha1", javaCast("null", "")),
[],
javaCast("null", ""),
javaCast("null", "")
);
signedInfo = XMLSignatureFactory.getInstance("DOM").newSignedInfo(
XMLSignatureFactory.getInstance("DOM").newCanonicalizationMethod("http://www.w3.org/TR/2001/REC-xml-c14n-20010315", javaCast("null", "")),
XMLSignatureFactory.getInstance("DOM").newSignatureMethod("http://www.w3.org/2000/09/xmldsig##rsa-sha1", javaCast("null", "")),
[reference]
);
KeyInfoFactory = XMLSignatureFactory.getInstance("DOM").getKeyInfoFactory();
X509Data = KeyInfoFactory.newX509Data([certificate]);
keyInfo = KeyInfoFactory.newKeyInfo([X509Data]);
xmlSignature = XMLSignatureFactory.getInstance("DOM").newXMLSignature(signedInfo, keyInfo);
DOMSignContext = createObject("java", "javax.xml.crypto.dsig.dom.DOMSignContext");
domSignContext.init(privateKey, xmlDoc.getDocumentElement());
xmlSignature.sign(domSignContext);
dump(xmlDoc);
</cfscript>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment