<cfset var strB = createObject("java", "java.lang.StringBuilder")/>
<cfloop from=1 to=32 index="i">
<cfset zeroPad = zeroPad & URLDecode("%00")/>
</cfloop>
<cfset strB.append(arguments.username)/>
<cfset strB.append(arguments.password)/>
<cfset strB.append(zeroPad)/>
<cfif strB.length() GT 32>
<cfset key = strB.substring(0,32)/>
<cfelse>
<cfset key = strB.toString()/>
</cfif>
The key being generated is used for AES encryption. Here's the method for that...
<cffunction name="aesEncrypt" returntype="string" output="no">
<cfargument name="plainText" type="string" />
<cfargument name="key" type="string" />
<cfset var cipher = CreateObject("java", "javax.crypto.Cipher")/>
<cfset var system = CreateObject("java", "java.lang.System")/>
<cfset var secretkeyspec = CreateObject("java", "javax.crypto.spec.SecretKeySpec")/>
<cfset var ivparamspec = CreateObject("java", "javax.crypto.spec.IvParameterSpec")/>
<cfset var b64 = CreateObject("java", "org.apache.commons.codec.binary.Base64")/>
<cfset var result = ""/>
<cfset var keyBytes = getByteArray(32)/>
<cfset var iv = getByteArray(16)/>
<cfset var b = key.getBytes('UTF-8')/>
<cfset var cipher = cipher.getInstance("AES/CBC/PKCS5Padding")/>
<cftry>
<cfset keyLen = len(b)/>
<cfif keyLen gt len(keyBytes)>
<cfset keyLen = len(keyBytes)/>
</cfif>
<cfset system.arraycopy(b, 0, keyBytes, 0, keyLen)/>
<cfset system.arraycopy(b, 0, iv, 0, 16)/>
<cfset keySpec = secretkeyspec.init(keyBytes, "AES")/>
<cfset ivSpec = ivparamspec.init(iv)/>
<cfset cipher.init(cipher.ENCRYPT_MODE, keySpec, ivSpec)/>
<cfset results = cipher.doFinal(plainText.getBytes())/>
<cfset result = binaryEncode(results, "Base64")/>
<cfcatch type="any">
<cfthrow message="#cfcatch.Message# (plainText:#plainText# key:#key#)"/>
</cfcatch>
</cftry>
<cfreturn result/>
</cffunction>
<cffunction name="getByteArray" access="private" returnType="binary" output="no">
<cfargument name="size" type="numeric" required="true"/>
<cfset var emptyByteArray =
createObject("java", "java.io.ByteArrayOutputStream").init().toByteArray()/>
<cfset var byteClass = emptyByteArray.getClass().getComponentType()/>
<cfset var byteArray =
createObject("java","java.lang.reflect.Array").newInstance(byteClass, arguments.size)/>
<cfreturn byteArray/>
</cffunction>
On my local dev machine (Mac OS X Mavericks, Java 1.6) this works fine and I'm able to encrypt with the generated key. However, on my Production environment (Windows Server 2008, Java 1.7) I'm getting error "Invalid key size". The key size on both shows as 32 and I'm flummoxed.
I'm currently updating my local dev machine to match the Java version on server, but I still can't think of what the differences are in such simple classes that would cause this.