繁体   English   中英

Java 中的 RSA 加密/PHP 中的解密失败

[英]RSA Encryption in Java / Decryption in PHP Fails

我有一个 PHP 脚本,我一直在使用它来解密我从 iOS 加密的会话密钥。 加密是在客户端使用 1024 位公钥完成的。 服务器端的解密是使用相应的私钥完成的。 现在我正在尝试为 Android 编写一种加密方法。 不幸的是,解密继续失败,我看不出哪里出了问题。

这是安卓代码:

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_private_decrypt行没有得到正确的解密结果。

由于我的 PHP 脚本适用于我的 iOS 代码,除非绝对必要,否则我不想更改它。 谁能看到我应该如何处理我的 Java 代码以使其与 PHP 端发生的事情保持一致?

您的 PHP 函数具有OPENSSL_PKCS1_OAEP_PADDING但您的 java 函数使用的是RSA/ECB/PKCS1PADDING

  1. 将您的 PHP 解密更改为OPENSSL_PKCS1_PADDING ,这似乎与您的 Java 加密相匹配。

或者

  1. 将您的 java 加密切换到RSA/ECB/OAEPWithSHA-1AndMGF1Padding

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM