Nodejs RSA 解密问题

发布于 1周前 作者 caililin 来自 nodejs/Nestjs

Nodejs RSA 解密问题

最近接酷派 SDK ,在做支付验证的时候,对方要求用 privatekey 和 modkey 把数据做一个解密,然后再根据解密出来的字符串和相应的字符串验证是否相等。 php 代码如下:

CoolpayDecryptDemo.php 文件:

<?php

require ‘CoolpayDecrypt.php’;

//以下三个数据为演示数据 trans_data 和 sign 为报文中获取的字段, key 为从商户自服务获取的应用密钥。 $trans_data = ‘{“exorderno”:“10004200000001100042”,“transid”:“02113013118562300203”,“waresid”:1,“appid”:“20004600000001200046”,“feetype”:0,“money”:3000,“count”:1,“result”:0,“transtype”:0,“transtime”:“2013-01-31 18:57:27”,“cpprivate”:“123456”}’; $key = ‘MjhERTEwQkFBRDJBRTRERDhDM0FBNkZBMzNFQ0RFMTFCQTBCQzE3QU1UUTRPRFV6TkRjeU16UTVNRFUyTnpnek9ETXJNVE15T1RRME9EZzROVGsyTVRreU1ETXdNRE0zTnpjd01EazNNekV5T1RJek1qUXlNemN4’; $sign = ‘28adee792782d2f723e17ee1ef877e7 166bc3119507f43b06977786376c0434 633cabdb9ee80044bc8108d2e9b3c86e’;

$tools = new CoolpayDecrypt(); $result = $tools->validsign($trans_data,$sign,$key); if($result == 0) //验签名成功,添加处理业务逻辑的代码; echo ‘SUCCESS’; else echo ‘FAILED’;

CoolpayDecrypt.php 文件:

<?php

require ‘RSAUtil.php’;

class CoolpayDecrypt{ public function validsign($trans_data,$sign,$key){ $rsa = new RSAUtil();

	//解析 key 需要从商户自服务提供的 key 中解析出我们的真正的 key. 商户自服务提供的 key = mybase64(private_key+mod_key);
	$key1 =  base64_decode($key);
	$key2 = substr($key1,40,strlen($key1)-40);
	$key3 = base64_decode($key2);
	//php 5.3 环境用下面这个
	//list($private_key, $mod_key) = explode("+", $key3);
	list($private_key, $mod_key) = split("\\+", $key3);
	//使用解析出来的 key ,解密包体中传过来的 sign 签名值
	$sign_md5 = $rsa-&gt;decrypt($sign, $private_key, $mod_key);
	$msg_md5 = md5($trans_data);
	//echo "key3 : {$key3} &lt;br/&gt;\n";
	//echo "private_key : {$private_key} &lt;br/&gt;\n";
	//echo "mod_key : {$mod_key} &lt;br/&gt;\n";
	//echo "sign_md5 : {$sign_md5} &lt;br/&gt;\n";
	//echo "msg_md5 : {$msg_md5} &lt;br/&gt;\n";
	
	return strcmp($msg_md5,$sign_md5);
}

} ?>

RSAUtil.php 文件:

<?php
class RSAUtil{
		/**
	 * 解密方法
	 * [@param](/user/param) $string 需要解密的密文字符
	 * [@param](/user/param) $d
	 * [@param](/user/param) $n
	 * [@return](/user/return) String
	 */
	public function decrypt($string, $d, $n){
		//解决某些机器验签时好时坏的 bug
		//BCMath 里面的函数 有的机器 php.ini 设置不起作用
		//要在 RSAUtil 的方法 decrypt 加 bcscale(0);这样一行代码才行
		//要不有的机器计算的时候会有小数点 就会失败
		bcscale(0);
	$bln = $this-&gt;keylen * 2 - 1;
	$bitlen = ceil($bln / 8);
	$arr = explode(' ', $string);
	$data = '';
	foreach($arr as $v){
		$v = Math::hex2dec($v);
		$v = bcpowmod($v, $d, $n);
		$data .= Math::int2byte($v);
	}
	return trim($data);
}

} ?>

网上找了很多资料,都是现成的库,参数都是一个密文一个 key 。有找到了一个 RSA.js 的前端库,好像符合要求,但只有加密的,解密的资料没找到


5 回复

谢谢,但是它这个 privatekey 和 modkey 都是很短的一段数字,完全不是 key 的格式啊,你给你代码不行呢、

酷派的好像接过啊,貌似 node 可以调用 php 代码,你可以试下

你接过?用的什么语言? 我看看 node 调 php 代码

在Node.js中处理RSA解密问题,通常我们会使用内置的crypto模块。以下是一个简单的示例,展示了如何使用RSA私钥解密数据。

首先,确保你有一个RSA私钥(例如privateKey.pem)和一个使用相应公钥加密的密文。

以下是解密过程的代码示例:

const crypto = require('crypto');
const fs = require('fs');

// 读取私钥
const privateKey = fs.readFileSync('privateKey.pem', 'utf8');

// 假设这是你的加密数据(密文),base64编码
const encryptedData = 'your_encrypted_data_base64_here';
const buffer = Buffer.from(encryptedData, 'base64');

// 创建解密对象
const decrypted = crypto.privateDecrypt(
  {
    key: privateKey,
    padding: crypto.constants.RSA_PKCS1_PADDING
  },
  buffer
);

// 输出解密后的明文
console.log('Decrypted:', decrypted.toString('utf8'));

注意事项:

  1. 私钥格式:确保你的私钥格式正确,并且没有损坏。
  2. 填充方式:在加密和解密时,填充方式必须匹配。这里使用的是RSA_PKCS1_PADDING
  3. 编码:密文通常是以Base64编码存储的,所以在解密前需要将其转换为Buffer。

如果你遇到错误,检查以下几点:

  • 私钥是否与加密时使用的公钥匹配。
  • 填充方式和加密时使用的填充方式是否一致。
  • 编码是否正确处理。

希望这个示例能帮助你解决Node.js中的RSA解密问题。

回到顶部