V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
imherer
V2EX  ›  Node.js

nodejs RSA 解密问题

  •  
  •   imherer · 2017-02-16 16:58:14 +08:00 · 2489 次点击
    这是一个创建于 2624 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近接酷派 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->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);
    	}
    }
    ?>
    

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

    4 条回复    2017-02-17 10:18:07 +08:00
    neoblackcap
        1
    neoblackcap  
       2017-02-16 18:00:37 +08:00
    imherer
        2
    imherer  
    OP
       2017-02-16 19:15:40 +08:00
    @neoblackcap 谢谢,但是它这个 privatekey 和 modkey 都是很短的一段数字,完全不是 key 的格式啊,你给你代码不行呢、
    alouha
        3
    alouha  
       2017-02-17 08:48:06 +08:00
    酷派的好像接过啊,貌似 node 可以调用 php 代码,你可以试下
    imherer
        4
    imherer  
    OP
       2017-02-17 10:18:07 +08:00
    @alouha 你接过?用的什么语言? 我看看 node 调 php 代码
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3327 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 11:25 · PVG 19:25 · LAX 04:25 · JFK 07:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.