使用ColdFusion加密SagePay表单

时间:2014-03-13 20:49:38

标签: encryption coldfusion cryptography sagepay

我正在尝试使用ColdFusion 10遵循SagePay 3.00中加密字段的规范。

要求是使用提供的密码作为密钥和初始化向量,在CBC模式下使用PKCS#5填充将字符串加密为AES(块大小为128位),并将结果编码为十六进制。

"使用提供的密码"这导致了问题。

目前我有

myStr = 'assortednamevaluepairsetc';
providedPassword = 'abcdefghijklmnop';
myCrypt = Encrypt(myStr,providedPassword,'AES/CBC/PKCS5Padding','HEX',providedPassword,1);

但由于SagePay给出的值导致错误而无法正常工作 - "指定的密钥不是此加密的有效密钥:无效的AES密钥长度"因为它只有16个字符长

根据CF文档,你需要使用generateSecretKey来保证AES的密钥长度,所以我试过这个但是虽然它给出了结果,但它在加密方面不是正确的结果

myStr = 'assortednamevaluepairsetc';
providedPassword = 'abcdefghijklmnop';
mySecret = GenerateSecretKey('AES');
myCrypt = Encrypt(myStr,mySecret,'AES/CBC/PKCS5Padding','HEX',providedPassword,1);

感谢任何帮助。

1 个答案:

答案 0 :(得分:4)

  

使用generateSecretKey   保证AES的密钥长度

该功能仅在您需要生成完全加密密钥时使用。你已经有一个。 generateSecretKey的主要目的是确保您生成强大的加密密钥,即sufficiently random

  

不起作用,因为SagePay给出的值导致了   错误 - “指定的密钥不是此加密的有效密钥:无效   AES密钥长度“仅为16个字符

AES的密钥长度16 bytes (ie 128 bits)是可以接受的。问题是encrypt()期望“密钥”是base64编码的字符串,比普通字符串长大约三十三.3%。当你调用encrypt(..)时,CF将提供的“key”字符串解码为字节,即基本上这样做:

  <cfset keyBytes = binaryDecode(yourPassword, "base64")>
  <cfoutput>length = #arrayLen(keyBytes)# bytes</cfoutput>

由于您的密码字符串不是base64编码的,因此生成的密钥长度太小,即(12)而不是(16)字节。因此错误信息。

解决方案是首先对其进行base64编码。 如何取决于字符串的编码。 It sounds like it is just a plain text string(希望是sufficiently random one...)。如果是这样,使用charsetDecode解码相关字符集中的字符串(即utf-8等),然后将binaryEncode解码为base64:

  <cfset keyIVBytes = charsetDecode(yourKeyString, "utf-8")>
  <cfset base64Key = binaryEncode(keyIVBytes, "base64")>

此外,iv参数应为二进制。由于keyiv是同一个,因此只需使用上一步中的字节数组。另外,删除iterations参数,因为它不适用。通过这些更改,它应该按预期工作:

 encrypt(myStr, base64Key,"AES/CBC/PKCS5Padding", "hex", keyIVBytes)

注意:我不是加密专家,但......使用密钥作为iv是NOT a great idea ...可能想与他们核实是否还有其他选项。