英文:
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 ?
<?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);
?>
答案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("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;
}
?>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论