关于RSA解密,求各路大神帮忙把这段php代码译成node,或者给点node写法思路也行
发布于 3 年前 作者 im-here 2406 次浏览 来自 问答

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->decrypt($sign, $private_key, $mod_key);
		$msg_md5 = md5($trans_data);
		//echo "key3 : {$key3} <br/>\n";
		//echo "private_key : {$private_key} <br/>\n";
		//echo "mod_key : {$mod_key} <br/>\n";
		//echo "sign_md5 : {$sign_md5} <br/>\n";
		//echo "msg_md5 : {$msg_md5} <br/>\n";
		
		return strcmp($msg_md5,$sign_md5);
	}
}
?>

RSAUtil.php 文件:

<?php
class RSAUtil{
		/**
	 * 解密方法
	 * @param $string 需要解密的密文字符
	 * @param $d
	 * @param $n
	 * @return String
	 */
	public function decrypt($string, $d, $n){
		//解决某些机器验签时好时坏的bug
		//BCMath 里面的函数 有的机器php.ini设置不起作用
		//要在RSAUtil的方法decrypt 加bcscale(0);这样一行代码才行
		//要不有的机器计算的时候会有小数点 就会失败
		bcscale(0);
		
		$bln = $this->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);
	}
}
?>

主要是最后这个解密函数不知道怎么用node写,虽然node有现成的RSA解密库,但是这个demo里的给的解密是需要2个key的,所以不知道怎么写了。

6 回复

供参考:

/**
 * rsa签名
 * @param prestr
 * @param key_file
 * @return {*|number}
 */
var rsaSign = function (prestr, key_file) {
    let pem = fs.readFileSync(key_file);
    let prikey = pem.toString('ascii');
    let signob = crypto.createSign('RSA-SHA1');
    signob.update(prestr, 'utf8');
    return signob.sign(prikey, 'base64');
};

/**
 * rsa签名验证
 * @param prestr
 * @param sign
 * @param key_file
 * @return {void|Object[]}
 */
var rsaVerify = function (prestr, sign, key_file) {
    let publicPem = fs.readFileSync(key_file);
    let publicKey = publicPem.toString('ascii');
    let verifyob = crypto.createVerify('RSA-SHA1');
    verifyob.update(prestr, 'utf8');
    let res = verifyob.verify(publicKey, sign, 'base64');
    return res;
};

@richenlin 额,你这个是签名和验签,不是我想要的加密和解密。不过还是谢谢你的回答!

我也被这个问题困扰了很久,$v = bcpowmod($v, $d, $n);里面的$d这个数好大,表示不知道怎么用node处理了,用了bignumber.js库也表示不了,麻烦解决了告知一声吧

@jiurihuahuo 我还卡着的。。。。

@jiurihuahuo 试试 BigInt.js 呢

你怎么总在问各种语言转成js怎么写

回到顶部