我已经生成了一个RSA Keypair from JavaScript,现在我想在Java应用程序中使用公钥(CFML,实际上,但我直接使用Java库)来解密之间的消息两个。
从JS生成密钥对后,pubkey以十六进制字符串的形式传输到服务器。例如:
idliZFy2GQOwVoPHIlDlBSbJd9jFw7DPKzDfZnPOSo4pGpSjjvfyXQaBc+OCSLc3C6+H0XE02T0Bjd40RuGzhw==
这是我的代码,用于尝试使用该十六进制字符串来水合RSA公钥对象并使用它来解密密文。
private function decryptPayload( payload, pubKey ){
//adapted from:
// http://www.12robots.com/index.cfm/2010/7/19/Using-Asymmetric-Cryptography-in-your-ColdFusion-Application--Security-Series-1610
var cipher = createObject('java', 'javax.crypto.Cipher').getInstance("RSA");
var decMode = cipher.DECRYPT_MODE;
var returnStr = "";
var pubkeyByteArray = BinaryDecode( pubKey, "Base64" );
var specs = createObject("java","java.security.spec.X509EncodedKeySpec").init( pubkeyByteArray );
var inflated = createObject('java', 'java.security.KeyFactory').getInstance("RSA").generatePublic(specs);
cipher.init( decMode, inflated );
returnStr = cipher.doFinal( arguments.payload, 0, len(arguments.payload) );
return toString(returnStr, "UTF8");
}
但是,当我运行它时,为pubKey
参数传递上面的十六进制字符串,我在行上收到错误无效的RSA公钥编码。:
var inflated = createObject('java', 'java.security.KeyFactory').getInstance("RSA").generatePublic(specs);
我感觉我只是在某个地方错过了一步,但我不知道该怎么做。我错过了什么或做错了什么?
尝试使用评论中的RSAPublicKeySpec建议:
private function decryptPayload( payload, pubKey = 'jx7I6P0BoE+oIStMrtTx54D0QRhs69qQkdopthDGb4Ji4UzP/mZZEcnjfZjgQzZ9ciwU0fkCHmpS9K5CmQp34w==' ){
//adapted from:
// http://www.12robots.com/index.cfm/2010/7/19/Using-Asymmetric-Cryptography-in-your-ColdFusion-Application--Security-Series-1610
var cipher = createObject('java', 'javax.crypto.Cipher').getInstance("RSA");
var decMode = cipher.DECRYPT_MODE;
var returnStr = "";
var pubkeyByteArray = BinaryDecode( pubKey, "Base64" );
var modulous = createObject('java','java.math.BigInteger').init(pubkeyByteArray);
var exponent = createObject('java', 'java.math.BigInteger').init( "03", 16 );
var keyspec = createObject('java', 'java.security.spec.RSAPublicKeySpec').init( modulous, exponent );
var inflated = createObject('java', 'java.security.KeyFactory').getInstance("RSA").generatePublic(keyspec);
cipher.init( decMode, inflated );
returnStr = cipher.doFinal( arguments.payload ); //, 0, len(arguments.payload)
return toString(returnStr, "UTF8");
}
writeOutput(decryptPayload('59e948...59c3529b4fae61dd0a6e36'));
在这里,我可以从十六进制值创建一个模数BigInt
,从已知值“03”创建一个指数BigInt
,然后将它们输入RSAPublicKeySpec
,然后输入结果规范到我的RSA cipher
实例没有问题。
现在我停留在doFinal()
步骤,因为方法签名不匹配。我试图传递一个字符串,但似乎它想要一个字节数组。我不确切地知道我从JS encrypt()调用中得到什么,或者如何将其转换为ByteArray。