Java中的RSA加密/PHP中的解密失败
我有一个PHP脚本,我一直在使用它来解密我从iOS加密的会话密钥。加密在客户端上使用1024位公钥完成。服务器端的解密使用相应的私钥完成。现在我正在尝试为Android编写一种加密方法。不幸的是,解密继续失败,我看不出哪里出了问题 以下是Android代码:Java中的RSA加密/PHP中的解密失败,java,php,android,cryptography,rsa,Java,Php,Android,Cryptography,Rsa,我有一个PHP脚本,我一直在使用它来解密我从iOS加密的会话密钥。加密在客户端上使用1024位公钥完成。服务器端的解密使用相应的私钥完成。现在我正在尝试为Android编写一种加密方法。不幸的是,解密继续失败,我看不出哪里出了问题 以下是Android代码: public String encryptSessionKeyWithPublicKey(String pemString, byte[] sessionKey) { try { PublicKey publicKe
public String encryptSessionKeyWithPublicKey(String pemString, byte[] sessionKey) {
try {
PublicKey publicKey = getPublicKeyFromPemFormat(pemString);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cipherData = cipher.doFinal(sessionKey);
return Base64.encodeToString(cipherData, Base64.DEFAULT);
} catch (IOException ioException) {
Log.e(TAG, "ioException");
} catch (NoSuchAlgorithmException exNoSuchAlg) {
Log.e(TAG, "NoSuchAlgorithmException");
} catch (InvalidKeySpecException exInvalidKeySpec) {
Log.e(TAG, "InvalidKeySpecException");
} catch (NoSuchPaddingException exNoSuchPadding) {
Log.e(TAG, "NoSuchPaddingException");
} catch (InvalidKeyException exInvalidKey) {
Log.e(TAG, "InvalidKeyException");
} catch (IllegalBlockSizeException exIllBlockSize) {
Log.e(TAG, "IllegalBlockSizeException");
} catch (BadPaddingException exBadPadding) {
Log.e(TAG, "BadPaddingException");
}
return null;
}
private PublicKey getPublicKeyFromPemFormat(String PEMString)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException
{
AssetManager assetManager = context.getAssets();
InputStream inputStream = assetManager.open(PEMString);
BufferedReader pemReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer content = new StringBuffer();
String line = null;
while ((line = pemReader.readLine()) != null) {
if (line.indexOf("-----BEGIN PUBLIC KEY-----") != -1) {
while ((line = pemReader.readLine()) != null) {
if (line.indexOf("-----END PUBLIC KEY") != -1) {
break;
}
content.append(line.trim());
}
break;
}
}
if (line == null) {
throw new IOException("PUBLIC KEY not found");
}
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(new X509EncodedKeySpec(Base64.decode(content.toString(), Base64.DEFAULT)));
}
PHP脚本相当简单:
<?php
$passphrase = 'xxxxxxxx'; // just for testing - load from file later
$decrypted_session_key = 'unavailable';
$encrypted_session_key = base64_decode($_POST['encrypted_session_key']);
$fp = fopen('private128.pem', 'r');
if ($fp == null) {
$arr = array('response' => 'failure', 'message' => 'private key not readable');
echo json_encode($arr);
die();
}
$priv_key = fread($fp, 8192);
fclose($fp);
$res = openssl_get_privatekey($priv_key, $passphrase);
$decr_result = openssl_private_decrypt($encrypted_session_key, $decrypted_session_key, $res, OPENSSL_PKCS1_OAEP_PADDING);
if (!$decr_result) {
$arr = array('response' => 'failure', 'message' => $decr_result);
echo json_encode($arr);
die();
}
// write the decrypted string to a file
$session_key_file = fopen("session_key", "w") or die("Unable to open file!");
fwrite($session_key_file, $decrypted_session_key);
fclose($session_key_file);
$arr = array('response' => 'success', 'message' => 'server confirms receipt of session key');
echo json_encode($arr);
?>
我要加密的是16个随机生成的字节
PHP输出为:
{“response”:“failure”,“message”:false}
这意味着openssl\u private\u decrypt
行没有得到正确的解密结果
由于我的PHP脚本与我的iOS代码一起工作,除非绝对必要,否则我不想更改它。有人能看到我应该如何处理我的Java代码,使其与PHP端发生的事情保持一致吗 您的PHP函数有
OPENSSL\u PKCS1\u OAEP\u PADDING
但您的java函数使用的是RSA/ECB/PKCS1PADDING
您的PHP函数具有
OPENSSL\u PKCS1\u OAEP\u PADDING
但您的java函数使用的是RSA/ECB/PKCS1PADDING
一般来说,您应该只做
$priv\u key=file\u get\u contents(…)
。考虑一下如果你的密钥文件的长度超过8K,你会加载一个部分密钥。我知道私钥文件只有1751字节。消息有多长?我只是加密16个随机生成的字节(128位)。一般来说,你应该只做$priv\u key=file\u get\u contents(…)
。考虑一下如果你的密钥文件的长度超过8K,你会加载一个部分密钥。我知道私钥文件只有1751字节。消息有多长?我只是在加密16个随机生成的数据字节(128位)…我知道填充会在某个地方出现。非常感谢!选择OAEP,而不是PKCS1。请更改“javascript”->“java”。解决方案2很有帮助!ThanksI知道填充物会在某个地方出现。非常感谢!选择OAEP,而不是PKCS1。请更改“javascript”->“java”。解决方案2很有帮助!谢谢