Signing signature in Node.js and verifying it on PHP

huangapple go评论91阅读模式
英文:

Signing signature in Node JS and verifying it on PHP

问题

I have translated the code sections you provided. Here they are:

PHP部分:

<?php
    // 创建新的私钥和公钥

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

    /**
     * 前端流程
     */
    $obj = (object) [
        'name' => 'alex',
        'age' => 27,
        'time' => time() // 添加此行将每次创建新的签名
    ];

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

    // 获取私钥
    $pem_private_key = file_get_contents('private_key.pem');
    $private_key = openssl_pkey_get_private($pem_private_key);

    // 加密数据
    $isvalid = openssl_private_encrypt ($data, $crypted , $pem_private_key, OPENSSL_PKCS1_PADDING);	

    // 创建签名
    openssl_sign($data, $signature, $private_key, OPENSSL_ALGO_SHA256);

    /**
     * 前端流程结束
     * ================================================
     */

    /**
     * 后端流程
     */
    // 获取公钥
    $pem_public_key = openssl_pkey_get_details($private_key)['key'];

    // 验证签名
    $result = openssl_verify($data, $signature, $pem_public_key, "sha256WithRSAEncryption");
    if ($result == 1) {
        echo "\n DATA: " . $data;
        echo "\n SIGNATURE: " . base64_encode($signature);
        // 如果签名有效,解密数据
        openssl_public_decrypt ($crypted, $decrypted , $pem_public_key, OPENSSL_PKCS1_PADDING);	
        echo " Data decryption : " . base64_decode($decrypted);

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

    /**
     * 后端流程结束
     */
?>

Node.js部分:

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

// 创建加密字符串的函数
function encryptString(data, privateKey) {
  // 使用 privateEncrypt() 方法进行加密
  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));
// 获取私钥
let privateKey = fs.readFileSync("./private_key.pem");
// 加密数据
let encoded = encryptString(data, privateKey);
signer.update(encoded);
signature_b64 = signer.sign(privateKey, "base64");
console.log(signature_b64, obj);
console.log(encoded);

验证签名的PHP部分:

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

// 获取公钥
$pem_public_key = openssl_pkey_get_details($private_key)['key'];

// 来自Node.js的签名变量
$signature = "MAgFdpMSHYRKIQjbfeqlLwHgostJN0YrkeBrNwapk6qYsNaSt7M+cA2y+rzQNOw35D3nxrDP5ICx8mVErMwu5uptkhFyaxay+DbBufHvfQvnXhq/bAZR9I7PAfS23cnNBnEmchATY/exVCk2tB82GattHbXIJxEcC2Z8OwI4+1hdAg31PbC7fjjeXxKh9ZGYtZVfpjhFzH2ybcsPqLnYJRoWTxg6CfO+/Mp6f+SI5KKqB5tYxqoHtdcL4Tw2xK3NQPmqoUoKAynO3hzp/jMyI0QnSnnpgJJOHcJB9llrvBolShvgqL8It0uVCNFD0Qj8Vaix0LRLOSMxftirQTR/4Q=="; 

// 来自Node.js的编码变量
$data = "jh9RSS+UpnsHXeQMES5Y2MS2WA0hoHCOHVI/l4LIj0u9AVa/WGPpGiD18rRZ3i2oP+mmVGXmhVW1VFjplsRGE9rxR+fnoI24kOzjMBIF3fOG4OrsZNLBDZ3K1y14mcssG3JVMO4mvFP5UaJMVKmQVwT8WgqeUkaADz4ayYZ+fporSYxDOT+HHHNJJhM+vMqh66MDC9yHPeAhYtoq+FvdMP1cTGoKHStUznxnmmQiDRnz4jvrvo+/EVA73sCeZWv+duu0kOGPMP23LfbKa3JAiNdtqC1LI1vz3GIwuRgnOKz1cRh5mypdR3VrM51gIvapbTHKjvtrmRZUUsAcFhIdQg=="; 

// 验证签名
$result = openssl_verify($data, $signature, $pem_public_key, "sha256WithRSAEncryption");
var_dump($result);
?>
英文:

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 ?

