Folks, Hoping for some help trying to decrypt a A...
# cfml-general
p
Folks, Hoping for some help trying to decrypt a AES-GCM encrypted JSON object sent via HTTP Header. I am far from an encryption expert. Here are the instructions I have: "The value of the header contains a base64-encoded string that includes the initialization vector, additional authentication data, the cipher text itself, and an authentication tag which are used as inputs for the decryption process. The header also includes the length of each input in bytes:
[ivLength: 1 byte][iv][aadLength: 2 bytes][aad][cipherTextLength: 4 bytes][cipherText][tag: 16 bytes]
Thus, to parse the initialization vector (iv), you would read the first byte of the sequence to get its length. Then, you would read the next n bytes in the sequence to get the actual value of iv. To get the aad, you would read the 2 bytes following the iv to get its length, and then the next m bytes in the sequence to get the aad value. The tag at the end of the sequence has a predetermined length of 16 bytes, so its length is not included." I have had many stops and starts but I am having all kinds of trouble figuring this out. I've poured over many articles from Ben Nadel and others. Here's one of many of my several tries... Hoping someone can point me in the right direction. I have no idea if I'm on the right path or not, but the "aad" errors saying the array is out of bounds.
Copy code
<cfset context = myEncryptedString>

			<cfset contextByte = createObject("Java", "java.lang.String").init(JavaCast("string", context).getBytes())>

			<cfset b64 = createObject("Java", "org.apache.commons.codec.binary.Base64").init().decodeBase64(contextByte)>

			<cfset in = createObject("Java", "java.io.ByteArrayInputStream").init(b64)>

<cfset strt = 1>
			<!---  parse the initialization vector (iv), you would read the first byte of the sequence to get its length --->
			<cfset test = binarySlice( b64, strt, 1 )>
			<cfset ivLength = createObject("Java", "java.io.ByteArrayInputStream").init(test).read()>
			<cfdump var="#ivLength#" label="ivLength"><br><hr> 

			<!--- Then, you would read the next n bytes in the sequence to get the actual value of iv --->
			<cfset strt = 2>
			<cfset iv = binarySlice( b64, strt, ivLength)>
			<cfset iv = createObject("Java", "java.io.ByteArrayInputStream").init(iv).read()>
			<cfdump var="#iv#" label="iv"><br><hr>

			<!--- To get the aad, you would read the 2 bytes following the iv to get its length --->
			<cfset strt = 3+iv>
			<cfset aadlen = binarySlice( b64, strt, 2)>
			<cfset aadlen = createObject("Java", "java.io.ByteArrayInputStream").init(aadlen).read()>
			<cfdump var="#aadlen#" label="aadlen"><br><hr>
			
			<!---  then the next m bytes in the sequence to get the aad value --->
			<!--- <cfset strt = strt+2>
			<cfset aad = binarySlice( b64, strt, aadlen)>
			<cfset aad = createObject("Java", "java.io.ByteArrayInputStream").init(aad).read()>
			<cfdump var="#aad#" label="aad"><br><hr> --->

			<!---  tag at the end of the sequence has a predetermined length of 16 bytes, so its length is not included --->

<!--- Thanks, Ben! --->
<cfscript>
public binary function binarySlice(
		required binary input,
		required numeric index,
		numeric length = 0
		) {
		var result = length
			? arraySlice( input, index, length )
			: arraySlice( input, index )
		;
		return( javaCast( "byte[]", result ) );
	}
</cfscript>
p
Not sure of the necessary need to decode the base64 using java but all you need to simply do is
tostring(tobinary(yourEncrypedWhatever))