使用 NodeJS 的 RSA PKCS#1 加密
RSA PKCS#1 encryption with NodeJS
我想用 public 密钥和 RSA PKCS#1 模式加密一些数据。我已经使用 phpseclib
库在 PHP 上完成了这项工作,并且没有任何问题。
这是我的 PHP 代码:
<?php
include(__DIR__ . DIRECTORY_SEPARATOR . 'phpseclib/Crypt/RSA.php');
$apiKey = 'xxxxxxxxxxxxxxxxxxxx';
$publicKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx';
// request values in JSON format
$Parameters = array(
"name" => "Example Name",
"mobile" => "99999999999",
"remark" => "Product ",
"email" => "example@example.com",
"language" => "en",
"fields" => array (
"udf1" => "",
"udf2" => "",
"udf3" => "",
),
);
// Create rsa object
$rsa = new Crypt_RSA();
// Load public key
$rsa->loadKey($publicKey);
// Set the mode to PKCS#1
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
//Start the loop through the PHP array to encrypt the value
$returnValue = [];
if($Parameters){
foreach($Parameters as $x => $x_value){
if($x == "fields"){
$_Fields = [];
foreach($x_value as $y => $y_value){
$ciphertext = $rsa->encrypt($y_value);
// Convert it into Base64
$y_value_encrypted = base64_encode($ciphertext);
// insert the line array into the overall array
$_Fields[$y] = $y_value_encrypted;
}
$returnValue[$x] = $_Fields;
}else{
$ciphertext = $rsa->encrypt($x_value);
// Convert it into Base64
$x_value_encrypted = base64_encode($ciphertext);
// insert the line array into the overall array
$returnValue[$x] = $x_value_encrypted;
}
}
print $returnValue;
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.example.com/v1',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $returnValue,
CURLOPT_HTTPHEADER => array(
"authorization: Bearer $apiKey",
"content-type: application/json"
),
));
$result = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
print $result;
}
?>
我想在 NodeJS 上使用相同的方法,但由于 Parameters
数据加密错误,我从 API 收到错误。
这是我的 NodeJs 代码:
var crypto = require('crypto');
var request = require('request');
const apiKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; //User API KEY
const publicKey = `-----BEGIN PUBLIC KEY-----\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n-----END PUBLIC KEY-----`; //User public Key
//Set data to encrypt
const Parameters = {
'name': 'example name',
'mobile': '9999999999',
'remark': 'Product ',
'email': 'example@example.com',
'language': 'en',
'fields': {
'udf1': '',
'udf2': '',
'udf3': '',
},
};
//Start encrypting "Parameters" values
function encrypt(requestData) {
var dataToEncrypt = requestData;
var returnValue = {};
if (dataToEncrypt) {
for (var i in dataToEncrypt) {
//Encrypt 'fields' values
if (i == 'fields') {
var fields_array = {};
var fields = dataToEncrypt[i];
for (var y in fields) {
var yVlaue = fields[y];
var result;
result += crypto.publicEncrypt({key:publicKey, padding:crypto.constants.RSA_PKCS1_PADDING}, Buffer.from(yVlaue, 'utf8') ).toString('base64');
fields_array[y] = result;
}
returnValue[i] = fields_array;
} else {
//Encrypt other values
var result;
result += crypto.publicEncrypt({key:publicKey, padding:crypto.constants.RSA_PKCS1_PADDING}, Buffer.from(dataToEncrypt[i], 'utf8') ).toString('base64');
returnValue[i] = result;
}
}
}
Send(returnValue);
return returnValue;
}
function Send(encryptedData) {
var options = {
'method': 'POST',
'url': 'https://api.example.com/v1',
'headers': {
'Authorization': 'Bearer '+ apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify(encryptedData)
};
request(options, function (error, response) {
if (!error && response.statusCode == 200) {
console.log("\nResult:\n"+response.body);
} else {
console.log(error.message);
}
});
}
encrypt(Parameters);
像我在 PHP 上所做的那样,使用 public 密钥加密字符串并在 NodeJs 上使用 RSA PKCS#1 模式的正确方法是什么?
请注意,加密在 NodeJs 上有效,但加密方式存在问题。
我建议如下更改 Node.js 中的 encrypt 函数,我相信这会在 PHP 中正确解密。
function encrypt(requestData) {
var dataToEncrypt = requestData;
var returnValue = {};
if (dataToEncrypt) {
for (var i in dataToEncrypt) {
//Encrypt 'fields' values
if (i == 'fields') {
var fields_array = {};
var fields = dataToEncrypt[i];
for (var y in fields) {
fields_array[y] = crypto.publicEncrypt({key:publicKey, padding: crypto.constants.RSA_PKCS1_PADDING}, Buffer.from(fields[y], 'utf8') ).toString('base64');
}
returnValue[i] = fields_array;
} else {
//Encrypt other values
returnValue[i] = crypto.publicEncrypt({key:publicKey, padding: crypto.constants.RSA_PKCS1_PADDING}, Buffer.from(dataToEncrypt[i], 'utf8') ).toString('base64');
}
}
}
Send(returnValue);
return returnValue;
}
输出如下所示:
{
"name": "fdz8lUYD0hsmRGz5nqgTvQVZ82rNZylFCQ2It24HHbL1JdKrbFAia9pzLu45AZ0uf45oUo6H8qzVKO/HmJBnWSMI3CYf1HSPcZC4EmtaSE2SIWf7Z29j5lt4vDIwGKDiefMz2IuKcQhnWy3e3/hDi3uhUaKPDczLZ0ZgBAzf9iI=",
"mobile": "oBYToRCFftSppUNulagXexPmMKag3tXFEQYV2rRq6VobptxkdZB3Thlhrhait+eVP/5lZzkekGgup5o0kTIAPkJdXvr1ttu4dEJNR6oa6TXBZ4YFMx0ndhLS2HJaYbLMQ5JjK7P4iKW6A6wKuEJlTaUjPL1tHXxMwAG5HjdO5zg=",
"remark": "pXCA406AVprrvcX33zYlrS8jEZ4wsQDc6RJux1mRBb4tj5tp09JgtoLF2rhJ7cjHLEiWpLlHSSBcC5gkOy2eK8prfshQTgJuGvnEqKMMKGwMhKUJebzP+yio4n6SlHqVasU2ejZksDEY7sSj8BIum9JiL8i9ylQ4chBuZNLXGgc=",
"email": "0g9zm4WlydNfLU0D0V5bOvxS9JiaQ8a/y4qXAlMealmxZegC973g2FttvolgPDUfxU7HfV10bzXbwgfiXJZXodGMrwYiAWDvhQz424I1SrZznhZEE3djHkz6zr69KBR6HV91Yv43AMyAYyHGHI4YIwzs1Pa8fInBnnTUreVvBo8=",
"language": "yrSJsmCFMi8py6e8iMXiIjn1r/VAiT858ss4GkPPLFOoxtJopC0XLudG9mDh0MQp6bZRIQifiJwsHi07jpSHHOZTCeiO2R0qCF3VI/FCV3YsyUPHSX3ZdKHYqkzIlwhocDKOPt7ZlAlNhW4U8UbBTAq7YsiyPBtkYA/ikxpgsOE=",
"fields": {
"udf1": "SdrCwXYnj6zIW51VzQD8TRXScE7lyrr+tn6eglBInoH+yAZE/IRx0R9nNihCUCbvoIL1s6rT5Irl4Y3KB7CGp6b0wIA3itryKhkaVLYUJpqjXen4lqVLPsdsUpAeboJEgcO0aUbhq2ybawAwr5T1IADUyI/5o937zBv2cJkR7dU=",
"udf2": "Q0FpyOYmOPUju1Xopr2DXTdRgUJKJ4JlmoxwhWoM3ZEYbIkC76UqT7jAyCtJ5yOTpuh9dyX8VMdI0mx8ziT3ytwrjusDcOKPN8D8SNLxszYAabZVPankcB0WlB+u5GN4owyead1NpDzmWvkyHf+iEf7OFHY4FkrEq3h39Vu50TE=",
"udf3": "fxs3phQu1DFPZbke13ka7veX2DlMD7DcjB98f31G2UqjJW7RTYzBQ8ddNdYWyuRPsG5N9zTGBLvm4+9om2TinAJd+NXJDOjhOf0pihifQJ/hypOjovWCgt5nlaptvd2Gi3vU9ny5LQ0r3CIwU17iTH2w9QCos/Ncta7Ev2VQ83E="
}
}
我还建议在 PHP 和 Node.js 中创建简单的测试脚本来测试字符串的简单加密和解密。
这很好地隔离了问题。我建议确保 Node.js 加密的输出可以在 PHP 中解密,反之亦然。
simple_encrypt.php
set_include_path(get_include_path() . PATH_SEPARATOR . 'phpseclib');
include(__DIR__ . '/phpseclib/Crypt/RSA.php');
$publicKey = '-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDbVuHaQIctLFZK1oIn2+P2j8z4
1S5kdQSo2AWYRMeo2yd+00ozdYjDpJ9eNpZyk1F7Dx9b+SmU39R0Tz89/IiTL78T
ZTOQ1FFFvktJhKT413QiegBAx09DhX3I+NQwvZWdU9SkptAGz9PD6zIeJTlh5HHA
fC/P+oLUhpQjkd+JBQIDAQAB
-----END PUBLIC KEY-----';
$privateKey = '-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDbVuHaQIctLFZK1oIn2+P2j8z41S5kdQSo2AWYRMeo2yd+00oz
dYjDpJ9eNpZyk1F7Dx9b+SmU39R0Tz89/IiTL78TZTOQ1FFFvktJhKT413QiegBA
x09DhX3I+NQwvZWdU9SkptAGz9PD6zIeJTlh5HHAfC/P+oLUhpQjkd+JBQIDAQAB
AoGAFv4WkuBsyyl4qkOuRSthzDjqzbLbOCCkKmbqvzmGjIbcrwjLIHXTrl6VbjTe
tIgI5JODQArwdvC3vrGH+aF9V27XW4Vl4WllPlBIzvaq1JufPOGupzNmssScFWV5
IL+P1Sx5F22rO+w+lIUdVFgbInITu4Bs2rvKsjAyBmvq7MkCQQD0kQvDWuPWkHSj
xzUjAXl+rT8ZOmANC1x35bLAEUHL2EWCejV9jO48TnwkqOQabT/rEWjrv4g7VHC0
ErNg1bAjAkEA5ZfrSKjyxoEbbK1lQz1GBMpyXGSpbTVJ+eMinBYY4JOnswLLUpmP
/OIJtLrOq38zSzNE2iHoxoGQDt1OlQDgtwJASPG2G3dRe16sm2jALYe0EBdmOYUS
vvFDjDNDhEvhXwZLfSYsLB1LtUsHdfu1xTgOl3Mi4yXGYUPHNb5aKCi0FwJAQGaH
sd7qEnI+jhJpOB4k2M0snOwDdkWfVX+3wo6UNdJVFOpwu9+lOurwjAhmVkaczbg4
1PL0B1JqZTEAjN0tKwJBAMRx0oqN5JNqc3iCrjDxJ9e94t7poVV7if0TfLBVzceR
5mgjPSOMjjkpzVG1P6+37V4whe26u3BhX04PD8Nzl3c=
-----END RSA PRIVATE KEY-----';
$rsa = new Crypt_RSA();
$rsa->loadKey($publicKey);
$plainText = 'abc';
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$cipherText = $rsa->encrypt($plainText);
$rsa->loadKey($privateKey);
echo "\nEncrypted (base64): " . base64_encode($cipherText);
echo "\nDecrypted: " . $rsa->decrypt($cipherText);
simple_encrypt.js
const crypto = require('crypto');
const publicKey = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDbVuHaQIctLFZK1oIn2+P2j8z4
1S5kdQSo2AWYRMeo2yd+00ozdYjDpJ9eNpZyk1F7Dx9b+SmU39R0Tz89/IiTL78T
ZTOQ1FFFvktJhKT413QiegBAx09DhX3I+NQwvZWdU9SkptAGz9PD6zIeJTlh5HHA
fC/P+oLUhpQjkd+JBQIDAQAB
-----END PUBLIC KEY-----`;
const privateKey = `-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDbVuHaQIctLFZK1oIn2+P2j8z41S5kdQSo2AWYRMeo2yd+00oz
dYjDpJ9eNpZyk1F7Dx9b+SmU39R0Tz89/IiTL78TZTOQ1FFFvktJhKT413QiegBA
x09DhX3I+NQwvZWdU9SkptAGz9PD6zIeJTlh5HHAfC/P+oLUhpQjkd+JBQIDAQAB
AoGAFv4WkuBsyyl4qkOuRSthzDjqzbLbOCCkKmbqvzmGjIbcrwjLIHXTrl6VbjTe
tIgI5JODQArwdvC3vrGH+aF9V27XW4Vl4WllPlBIzvaq1JufPOGupzNmssScFWV5
IL+P1Sx5F22rO+w+lIUdVFgbInITu4Bs2rvKsjAyBmvq7MkCQQD0kQvDWuPWkHSj
xzUjAXl+rT8ZOmANC1x35bLAEUHL2EWCejV9jO48TnwkqOQabT/rEWjrv4g7VHC0
ErNg1bAjAkEA5ZfrSKjyxoEbbK1lQz1GBMpyXGSpbTVJ+eMinBYY4JOnswLLUpmP
/OIJtLrOq38zSzNE2iHoxoGQDt1OlQDgtwJASPG2G3dRe16sm2jALYe0EBdmOYUS
vvFDjDNDhEvhXwZLfSYsLB1LtUsHdfu1xTgOl3Mi4yXGYUPHNb5aKCi0FwJAQGaH
sd7qEnI+jhJpOB4k2M0snOwDdkWfVX+3wo6UNdJVFOpwu9+lOurwjAhmVkaczbg4
1PL0B1JqZTEAjN0tKwJBAMRx0oqN5JNqc3iCrjDxJ9e94t7poVV7if0TfLBVzceR
5mgjPSOMjjkpzVG1P6+37V4whe26u3BhX04PD8Nzl3c=
-----END RSA PRIVATE KEY-----`;
const plainText = "abc";
function encryptWithPublicKey(plainText, publicKey) {
const buffer = Buffer.from(plainText);
return crypto.publicEncrypt( { key: publicKey, padding: crypto.constants.RSA_PKCS1_PADDING } , buffer);
}
function decryptWithPrivateKey(cipherTextBuffer, privateKey) {
const decrypted = crypto.privateDecrypt( { key: privateKey, padding: crypto.constants.RSA_PKCS1_PADDING} , cipherTextBuffer);
return decrypted.toString("utf8");
}
let cipherText = encryptWithPublicKey(plainText, publicKey);
let decrypted = decryptWithPrivateKey(cipherText, privateKey);
console.log("Encrypted (base64):", cipherText.toString("base64"));
console.log("Decrypted:", decrypted)
注意: 我们不会期望两个脚本的结果相同,因为输出是不确定的。
我想用 public 密钥和 RSA PKCS#1 模式加密一些数据。我已经使用 phpseclib
库在 PHP 上完成了这项工作,并且没有任何问题。
这是我的 PHP 代码:
<?php
include(__DIR__ . DIRECTORY_SEPARATOR . 'phpseclib/Crypt/RSA.php');
$apiKey = 'xxxxxxxxxxxxxxxxxxxx';
$publicKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx';
// request values in JSON format
$Parameters = array(
"name" => "Example Name",
"mobile" => "99999999999",
"remark" => "Product ",
"email" => "example@example.com",
"language" => "en",
"fields" => array (
"udf1" => "",
"udf2" => "",
"udf3" => "",
),
);
// Create rsa object
$rsa = new Crypt_RSA();
// Load public key
$rsa->loadKey($publicKey);
// Set the mode to PKCS#1
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
//Start the loop through the PHP array to encrypt the value
$returnValue = [];
if($Parameters){
foreach($Parameters as $x => $x_value){
if($x == "fields"){
$_Fields = [];
foreach($x_value as $y => $y_value){
$ciphertext = $rsa->encrypt($y_value);
// Convert it into Base64
$y_value_encrypted = base64_encode($ciphertext);
// insert the line array into the overall array
$_Fields[$y] = $y_value_encrypted;
}
$returnValue[$x] = $_Fields;
}else{
$ciphertext = $rsa->encrypt($x_value);
// Convert it into Base64
$x_value_encrypted = base64_encode($ciphertext);
// insert the line array into the overall array
$returnValue[$x] = $x_value_encrypted;
}
}
print $returnValue;
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.example.com/v1',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $returnValue,
CURLOPT_HTTPHEADER => array(
"authorization: Bearer $apiKey",
"content-type: application/json"
),
));
$result = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
print $result;
}
?>
我想在 NodeJS 上使用相同的方法,但由于 Parameters
数据加密错误,我从 API 收到错误。
这是我的 NodeJs 代码:
var crypto = require('crypto');
var request = require('request');
const apiKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; //User API KEY
const publicKey = `-----BEGIN PUBLIC KEY-----\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n-----END PUBLIC KEY-----`; //User public Key
//Set data to encrypt
const Parameters = {
'name': 'example name',
'mobile': '9999999999',
'remark': 'Product ',
'email': 'example@example.com',
'language': 'en',
'fields': {
'udf1': '',
'udf2': '',
'udf3': '',
},
};
//Start encrypting "Parameters" values
function encrypt(requestData) {
var dataToEncrypt = requestData;
var returnValue = {};
if (dataToEncrypt) {
for (var i in dataToEncrypt) {
//Encrypt 'fields' values
if (i == 'fields') {
var fields_array = {};
var fields = dataToEncrypt[i];
for (var y in fields) {
var yVlaue = fields[y];
var result;
result += crypto.publicEncrypt({key:publicKey, padding:crypto.constants.RSA_PKCS1_PADDING}, Buffer.from(yVlaue, 'utf8') ).toString('base64');
fields_array[y] = result;
}
returnValue[i] = fields_array;
} else {
//Encrypt other values
var result;
result += crypto.publicEncrypt({key:publicKey, padding:crypto.constants.RSA_PKCS1_PADDING}, Buffer.from(dataToEncrypt[i], 'utf8') ).toString('base64');
returnValue[i] = result;
}
}
}
Send(returnValue);
return returnValue;
}
function Send(encryptedData) {
var options = {
'method': 'POST',
'url': 'https://api.example.com/v1',
'headers': {
'Authorization': 'Bearer '+ apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify(encryptedData)
};
request(options, function (error, response) {
if (!error && response.statusCode == 200) {
console.log("\nResult:\n"+response.body);
} else {
console.log(error.message);
}
});
}
encrypt(Parameters);
像我在 PHP 上所做的那样,使用 public 密钥加密字符串并在 NodeJs 上使用 RSA PKCS#1 模式的正确方法是什么?
请注意,加密在 NodeJs 上有效,但加密方式存在问题。
我建议如下更改 Node.js 中的 encrypt 函数,我相信这会在 PHP 中正确解密。
function encrypt(requestData) {
var dataToEncrypt = requestData;
var returnValue = {};
if (dataToEncrypt) {
for (var i in dataToEncrypt) {
//Encrypt 'fields' values
if (i == 'fields') {
var fields_array = {};
var fields = dataToEncrypt[i];
for (var y in fields) {
fields_array[y] = crypto.publicEncrypt({key:publicKey, padding: crypto.constants.RSA_PKCS1_PADDING}, Buffer.from(fields[y], 'utf8') ).toString('base64');
}
returnValue[i] = fields_array;
} else {
//Encrypt other values
returnValue[i] = crypto.publicEncrypt({key:publicKey, padding: crypto.constants.RSA_PKCS1_PADDING}, Buffer.from(dataToEncrypt[i], 'utf8') ).toString('base64');
}
}
}
Send(returnValue);
return returnValue;
}
输出如下所示:
{
"name": "fdz8lUYD0hsmRGz5nqgTvQVZ82rNZylFCQ2It24HHbL1JdKrbFAia9pzLu45AZ0uf45oUo6H8qzVKO/HmJBnWSMI3CYf1HSPcZC4EmtaSE2SIWf7Z29j5lt4vDIwGKDiefMz2IuKcQhnWy3e3/hDi3uhUaKPDczLZ0ZgBAzf9iI=",
"mobile": "oBYToRCFftSppUNulagXexPmMKag3tXFEQYV2rRq6VobptxkdZB3Thlhrhait+eVP/5lZzkekGgup5o0kTIAPkJdXvr1ttu4dEJNR6oa6TXBZ4YFMx0ndhLS2HJaYbLMQ5JjK7P4iKW6A6wKuEJlTaUjPL1tHXxMwAG5HjdO5zg=",
"remark": "pXCA406AVprrvcX33zYlrS8jEZ4wsQDc6RJux1mRBb4tj5tp09JgtoLF2rhJ7cjHLEiWpLlHSSBcC5gkOy2eK8prfshQTgJuGvnEqKMMKGwMhKUJebzP+yio4n6SlHqVasU2ejZksDEY7sSj8BIum9JiL8i9ylQ4chBuZNLXGgc=",
"email": "0g9zm4WlydNfLU0D0V5bOvxS9JiaQ8a/y4qXAlMealmxZegC973g2FttvolgPDUfxU7HfV10bzXbwgfiXJZXodGMrwYiAWDvhQz424I1SrZznhZEE3djHkz6zr69KBR6HV91Yv43AMyAYyHGHI4YIwzs1Pa8fInBnnTUreVvBo8=",
"language": "yrSJsmCFMi8py6e8iMXiIjn1r/VAiT858ss4GkPPLFOoxtJopC0XLudG9mDh0MQp6bZRIQifiJwsHi07jpSHHOZTCeiO2R0qCF3VI/FCV3YsyUPHSX3ZdKHYqkzIlwhocDKOPt7ZlAlNhW4U8UbBTAq7YsiyPBtkYA/ikxpgsOE=",
"fields": {
"udf1": "SdrCwXYnj6zIW51VzQD8TRXScE7lyrr+tn6eglBInoH+yAZE/IRx0R9nNihCUCbvoIL1s6rT5Irl4Y3KB7CGp6b0wIA3itryKhkaVLYUJpqjXen4lqVLPsdsUpAeboJEgcO0aUbhq2ybawAwr5T1IADUyI/5o937zBv2cJkR7dU=",
"udf2": "Q0FpyOYmOPUju1Xopr2DXTdRgUJKJ4JlmoxwhWoM3ZEYbIkC76UqT7jAyCtJ5yOTpuh9dyX8VMdI0mx8ziT3ytwrjusDcOKPN8D8SNLxszYAabZVPankcB0WlB+u5GN4owyead1NpDzmWvkyHf+iEf7OFHY4FkrEq3h39Vu50TE=",
"udf3": "fxs3phQu1DFPZbke13ka7veX2DlMD7DcjB98f31G2UqjJW7RTYzBQ8ddNdYWyuRPsG5N9zTGBLvm4+9om2TinAJd+NXJDOjhOf0pihifQJ/hypOjovWCgt5nlaptvd2Gi3vU9ny5LQ0r3CIwU17iTH2w9QCos/Ncta7Ev2VQ83E="
}
}
我还建议在 PHP 和 Node.js 中创建简单的测试脚本来测试字符串的简单加密和解密。
这很好地隔离了问题。我建议确保 Node.js 加密的输出可以在 PHP 中解密,反之亦然。
simple_encrypt.php
set_include_path(get_include_path() . PATH_SEPARATOR . 'phpseclib');
include(__DIR__ . '/phpseclib/Crypt/RSA.php');
$publicKey = '-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDbVuHaQIctLFZK1oIn2+P2j8z4
1S5kdQSo2AWYRMeo2yd+00ozdYjDpJ9eNpZyk1F7Dx9b+SmU39R0Tz89/IiTL78T
ZTOQ1FFFvktJhKT413QiegBAx09DhX3I+NQwvZWdU9SkptAGz9PD6zIeJTlh5HHA
fC/P+oLUhpQjkd+JBQIDAQAB
-----END PUBLIC KEY-----';
$privateKey = '-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDbVuHaQIctLFZK1oIn2+P2j8z41S5kdQSo2AWYRMeo2yd+00oz
dYjDpJ9eNpZyk1F7Dx9b+SmU39R0Tz89/IiTL78TZTOQ1FFFvktJhKT413QiegBA
x09DhX3I+NQwvZWdU9SkptAGz9PD6zIeJTlh5HHAfC/P+oLUhpQjkd+JBQIDAQAB
AoGAFv4WkuBsyyl4qkOuRSthzDjqzbLbOCCkKmbqvzmGjIbcrwjLIHXTrl6VbjTe
tIgI5JODQArwdvC3vrGH+aF9V27XW4Vl4WllPlBIzvaq1JufPOGupzNmssScFWV5
IL+P1Sx5F22rO+w+lIUdVFgbInITu4Bs2rvKsjAyBmvq7MkCQQD0kQvDWuPWkHSj
xzUjAXl+rT8ZOmANC1x35bLAEUHL2EWCejV9jO48TnwkqOQabT/rEWjrv4g7VHC0
ErNg1bAjAkEA5ZfrSKjyxoEbbK1lQz1GBMpyXGSpbTVJ+eMinBYY4JOnswLLUpmP
/OIJtLrOq38zSzNE2iHoxoGQDt1OlQDgtwJASPG2G3dRe16sm2jALYe0EBdmOYUS
vvFDjDNDhEvhXwZLfSYsLB1LtUsHdfu1xTgOl3Mi4yXGYUPHNb5aKCi0FwJAQGaH
sd7qEnI+jhJpOB4k2M0snOwDdkWfVX+3wo6UNdJVFOpwu9+lOurwjAhmVkaczbg4
1PL0B1JqZTEAjN0tKwJBAMRx0oqN5JNqc3iCrjDxJ9e94t7poVV7if0TfLBVzceR
5mgjPSOMjjkpzVG1P6+37V4whe26u3BhX04PD8Nzl3c=
-----END RSA PRIVATE KEY-----';
$rsa = new Crypt_RSA();
$rsa->loadKey($publicKey);
$plainText = 'abc';
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$cipherText = $rsa->encrypt($plainText);
$rsa->loadKey($privateKey);
echo "\nEncrypted (base64): " . base64_encode($cipherText);
echo "\nDecrypted: " . $rsa->decrypt($cipherText);
simple_encrypt.js
const crypto = require('crypto');
const publicKey = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDbVuHaQIctLFZK1oIn2+P2j8z4
1S5kdQSo2AWYRMeo2yd+00ozdYjDpJ9eNpZyk1F7Dx9b+SmU39R0Tz89/IiTL78T
ZTOQ1FFFvktJhKT413QiegBAx09DhX3I+NQwvZWdU9SkptAGz9PD6zIeJTlh5HHA
fC/P+oLUhpQjkd+JBQIDAQAB
-----END PUBLIC KEY-----`;
const privateKey = `-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDbVuHaQIctLFZK1oIn2+P2j8z41S5kdQSo2AWYRMeo2yd+00oz
dYjDpJ9eNpZyk1F7Dx9b+SmU39R0Tz89/IiTL78TZTOQ1FFFvktJhKT413QiegBA
x09DhX3I+NQwvZWdU9SkptAGz9PD6zIeJTlh5HHAfC/P+oLUhpQjkd+JBQIDAQAB
AoGAFv4WkuBsyyl4qkOuRSthzDjqzbLbOCCkKmbqvzmGjIbcrwjLIHXTrl6VbjTe
tIgI5JODQArwdvC3vrGH+aF9V27XW4Vl4WllPlBIzvaq1JufPOGupzNmssScFWV5
IL+P1Sx5F22rO+w+lIUdVFgbInITu4Bs2rvKsjAyBmvq7MkCQQD0kQvDWuPWkHSj
xzUjAXl+rT8ZOmANC1x35bLAEUHL2EWCejV9jO48TnwkqOQabT/rEWjrv4g7VHC0
ErNg1bAjAkEA5ZfrSKjyxoEbbK1lQz1GBMpyXGSpbTVJ+eMinBYY4JOnswLLUpmP
/OIJtLrOq38zSzNE2iHoxoGQDt1OlQDgtwJASPG2G3dRe16sm2jALYe0EBdmOYUS
vvFDjDNDhEvhXwZLfSYsLB1LtUsHdfu1xTgOl3Mi4yXGYUPHNb5aKCi0FwJAQGaH
sd7qEnI+jhJpOB4k2M0snOwDdkWfVX+3wo6UNdJVFOpwu9+lOurwjAhmVkaczbg4
1PL0B1JqZTEAjN0tKwJBAMRx0oqN5JNqc3iCrjDxJ9e94t7poVV7if0TfLBVzceR
5mgjPSOMjjkpzVG1P6+37V4whe26u3BhX04PD8Nzl3c=
-----END RSA PRIVATE KEY-----`;
const plainText = "abc";
function encryptWithPublicKey(plainText, publicKey) {
const buffer = Buffer.from(plainText);
return crypto.publicEncrypt( { key: publicKey, padding: crypto.constants.RSA_PKCS1_PADDING } , buffer);
}
function decryptWithPrivateKey(cipherTextBuffer, privateKey) {
const decrypted = crypto.privateDecrypt( { key: privateKey, padding: crypto.constants.RSA_PKCS1_PADDING} , cipherTextBuffer);
return decrypted.toString("utf8");
}
let cipherText = encryptWithPublicKey(plainText, publicKey);
let decrypted = decryptWithPrivateKey(cipherText, privateKey);
console.log("Encrypted (base64):", cipherText.toString("base64"));
console.log("Decrypted:", decrypted)
注意: 我们不会期望两个脚本的结果相同,因为输出是不确定的。