簡體   English   中英

在 Node JS 中簽名並在 PHP 上驗證

[英]Signing signature in Node JS and verifying it on PHP

我有這個工作示例,據此我在 PHP 上創建了私鑰和公鑰。當我使用純 php 時,下面的代碼工作正常並且簽名有效。但是,我的想法是使用 Javscript 生成簽名,然后使用驗證簽名PHP,這可能嗎?

<?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
     */
?>

但是我如何在 Node JS 中簽名,特別是上面代碼的前端流程。 這是我嘗試過的方法,但它不起作用,它一直返回無效簽名。

//節點.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);

我驗證 Node.js 生成的簽名的驗證流程是這樣的

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM