How to digitally Sign data using p8 form private key in PHP and Verify it using Public key

Viewed 555

I created a P8 format Private Key and signed data Using Java and tried to verify it using Public Key in PHP which Failed.

I created p8 file using openssl command

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

and Signed a Json data using

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;
    }

But When I tried to verify it using Public cerificate in PHP using openssl command, it failed

$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');

What am I doing wrong, Also is there a way I can Sign the data using p8 key in php!

1 Answers

By following this process everything is ok. Maybe it will be useful to you?

Use openssl to generate keys:

# 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

Test pkey and sign data (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, returns:

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