I'm trying use JKS XML signature in Lucee, but when test my code ocurring the follow error
cannot load class through its string name, because no definition for the class with the specified name [java.security.KeyStore.PasswordProtection] could be found caused by (java.lang.ClassNotFoundException:java.security.KeyStore.PasswordProtection;java.lang.ClassNotFoundException:java.security.KeyStore.PasswordProtection;)
Lucee "createObject" function does not imports java.security.KeyStore.PasswordProtection
My code:
<cfobject type="java" name="FileInputStream"/>
<cfobject type="java" name="FileOutputStream"/>
<cfobject type="java" name="OutputStream"/>
<cfobject type="java" name="KeyStore"/>
<cfobject type="java" name="PasswordProtection"/>
<cfobject type="java" name="X509Certificate"/>
<cfobject type="java" name="ArrayList"/>
<cfobject type="java" name="Collections"/>
<cfobject type="java" name="List"/>
<cfobject type="java" name="CanonicalizationMethod"/>
<cfobject type="java" name="DigestMethod"/>
<cfobject type="java" name="Reference"/>
<cfobject type="java" name="SignedInfo"/>
<cfobject type="java" name="Transform"/>
<cfobject type="java" name="XMLSignature"/>
<cfobject type="java" name="XMLSignatureFactory"/>
<cfobject type="java" name="DOMSignContext"/>
<cfobject type="java" name="KeyInfo"/>
<cfobject type="java" name="KeyInfoFactory"/>
<cfobject type="java" name="X509Data"/>
<cfobject type="java" name="C14NMethodParameterSpec"/>
<cfobject type="java" name="TransformParameterSpec"/>
<cfobject type="java" name="DocumentBuilderFactory"/>
<cfobject type="java" name="Transformer"/>
<cfobject type="java" name="TransformerFactory"/>
<cfobject type="java" name="DOMSource"/>
<cfobject type="java" name="StreamResult"/>
<cfobject type="java" name="Document"/>
<cfscript>
fac = XMLSignatureFactory.getInstance();
// Create a Reference to the enveloped document (in this case,
// you are signing the whole document, so a URI of "" signifies
// that, and also specify the SHA1 digest algorithm and
// the ENVELOPED Transform.
writeOutput("Creating a reference to the enveloped document...");
ref = fac.newReference("", fac.newDigestMethod(DigestMethod.SHA256, nullValue()),Collections.singletonList(fac.newTransform(Transform.ENVELOPED, nullValue())), nullValue(), nullValue());
// Create the SignedInfo.
writeOutput("Creating a Signed Info...");
si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, nullValue()),
fac.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more##rsa-sha256", nullValue()), Collections.singletonList(ref));
// Instantiate the document to be signed.
writeOutput("Instantiate the document to be signed... in this case it's purchaseOrder.xml");
dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
doc = dbf.newDocumentBuilder().parse(FileInputStream.init(expandPath("purchaseOrder.xml")));
writeOutput("Load the keystore stored in this project to get our keys and certificate...");
// Load the KeyStore and get the signing key and certificate.
ks = KeyStore.getInstance("JKS");
ks.load(FileInputStream.init(expandPath("changeit.keystore")), "changeit".toCharArray());
keyEntry = ks.getEntry("myAlias", KeyStore.PasswordProtection("changeit".toCharArray()));
cert = keyEntry.getCertificate();
// Create the KeyInfo containing the X509Data.
kif = fac.getKeyInfoFactory();
x509Content = new ArrayList();
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(cert);
xd = kif.newX509Data(x509Content);
ki = kif.newKeyInfo(Collections.singletonList(xd));
// Create a DOMSignContext and specify the RSA PrivateKey and
// location of the resulting XMLSignature's parent element.
writeOutput("Creating a DomSignContext with our privateKey...");
dsc = new DOMSignContext(keyEntry.getPrivateKey(), doc.getDocumentElement());
// Create the XMLSignature, but don't sign it yet.
writeOutput("Creating the XMLsignature but don't sign it...");
signature = fac.newXMLSignature(si, ki);
// Marshal, generate, and sign the enveloped signature.
writeOutput("Marshal, generate and sign the enveloped signature...");
signature.sign(dsc);
// Output the resulting document.
os = FileOutputStream.init(expandPath("signedPurchaseOrder.xml"));
tf = TransformerFactory.newInstance();
trans = tf.newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(os));
writeOutput("Output to signedPurchaseOrder.xml ...");
// Validate our created signedPurchaseOrder.xml with our provided public key.
writeOutput("Validate our signedPurchaseOrder.xml ...");
// new Validation().validate(cert.getPublicKey(), "signedPurchaseOrder.xml");
</cfscript>
Can anybody help me?
Thanks,
CodePudding user response:
PasswordProtection
is an inner class of java.security.KeyStore
. To instantiate it in Lucee you need to use a $
, so change
<cfobject type="java" name="PasswordProtection"/>
to
<cfobject type="java" name="PasswordProtection"/>