Skip to content

Instantly share code, notes, and snippets.

@jeaguilar
Last active February 23, 2021 05:18
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jeaguilar/b9d49f909a4a84a89a70 to your computer and use it in GitHub Desktop.
Save jeaguilar/b9d49f909a4a84a89a70 to your computer and use it in GitHub Desktop.
Basic implementation of encryption and decryption in CFML using AWS KMS and the AWS SDK for Java (Tested on Lucee 4.5)
<cfscript>
// Step 1: Download AWS SDK for Java https://aws.amazon.com/sdk-for-java/
// Step 2: Copy [sdk archive]/lib/aws-java-sdk-1.10.47.jar to WEB-INF/lucee/lib
// Step 3: Create IAM User and obtain basic credentials (Access Key ID and Secret Access Key)
// Step 4: Create IAM Encryption Key add "Step 3 IAM User" as a Key User (remove as Key Administrator)
// Step 5: Obtain Key Id for "Step 4 IAM Encryption Key"
// Reference: http://docs.aws.amazon.com/kms/latest/developerguide/programming-top.html
public Any function getBasicAWSCredentials( required string AccessKeyId, required string SecretAccessKey ) {
return CreateObject(
"java",
"com.amazonaws.auth.BasicAWSCredentials"
).init(
arguments.AccessKeyId,
arguments.SecretAccessKey
);
}
public Any function getAWSKMSClient( required Any credentials ) {
return createObject(
"java",
"com.amazonaws.services.kms.AWSKMSClient"
).init(
arguments.credentials
);
}
public Any function kmsEncrypt( required Any kmsClient, required string plaintext, required string KeyId ){
var b64Plaintext = ToBase64(arguments.plaintext);
var binPlaintext = toBinary(b64Plaintext);
var binPlaintextLen = JavaCast("int", ArrayLen(binPlaintext));
var encryptBuffer = CreateObject("java", "java.nio.ByteBuffer");
var arrBuffer = encryptBuffer.Allocate(binPlaintextLen);
arrBuffer.put(binPlaintext, JavaCast( "int", 0 ), JavaCast( "int", binPlaintextLen));
var bytePlainText = encryptBuffer.wrap( arrBuffer.array() );
var encryptRequest = createObject("java", "com.amazonaws.services.kms.model.EncryptRequest");
encryptRequest.withKeyId(arguments.KeyId).withPlaintext(bytePlainText);
var binCipherText = arguments.kmsClient.encrypt(encryptRequest).getCiphertextBlob().array();
var b64CipherText = toBase64(binCipherText);
return b64CipherText;
}
public Any function kmsDecrypt( required Any kmsClient, required Any b64CipherText ){
var binCipherText = toBinary(arguments.b64CipherText);
var binCipherTextLen = JavaCast("int", ArrayLen(binCipherText));
var decryptBuffer = CreateObject("java", "java.nio.ByteBuffer");
var arrBuffer = decryptBuffer.Allocate(binCipherTextLen);
arrBuffer.put(binCipherText, JavaCast( "int", 0 ), JavaCast( "int", binCipherTextLen));
var byteCipherText = decryptBuffer.wrap( arrBuffer.array() );
var decryptRequest = createObject("java", "com.amazonaws.services.kms.model.DecryptRequest");
decryptRequest.withCiphertextBlob(byteCipherText);
var binPlainText = arguments.kmsClient.decrypt(decryptRequest).getPlaintext();
var strPlainText = toString(binPlainText.array());
return strPlainText;
}
try {
// Set Basic Authentication Credentials
credentials = getBasicAWSCredentials("{YOUR ACCESS KEY ID}", "{YOUR SECRET ACCESS KEY}");
// Create KMS Client
kms = getAWSKMSClient(credentials);
plaintext = "123456789101112";
keyId = "{YOUR KEY ID FROM STEP 5}";
// Encrypt the plaintext, returns Base64
b64CipherText = kmsEncrypt(kms, plaintext, keyId);
writeDump(b64CipherText);
// Decrypt the Base64 Ciphertext, returns a string
decryptedCipherText = kmsDecrypt(kms, b64CipherText);
writeDump(decryptedCipherText);
// If it works, then the plaintext and decryptedCipherText should be identical (returns 0)
writeDump(Compare(plaintext, decryptedCipherText));
}
catch (Any excpt){
writeDump(excpt);
}
</cfscript>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment