首页 > 解决方案 > Java 到 PHP:使用 RSA 加密 base 64 密钥

问题描述

我正在尝试在 PHP 中复制以下 java 函数。

Java 代码:

public static String signWithRSA(SecretKey value, Path keyPath) throws InvalidPublicKeyException {
        try(FileInputStream fin = new FileInputStream(keyPath.toFile())){
            CertificateFactory f = CertificateFactory.getInstance("X.509");
            X509Certificate certificate = (X509Certificate)f.generateCertificate(fin);
            PublicKey pk = certificate.getPublicKey();
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pk);
            byte [] appKeyBytes = Base64.getEncoder().encode(value.getEncoded());
            return Base64.getEncoder().encodeToString(cipher.doFinal(appKeyBytes));
        } catch (NoSuchAlgorithmException
                | IllegalBlockSizeException
                | BadPaddingException
                | NoSuchPaddingException
                | InvalidKeyException
                | CertificateException
                | IOException e) {
            throw new InvalidPublicKeyException("Invalid Certificate Provided: "+e.getMessage());
        }
    }

我从这段代码中了解到的是,

1. Getting Certificate from File,
2. Get PublicKey 
3. RSA encode the PublicKey
4. Base64encode the PrivateKey
5. RSA Encode the encodedPrivateKey with encodedPublicKey and retrn the Base64EncodedValue

I have tried with the following code: (PHP 7.2, PhpSecLib)
require __DIR__ . '/vendor/autoload.php';

use phpseclib\Crypt\RSA;
use phpseclib\Math\BigInteger;

$testCertLocation ="resource/public.cer";

$pub_key = openssl_get_publickey(file_get_contents($testCertLocation));

$keyData = openssl_pkey_get_details($pub_key);

$mykey_n= ($keyData['rsa']['n']);
$mykey_e = ($keyData['rsa']['e']);

$mykey_n_h = bin2hex($mykey_n);
$mykey_e_h = bin2hex($mykey_e);


$rsa = new RSA();

$r = $rsa->loadkey(
    array(
      'e' => new BigInteger($mykey_e_h, 16),
      'n' => new BigInteger($mykey_n_h, 16)
    ),
    3 
);

$providedEncodedKey = "guRPIRvUYvgqRL5AaLuDYl69dOhVH8+R763oM2Y6iXg=";
$plaintext = $providedEncodedKey;

$rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
$ciphertext = $rsa->encrypt($plaintext);
echo base64_encode($ciphertext) . "<br>";

echo $rsa->verify($plaintext, $ciphertext) ? 'verified' : 'unverified';

我面临以下问题:

  1. 密文随着每次刷新而不断变化(我认为它不应该改变给定的常数。不过我可能是错的。)

  2. 它与提供的样本不匹配(对于给定的明文)。提供的值为:

dWXiHslSGaKwQB6D93Q2lBNOl4x+N73wtDEU5E39IM3c0Cd2HrFO9EB9ZCK+qyUxU/zdEdx2GYw5a0mV9OXPwLONJYBFuN
ApHRyxRQAS8fLwtuSUKWzygsMPekd+AhvuPUlJO+9Qfutq2igy+kCNVe0lJWZqOY4l7FNQGd3XdDapRaNhgiFw3VV1O00d
elrCM9rKCaDUN6HFAmLy11zK/vMbXmy0YA8PUoX1mJvaxQwFEQWvJhG++NRQL3KtHWNPDKA0irkWoZqpZF/XyUS1zmXuMI
3SZ7c2bG6rHFebby1t/TVr3jcHSwKmLVMGIJi4QtdWRT6Rjl3FnN4DVunPbg==

The Certificate details are as follows:
N: ceeb7b9b5cc4c84e5a050d4082fa59c19a23583a2d861de03415a36f6660feed43a2d6047fe0d42513a996691d7
6e499c240005afe5a1ad01a677327b6de049740fd319acbff15bfd56a27f23b1c648c1cd6f9533fb20387f88c0cb92
6ff1f5eb87bbe79a03803072158a54fe91a2ccaf4227c1ec682e71d35f5f711bf0278f1ee1007d77f7f24df4378967
9d512221837c0e100d6ed6d699749923530c299df0814ea60a94006f747ca6ff2cb992233d67aebb1681c815c5fed1
c5d2c3c1b3c25241276d7f2d59a07d9845f9c5e81cdd7c5269038a35cd1cfd990af953fc8f5531aabdb30ed524f46a
e6a03f024325069078530e1ff8c2c069373d57e45b5f5
E: 010001

The result which I am getting is ($ciphertext) as follows:
sbQK1CBP06ByLZyJObc3bm6EAyfHvgAPvPMkKy+RCFqQiW9maKc9qqwliYgLYtNhF6aDCrEv/jtTHPZn3YqDbVnIXGcG63
dcn/YK9NVkHj+f4aRSPO99mAUMDeSjTkiMgfhIGO8yMWp7SvFL8tynFP/+j4W5KkyS+vOkwocCy1OdK3VN5u0fnFPUUFMH
/WEodMFndz5fF49vI9ZGioIge75kgTxvKzwroQ+BRML59ZL+PNM1M5QbAqVnyF4KE7iL1Lj/KvKMdnLkU6z/8Atpnw7jz1
8DRna5ztQpGKWGkUs1IiEYAZmRTl77FXfQfDeGOtEl38V9pmwCtGPUHf6Ctw==

unverified

谢谢。

标签: javaphpencryptionrsaphpseclib

解决方案


推荐阅读