简体   繁体   中英

Signing signature in Node JS and verifying it on PHP

I have this working example, whereby I have created private key and public key on PHP. The below code works fine & signature is valid WHEN i am using pure php. However, the idea is to generate signature with Javscript and then validate the signature with PHP. Is this possible?

<?php
    //create new private and public key

    $new_key_pair = openssl_pkey_new(array(
        "private_key_bits" => 2048,
        "private_key_type" => OPENSSL_KEYTYPE_RSA,
    ));

    openssl_pkey_export($new_key_pair, $private_key_pem);

    /**
     * FrontEnd Flow
     */
    $obj = (object) [
        'name' => 'alex',
        'age' => 27,
        'time' => time() //adding this will create new signature every time
    ];

    $data = base64_encode(json_encode($obj));

    //Get Private Key
    $pem_private_key = file_get_contents('private_key.pem');
    $private_key = openssl_pkey_get_private($pem_private_key);

    // To encrpt data
    $isvalid = openssl_private_encrypt ($data, $crypted , $pem_private_key,OPENSSL_PKCS1_PADDING);  
 
    //create signature
    openssl_sign($data, $signature, $private_key, OPENSSL_ALGO_SHA256);

    /**
     * End of FrontEnd Flow
     * ================================================
     */

    /**
     * BackEnd Flow
     */
    //Get Public Key
    $pem_public_key = openssl_pkey_get_details($private_key)['key'];

    //verify signature
    $result = openssl_verify($data, $signature, $pem_public_key, "sha256WithRSAEncryption");
    if ($result == 1) {
        echo    "\n DATA: " . $data;
        echo    "\n SIGNATURE: " . base64_encode($signature);
        //if signature is valid, decrypt data
        openssl_public_decrypt ($crypted, $decrypted , $pem_public_key,OPENSSL_PKCS1_PADDING);  
        echo "\n  Data decryption : ". base64_decode($decrypted);

    } elseif ($result == 0) {
        echo "signature is invalid for given data.";
    } else {
        echo "\n error: ".openssl_error_string();
    }

    /**
     * End of BackEnd Flow
     */
?>

However how do I sign signature in Node JS, specifically the front end flow from the above code. This is what I have tried & it doesn't work, it keeps returning invalid signature.

//Node.js

const fs = require("fs");
const crypto = require("crypto");
const signer = crypto.createSign("RSA-SHA256");

// Creating a function to encrypt string
function encryptString(data, privateKey) {
  // privateEncrypt() method with its parameters
  const encrypted = crypto.privateEncrypt(privateKey, data);
  return encrypted.toString("base64");
}

let obj = {
  name: "alex",
  age: 27,
  time: Date.now(),
};

let data = btoa(JSON.stringify(obj));
//Get Private Key
let privateKey = fs.readFileSync("./private_key.pem");
//Encrypt data
let encoded = encryptString(data, privateKey);
signer.update(encoded);
signature_b64 = signer.sign(privateKey, "base64");
console.log(signature_b64, obj);
console.log(encoded);

My verification flow to validate signature produced by Node.js is this

<?php
    $pem_private_key = file_get_contents('private_key.pem');
    $private_key = openssl_pkey_get_private($pem_private_key);

    //Get Public Key
    $pem_public_key = openssl_pkey_get_details($private_key)['key'];
//from nodejs's signature variable
    $signature = 
    "MAgFdpMSHYRKIQjbfeqlLwHgostJN0YrkeBrNwapk6qYsNaSt7M+cA2y+rzQNOw35D3nxrDP5ICx8mVErMwu5uptkhFyaxay+DbBufHvfQvnXhq/bAZR9I7PAfS23cnNBnEmchATY/exVCk2tB82GattHbXIJxEcC2Z8OwI4+1hdAg31PbC7fjjeXxKh9ZGYtZVfpjhFzH2ybcsPqLnYJRoWTxg6CfO+/Mp6f+SI5KKqB5tYxqoHtdcL4Tw2xK3NQPmqoUoKAynO3hzp/jMyI0QnSnnpgJJOHcJB9llrvBolShvgqL8It0uVCNFD0Qj8Vaix0LRLOSMxftirQTR/4Q=="; 
    

//from nodejs's encoded variable
    $data = "jh9RSS+UpnsHXeQMES5Y2MS2WA0hoHCOHVI/l4LIj0u9AVa/WGPpGiD18rRZ3i2oP+mmVGXmhVW1VFjplsRGE9rxR+fnoI24kOzjMBIF3fOG4OrsZNLBDZ3K1y14mcssG3JVMO4mvFP5UaJMVKmQVwT8WgqeUkaADz4ayYZ+fporSYxDOT+HHHNJJhM+vMqh66MDC9yHPeAhYtoq+FvdMP1cTGoKHStUznxnmmQiDRnz4jvrvo+/EVA73sCeZWv+duu0kOGPMP23LfbKa3JAiNdtqC1LI1vz3GIwuRgnOKz1cRh5mypdR3VrM51gIvapbTHKjvtrmRZUUsAcFhIdQg=="; 

     //verify signature
     $result = openssl_verify($data, $signature, $pem_public_key, "sha256WithRSAEncryption");
     var_dump($result);
     ?>
I kinda figured it out on how to verify the signature.

    // Generating Signature In Node js
        const crypto = require("crypto");
        const fs = require("fs");
        
        const privateKey = fs.readFileSync("./keys/private.pem");
        
        let obj = {
          name: "alex",
          age: 27,
          time: Date.now(),
        };
        
        let data = btoa(JSON.stringify(obj));
        
        const sign = crypto.createSign("SHA256");
        sign.update(data);
        sign.end();
        const signature = sign.sign(privateKey, "base64");
        console.log(`Signature: ${signature}`);
        console.log(`data: ${data}`);


Whereas to verify signature in PHP
    
    

    <?php
        //get public key
        $cert = file_get_contents("./keys/public.pem");
        //data in base 64 format from Node js
        $data = "eyJuYW1lIjoiYWxleCIsImFnZSI6MjcsInRpbWUiOjE2NzI4ODA3ODY1OTZ9";
        //Signature from Node js
        $signature = "UwKM3w1O1bE80XThZJOCHQpdrrVf00lPlMSi4buS0fuDTxtOjB6LJGGBIzW5FU4YZOGdlqpwKkkqXrYLBCvSZYeDqJgT8D2JL9jpCzUfBACS/PTKhMpAVmU0Eco/PENVuuEV/yhx0+croUXJ/Mzooao4TB6oTQpR+6NNvAab9ECCBDyEeCn59G4cNnn0DFaBsTmFfIrX0DnnGn99UOSO0iCmFzdjDXnJuHrvsxd/ACIUpCqpwycorn6o+yXV7ChQcMuClS+y4kiF+9chhA3/OSHyoaF3uaCTfFXNLTycOjtvkPRTbHQ/FozL3enIrM2NHweJ58nondtKPZ5C7xPz4g==";
        //read public key
        $pubkeyid = openssl_pkey_get_public($cert);
        $ok = openssl_verify($data, base64_decode($signature), $pubkeyid,OPENSSL_ALGO_SHA256);
        
        if ($ok == 1) {
            # code...
            // decrypt data
            $decrypt =  base64_decode($data);   
            $object  = json_decode($decrypt);
            echo $object->name;
        }
        ?>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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