Due to server to server interoperability requirements I was not able to rely on Lucee’s RSA encryption implementation (PKCS 8). Being able to specify the cipher for key generation and encrypt/decrypt is required. The system I was interacting was expecting the encrypted value to have used the PKCS #1 v1.5 cipher algorithm.
Here is how I implemented RSA encryption with Java instead.
private any function encryptCardNumber(required string cardNumber, required string publicKey) {
var secureRandom = createObject("java", "java.security.SecureRandom").init();
var cipher = createObject("java", "javax.crypto.Cipher").getInstance("RSA/ECB/PKCS1Padding", "SunJCE"); // This also is equivalent: getInstance("RSA/None/PKCS1Padding", "BC") for BouncyCastle (org.bouncycastle.jce.provider.BouncyCastleProvider)
// Convert public key from string to java Key object
// First need to convert raw string to ByteArray
var publicKeySpec = createObject('java', 'java.security.spec.X509EncodedKeySpec').init(toBinary(arguments.publicKey));
var keyFactory = createObject('java', 'java.security.KeyFactory').getInstance('RSA');
var key = keyFactory.generatePublic(publicKeySpec);
cipher.init(createObject("java", "javax.crypto.Cipher").ENCRYPT_MODE, key, secureRandom);
return cipher.doFinal(toBinary(toBase64(arguments.cardNumber)));
}