ColdFusion零字节填充Java 1.6 vs 1.7

ColdFusion零字节填充Java 1.6 vs 1.7,java,encryption,coldfusion,java-7,java-6,Java,Encryption,Coldfusion,Java 7,Java 6,生成的密钥用于AES加密。这是解决这个问题的方法 <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.use

生成的密钥用于AES加密。这是解决这个问题的方法

<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>

在我的本地开发机器(MacOSXMavericks,Java1.6)上,这可以正常工作,并且我能够使用生成的密钥进行加密。然而,在我的生产环境(WindowsServer2008,Java1.7)中,我得到了错误“无效密钥大小”。两个屏幕上的键大小都显示为32,我很困惑


我目前正在更新我的本地开发机器,以匹配服务器上的Java版本,但我仍然想不出在这些简单类中有哪些差异会导致这种情况。

您能提供一个我们可以独立测试的文本值示例吗?另外,您生成自己的密钥而不是使用更安全的方法(如
generateSecretKey
)有什么原因吗?@Leigh我对该密钥使用的API不是我可以控制的。这些是刹车。成功执行与此密钥一起使用的API方法后,服务器将提供一个在后续方法中使用的私钥。我没有设计它,我不能改变它。@Leigh我已经用我的方法更新了这个问题,好的。您是否能够生成一个虚拟/示例密钥,并发布一些测试值,或者这些值都是由另一方生成的(即您无法共享的内容)?此外,我注意到代码没有在此处指定字符集:
plainText.getBytes()
,因此它将使用默认值。如果机器之间的默认值不同,则可能会导致不同的结果。1) 这两台机器的默认设置是什么?2)
getByteArray
的代码是什么?
<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>