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