&lt;?php
//create new private and public key
$new_key_pair = openssl_pkey_new(array(
&quot;private_key_bits&quot; =&gt; 2048,
&quot;private_key_type&quot; =&gt; OPENSSL_KEYTYPE_RSA,
));
openssl_pkey_export($new_key_pair, $private_key_pem);
/**
* FrontEnd Flow
*/
$obj = (object) [
&#39;name&#39; =&gt; &#39;alex&#39;,
&#39;age&#39; =&gt; 27,
&#39;time&#39; =&gt; time() //adding this will create new signature every time
];
$data = base64_encode(json_encode($obj));
//Get Private Key
$pem_private_key = file_get_contents(&#39;private_key.pem&#39;);
$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)[&#39;key&#39;];
//verify signature
$result = openssl_verify($data, $signature, $pem_public_key, &quot;sha256WithRSAEncryption&quot;);
if ($result == 1) {
echo    &quot;\n DATA: &quot; . $data;
echo    &quot;\n SIGNATURE: &quot; . base64_encode($signature);
//if signature is valid, decrypt data
openssl_public_decrypt ($crypted, $decrypted , $pem_public_key,OPENSSL_PKCS1_PADDING);	
echo &quot;\n  Data decryption : &quot;. base64_decode($decrypted);
} elseif ($result == 0) {
echo &quot;signature is invalid for given data.&quot;;
} else {
echo &quot;\n error: &quot;.openssl_error_string();
}
/**
* End of BackEnd Flow
*/
?&gt;

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(&quot;fs&quot;);
const crypto = require(&quot;crypto&quot;);
const signer = crypto.createSign(&quot;RSA-SHA256&quot;);
// Creating a function to encrypt string
function encryptString(data, privateKey) {
// privateEncrypt() method with its parameters
const encrypted = crypto.privateEncrypt(privateKey, data);
return encrypted.toString(&quot;base64&quot;);
}
let obj = {
name: &quot;alex&quot;,
age: 27,
time: Date.now(),
};
let data = btoa(JSON.stringify(obj));
//Get Private Key
let privateKey = fs.readFileSync(&quot;./private_key.pem&quot;);
//Encrypt data
let encoded = encryptString(data, privateKey);
signer.update(encoded);
signature_b64 = signer.sign(privateKey, &quot;base64&quot;);
console.log(signature_b64, obj);
console.log(encoded);

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

&lt;?php
$pem_private_key = file_get_contents(&#39;private_key.pem&#39;);
$private_key = openssl_pkey_get_private($pem_private_key);
//Get Public Key
$pem_public_key = openssl_pkey_get_details($private_key)[&#39;key&#39;];
//from nodejs&#39;s signature variable
$signature = 
&quot;MAgFdpMSHYRKIQjbfeqlLwHgostJN0YrkeBrNwapk6qYsNaSt7M+cA2y+rzQNOw35D3nxrDP5ICx8mVErMwu5uptkhFyaxay+DbBufHvfQvnXhq/bAZR9I7PAfS23cnNBnEmchATY/exVCk2tB82GattHbXIJxEcC2Z8OwI4+1hdAg31PbC7fjjeXxKh9ZGYtZVfpjhFzH2ybcsPqLnYJRoWTxg6CfO+/Mp6f+SI5KKqB5tYxqoHtdcL4Tw2xK3NQPmqoUoKAynO3hzp/jMyI0QnSnnpgJJOHcJB9llrvBolShvgqL8It0uVCNFD0Qj8Vaix0LRLOSMxftirQTR/4Q==&quot;; 
//from nodejs&#39;s encoded variable
$data = &quot;jh9RSS+UpnsHXeQMES5Y2MS2WA0hoHCOHVI/l4LIj0u9AVa/WGPpGiD18rRZ3i2oP+mmVGXmhVW1VFjplsRGE9rxR+fnoI24kOzjMBIF3fOG4OrsZNLBDZ3K1y14mcssG3JVMO4mvFP5UaJMVKmQVwT8WgqeUkaADz4ayYZ+fporSYxDOT+HHHNJJhM+vMqh66MDC9yHPeAhYtoq+FvdMP1cTGoKHStUznxnmmQiDRnz4jvrvo+/EVA73sCeZWv+duu0kOGPMP23LfbKa3JAiNdtqC1LI1vz3GIwuRgnOKz1cRh5mypdR3VrM51gIvapbTHKjvtrmRZUUsAcFhIdQg==&quot;; 
//verify signature
$result = openssl_verify($data, $signature, $pem_public_key, &quot;sha256WithRSAEncryption&quot;);
var_dump($result);
?&gt;

答案1

得分: 1

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

//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) {
    // decrypt data
    $decrypt =  base64_decode($data);	
    $object  = json_decode($decrypt);
    echo $object->name;
}
?>
英文:
I kinda figured it out on how to verify the signature.
// Generating Signature In Node js
const crypto = require(&quot;crypto&quot;);
const fs = require(&quot;fs&quot;);
const privateKey = fs.readFileSync(&quot;./keys/private.pem&quot;);
let obj = {
name: &quot;alex&quot;,
age: 27,
time: Date.now(),
};
let data = btoa(JSON.stringify(obj));
const sign = crypto.createSign(&quot;SHA256&quot;);
sign.update(data);
sign.end();
const signature = sign.sign(privateKey, &quot;base64&quot;);
console.log(`Signature: ${signature}`);
console.log(`data: ${data}`);
Whereas to verify signature in PHP
&lt;?php
//get public key
$cert = file_get_contents(&quot;./keys/public.pem&quot;);
//data in base 64 format from Node js
$data = &quot;eyJuYW1lIjoiYWxleCIsImFnZSI6MjcsInRpbWUiOjE2NzI4ODA3ODY1OTZ9&quot;;
//Signature from Node js
$signature = &quot;UwKM3w1O1bE80XThZJOCHQpdrrVf00lPlMSi4buS0fuDTxtOjB6LJGGBIzW5FU4YZOGdlqpwKkkqXrYLBCvSZYeDqJgT8D2JL9jpCzUfBACS/PTKhMpAVmU0Eco/PENVuuEV/yhx0+croUXJ/Mzooao4TB6oTQpR+6NNvAab9ECCBDyEeCn59G4cNnn0DFaBsTmFfIrX0DnnGn99UOSO0iCmFzdjDXnJuHrvsxd/ACIUpCqpwycorn6o+yXV7ChQcMuClS+y4kiF+9chhA3/OSHyoaF3uaCTfFXNLTycOjtvkPRTbHQ/FozL3enIrM2NHweJ58nondtKPZ5C7xPz4g==&quot;;
//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-&gt;name;
}
?&gt;

huangapple
  • 本文由 发表于 2023年1月4日 17:13:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75003236.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定