[英]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.