在 ColdFusion 中创建 Google reCAPTCHA 'secure token'
Creating a Google reCAPTCHA 'secure token' in ColdFusion
Google 允许您为 reCAPTCHA 创建 'secure token',这意味着您可以在多个域中使用相同的 key/secret。无需为您管理的每个域创建 key/secret。
这是他们的文档,正如您所看到的,除了 an example in Java 之外,它对令牌的加密方式一无所知。我的问题是这将如何用 ColdFusion 编写。我已经尝试了 4 个小时,但就是无法正常工作。我审查过的其他示例:
有哪位 ColdFusion 加密大师知道如何做到这一点?
更新
谢谢 Leigh,认为我们已经走得更远了,但仍然看到 'invalid stoken'。这是我拥有的:
json_token = '{"session_id":"#createUUID()#","ts_ms":#dateDiff("s", dateConvert("utc2Local", "January 1 1970 00:00"), now())#}';
secret_key_hash = hash(secret_key,"SHA", "UTF-8");
secret_key_binary = binaryDecode(secret_key_hash, "hex");
secret_key_aes = arraySlice(secret_key_binary,1,16);
secret_key_base64 = binaryEncode( javacast("byte[]", secret_key_aes), "base64");
secure_token = Encrypt(json_token,secret_key_base64,"AES/ECB/PKCS5Padding",'base64');
我们在 Java 1.7 上使用 ColdFusion 9,arraySlice 方法不可用或底层 java.subList()。所以我们使用 cflib.org 中的 arraySlice UDF。
我也看到了PHP实现上关于URL编码的评论,所以我最后也试了这个,没有效果:
secure_token = Replace(secure_token,"=","","ALL");
secure_token = Replace(secure_token,"+","-","ALL");
secure_token = Replace(secure_token,"/","_","ALL");
注意: 发布这个是因为我在问题关闭之前已经写好了。尽管将来,请在问题中包含您尝试过的代码。它会有助于澄清这个问题(并且可能避免它被关闭为 "too broad")
no insight on how the token is encrypted
如果您只停留在加密部分,它看起来像是来自 the java example 的标准 AES 加密(ECB 模式和 PKCS5Padding)。唯一棘手的部分是加密密钥的处理。
byte[] key = siteSecret.getBytes("UTF-8");
key = Arrays.copyOf(MessageDigest.getInstance("SHA").digest(key), 16);
在 java 代码中,getKey()
方法解码密钥字符串并使用 SHA1, which produces 20 bytes (or 160 bits). Since that is not a valid AES key size, the code grabs the first sixteen (16) bytes to use as a 128 bit AES encryption key. The rest of the java code is just basic AES encryption, which you can easily reproduce in CF using the encrypt()
函数对其进行哈希处理。
要在 CF 中复制加密:
散列 secretKey 字符串
hashAsHex = hash(secretKey, "SHA", "UTF-8");
然后将哈希解码为二进制,这样您就可以提取前十六 (16) 个字节。这为您提供了 128 位 AES 加密密钥(二进制形式):
hashAsBinary = binaryDecode(hashAsHex, "hex");
keyBytes = arraySlice(hashAsBinary, 1, 16);
现在只需将密钥字节转换为 base64 字符串,并将其传递给 encrypt() 函数:
keyAsBase64 = binaryEncode( javacast("byte[]", keyBytes), "base64");
token = encrypt(jsonToken, keyAsBase64 , "AES/ECB/PKCS5Padding", "base64");
就是这样。我会让你自己解决剩下的问题。
Google 允许您为 reCAPTCHA 创建 'secure token',这意味着您可以在多个域中使用相同的 key/secret。无需为您管理的每个域创建 key/secret。
这是他们的文档,正如您所看到的,除了 an example in Java 之外,它对令牌的加密方式一无所知。我的问题是这将如何用 ColdFusion 编写。我已经尝试了 4 个小时,但就是无法正常工作。我审查过的其他示例:
有哪位 ColdFusion 加密大师知道如何做到这一点?
更新
谢谢 Leigh,认为我们已经走得更远了,但仍然看到 'invalid stoken'。这是我拥有的:
json_token = '{"session_id":"#createUUID()#","ts_ms":#dateDiff("s", dateConvert("utc2Local", "January 1 1970 00:00"), now())#}';
secret_key_hash = hash(secret_key,"SHA", "UTF-8");
secret_key_binary = binaryDecode(secret_key_hash, "hex");
secret_key_aes = arraySlice(secret_key_binary,1,16);
secret_key_base64 = binaryEncode( javacast("byte[]", secret_key_aes), "base64");
secure_token = Encrypt(json_token,secret_key_base64,"AES/ECB/PKCS5Padding",'base64');
我们在 Java 1.7 上使用 ColdFusion 9,arraySlice 方法不可用或底层 java.subList()。所以我们使用 cflib.org 中的 arraySlice UDF。
我也看到了PHP实现上关于URL编码的评论,所以我最后也试了这个,没有效果:
secure_token = Replace(secure_token,"=","","ALL");
secure_token = Replace(secure_token,"+","-","ALL");
secure_token = Replace(secure_token,"/","_","ALL");
注意: 发布这个是因为我在问题关闭之前已经写好了。尽管将来,请在问题中包含您尝试过的代码。它会有助于澄清这个问题(并且可能避免它被关闭为 "too broad")
no insight on how the token is encrypted
如果您只停留在加密部分,它看起来像是来自 the java example 的标准 AES 加密(ECB 模式和 PKCS5Padding)。唯一棘手的部分是加密密钥的处理。
byte[] key = siteSecret.getBytes("UTF-8"); key = Arrays.copyOf(MessageDigest.getInstance("SHA").digest(key), 16);
在 java 代码中,getKey()
方法解码密钥字符串并使用 SHA1, which produces 20 bytes (or 160 bits). Since that is not a valid AES key size, the code grabs the first sixteen (16) bytes to use as a 128 bit AES encryption key. The rest of the java code is just basic AES encryption, which you can easily reproduce in CF using the encrypt()
函数对其进行哈希处理。
要在 CF 中复制加密:
散列 secretKey 字符串
hashAsHex = hash(secretKey, "SHA", "UTF-8");
然后将哈希解码为二进制,这样您就可以提取前十六 (16) 个字节。这为您提供了 128 位 AES 加密密钥(二进制形式):
hashAsBinary = binaryDecode(hashAsHex, "hex"); keyBytes = arraySlice(hashAsBinary, 1, 16);
现在只需将密钥字节转换为 base64 字符串,并将其传递给 encrypt() 函数:
keyAsBase64 = binaryEncode( javacast("byte[]", keyBytes), "base64"); token = encrypt(jsonToken, keyAsBase64 , "AES/ECB/PKCS5Padding", "base64");
就是这样。我会让你自己解决剩下的问题。