我试图使用RSA公钥和Android应用程序对AES密钥进行加密,然后使用PHP和phpseclib解密服务器上的AES密钥。我已经过测试,以确保RSA加密/解密在两个平台上都可以通过加密静态文本并在解密后检查是否仍然可以获得原始文本。根据测试,RSA代码在每个平台上单独运行,但平台之间似乎有区别。Java中的RSA加密,PHP中的解密
在Java中,我使用充气城堡库,并有下面的代码:
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
new BigInteger("00c897f9e401819e223ffbecc6f715a8d84dce9022762e0e2d54fa434787fcaf230d28bd0c3b6b39b5211f74ffc4871c421362ccfc07ae98b88fa9728f1e26b8210ebbf4981e45867fe810938294d0095d341b646b86dcbd4c246676c203cb1584d01eef0635299714d94fa12933ecd35e6c412573156d9e6e549b7804eb6e165660507d8748bcc8c60da10099bacb94d3f7b50b1883ee108489e0dd97ed7d28e564edd4ee5d6b4225f5c23cdaaf495c3fa08c3b82e1674946e4fa1e79b2493204d6953c261105ba5d0f8dcf3fcd39a51fbc18a5f58ffff169b1bed7ceeded2ae0e8e8e2238e8b77b324d1a482593b1a642e688c860e90d5a3de8515caf384133b", 16),
new BigInteger("11", 16));
keyFactory = KeyFactory.getInstance("RSA", "BC");
//RSAPublicKeySpec rsaKeySpec = new RSAPublicKeySpec(rsaKey.MODULUS, new BigInteger("11", 16));
RSAPublicKey pubKey = (RSAPublicKey)keyFactory.generatePublic(pubKeySpec);
//Set up the cipher to RSA encryption
Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
// make sure the Aes Key is less than a block size
// otherwise major errors will occur
if(AesKey.length * 8 > pubKey.getModulus().bitLength())
return "Error: AesKey bigger than block size of RSA Key";
byte[] encryptedKey = cipher.doFinal(AesKey);
// return result Base64 encoded
return Base64.encodeToString(encryptedKey, Base64.DEFAULT);
然后在PHP中,我使用下面的代码来解密AES密钥:
$AESkey = base64_decode($AES);
$rsa = new Crypt_RSA();
$private = file_get_contents($_SERVER['DOCUMENT_ROOT'].'/PrivateData/private_key.pem');
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$rsa->loadKey($private);
$AESkey = $rsa->decrypt($AESkey);
当AES密钥被服务器解密时,我总是得到以下错误:1911行C:\ xampp \ php \ PEAR \ phpseclib \ Crypt \ RSA.php中的解密错误。查看RSA.php中的代码,我认为这个错误与加密期间填充不正确有关,但我似乎无法弄清楚方法来解决它。
更新:我发现上述加密/解密代码实际上是正确的。我遇到的问题是,在将数据从应用程序发送到PHP之前,我没有对输出进行网址编码,因此一些信息丢失了。
错误意味着前两个高位字节一个是错误的,通常表示一个非常严重的错误,如私钥不正确。可能会有一个排序问题?这是我会检查的另一件事。 –
我究竟该如何检查?我有一种感觉,自己没有任何问题,因为我可以让它工作,如果我在PHP中同时执行加密和解密,但我认为这可能是一个问题,我如何将公钥输入到Java或者我在Java中使用的填充方案。 – UmangB
检查的一种方法是反转密码字节并查看解密是否成功。但最好的方法是找到一些已知的好测试向量,看看它们是如何被PHP端处理的。如果您可以在phpseclib中设置断点来检查中间值,这也会有所帮助。 –