首页 > 解决方案 > php:使用 RSA 私钥的字符串加密(从 JAVA 转换为 php)

问题描述

我有这个 JAVA 代码 & 我需要在 php 中写同样的东西:

public static String signMsg(String msg, String privateKey)
throws Exception {
    byte[] bytes = Base64.getDecoder().decode(privateKey);
    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    Signature ps = Signature.getInstance("SHA256withRSA");
    ps.initSign(kf.generatePrivate(spec));
    ps.update(msg.getBytes("UTF-8"));
    byte[] sigBytes = ps.sign();
    return Base64.getEncoder().encodeToString(sigBytes);
}

提前致谢 :)

标签: javaphpencryptionrsaprivate-key

解决方案


关于您的第一种方法:使用私钥创建签名。公钥用于验证签名。关于您的第二种方法:HMAC 与签名不同。

Java 代码加载 PKCS8 格式的私钥,PEM 编码没有页眉和页脚。在 PHP 代码中,可以以相同的格式和编码读取密钥。或者,可以以 PKCS#1 格式加载密钥。关于编码,也接受 PEM 或 DER 编码的密钥。

此外,必须指定用于签名的算法。Java 代码应用带有 PKCS#1 v1.5 填充和 SHA-256 作为摘要的 RSA。此外,生成的签名是 Base64 编码的。为了让 PHP 代码提供相同的 RSA 签名,必须使用相同的参数。

请注意,签名不一定使用相同的消息和相同的密钥生成相同的签名。这取决于算法。但是,对于带有 PKCS#1 v1.5 填充的 RSA,始终会生成相同的签名(确定性)。另一方面,对于 PSS,每次都会生成不同的签名(概率)。

以下 PHP 代码使用 PHPSECLIB 并生成与 Java 代码相同的签名:

use phpseclib3\Crypt\RSA;

$privateKey= 'MIIEvg...';
   
$signatureB64 = base64_encode(                              // Base64 encode signature
    RSA::load($privateKey)->                                // Choose RSA, load private PKCS8 key
    withHash('sha256')->                                    // Choose SHA-256 as digest
    withPadding(RSA::SIGNATURE_PKCS1)->                     // Choose PKCS#1 v1.5 padding
    sign('The quick brown fox jumps over the lazy dog')     // Sign messsage
);

print($signatureB64);

推荐阅读