如何在 PHP 中使用 p8 表单私钥对数据进行数字签名并使用公钥对其进行验证

时间:2021-03-04 07:34:36

标签: php openssl

我创建了一个 P8 格式的私钥并使用 Java 签署了数据,并尝试使用 PHP 中的公钥验证它,但失败了。

我使用 openssl 命令创建了 p8 文件

openssl pkcs8 -topk8 -inform PEM -outform DER -in myprivate.in.key -out myprivate.in.key.p8 -nocrypt

并使用

对 Json 数据进行签名
public byte[] sign(String data, String privateKeyFilePath) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, IOException, SignatureException {
        byte[] returnVal = null;

            Signature signature = Signature.getInstance(RSA_SHA_256);
            PrivateKey privateKey = getPrivateKey(privateKeyFilePath);
            signature.initSign(privateKey);
            signature.update(data.getBytes());
            returnVal = signature.sign();

        return returnVal;
    }

但是当我尝试使用 openssl 命令在 PHP 中使用公共证书验证它时,它失败了

$cert_path = file_get_contents(storage_path('certificates/my_in.cer'));
        $pub_key = openssl_get_publickey($cert_path);
        $keyData = openssl_pkey_get_details($pub_key);
        $pub_key = $keyData['key'];

        // $verify = openssl_x509_verify()
        $verify = openssl_verify($dataSigned, $signatureDecoded, $pub_key, 'sha256WithRSAEncryption');

我做错了什么,还有什么方法可以在 php 中使用 p8 键对数据进行签名!

1 个答案:

答案 0 :(得分:1)

按照这个过程,一切正常。也许对你有用?

使用 openssl 生成密钥:

# Generate PK
openssl genpkey -algorithm RSA \
    -pkeyopt rsa_keygen_bits:2048 \
    -pkeyopt rsa_keygen_pubexp:65537 | \
  openssl pkcs8 -topk8 -nocrypt -outform der > rsa-2048-private-key.p8

# Convert your PKCS#8 file to a plain private key
openssl pkcs8 -nocrypt -in rsa-2048-private-key.p8 -inform DER -out rsa-2048-private-key.pem

# Generate pub key
openssl rsa -in rsa-2048-private-key.pem -pubout -out rsa-2048-public-key.pem

测试pkey和签名数据(index.php):

<?php

$privateKeyFile="file://".__DIR__.DIRECTORY_SEPARATOR."rsa-2048-private-key.pem";
$publicKeyFile="file://".__DIR__.DIRECTORY_SEPARATOR."rsa-2048-public-key.pem";

// Data to sign
$data = 'Hello world!';

// Test on get private key
$pkeyid = openssl_pkey_get_private($privateKeyFile);

if ($pkeyid === false) {
    var_dump(openssl_error_string());
}else{
    var_dump($pkeyid);
}

// Sign data
openssl_sign($data, $signature, $pkeyid);

// Free memory
openssl_free_key($pkeyid);

// Read pub key
$pubkeyid = openssl_pkey_get_public($publicKeyFile);

// Test if sign is ok
$ok = openssl_verify($data, $signature, $pubkeyid);
if ($ok == 1) {
    echo "Sign OK";
} elseif ($ok == 0) {
    echo "Sign NOK";
} else {
    echo "Sign check error";
}
// Free memory
openssl_free_key($pubkeyid);

php -S localhost:8000,http://localhost:8000,返回:

resource(2) of type (OpenSSL key) Sign OK