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

关于 RSA 签名问题

  •  
  •   imherer · 2017-05-27 18:08:35 +08:00 · 2448 次点击
    这是一个创建于 2764 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在接 SDK 支付的时候遇到一个签名问题,文档里给了 php demo,我拿过来也跑通了,但是把签名算法换成 nodejs 怎么跑都不通,不知道为啥。麻烦大佬帮忙看看

    private_key

    MIICXgIBAAKBgQDZjpotEmPKwRPKeqb6kqLgmiJkmUQ6EgMAlHBLCAdykb8mAKNWPFs+uyyknOAg+kqQzS9oEoF1P2YYDzYLVQeU4x2c9PtLPMxhXOqdiS6tdJ7RBa2SS4z0WaPmjGAds8qvVnec8Kp5/UXpIDXHRfJ7vNCwNB5O1BEJO/uIRMNIOwIDAQABAoGBAM/HCOpo+NPIyN0FfPotF8/IhXZshqOrViC0o/aU6X/7QILL8zNGG6Ly4nUouknkoVhgDpmnqupOrXPm+yehgsVljoeYRDVEmoyPvFNm+lbv5iDsnHlOohkyEdIO8tMYX7FT269YjWd7PGV1cnHqYUUAq0ncxbu2/RbPbXXsWcAJAkEA83tyOnvKMm46wEaLYXbUzS2iWCv+X0/4h5IKU9q9D2kYhApGaPIOWKf7qtLigkwvSwZ6ZU4kPKcmM817WR64vwJBAOS98iTBD6tYMe6U0Y5E1rO/sQQrIpMwJ2Y6PJQ/uU8z6rXsbEztUR/pbEExkf2a0xCByRxPEwrIRgzBat2Q84UCQHvAvLhY/tZPDHF56ZHqMhLvJNqn0axkGy/c3H7uaLWSdzF1f4ALt5r8FoAmm5YaXtdFPaSL6QMi+dnOkOklIkUCQQCFt0AhGjb1vCXcSWTDHRzBkRKC1FBu6JxvlyWoqCPE2B2h4aZhxe1BkWu2JKsqLGKr6KLPCK6iA/dnJ344La8dAkEA71Mz9WB4fhhU3e284lM1Y6ybS+F5a04racip9NbRAp9bnaDXDBO/EeFM4JZtb48IgnIJ0hfe09y+MDFgw4tgFA==
    

    要加密的数据

    var data ={"appid":"301074772","waresid":1,"cporderid":"123412zxcvzasdfqwesdfdsrasdghj","price":0.01,"currency":"RMB","appuserid":"10123059","cpprivateinfo":"11qwe123r23q232111"}
    

    php 代码

    /**格式化公钥
     * $priKey PKCS#1 格式的私钥串
     * return pem 格式私钥, 可以保存为.pem 文件
     */
    function formatPriKey($priKey) {
        $fKey = "-----BEGIN RSA PRIVATE KEY-----\n";
        $len = strlen($priKey);
        for($i = 0; $i < $len; ) {
            $fKey = $fKey . substr($priKey, $i, 64) . "\n";
            $i += 64;
        }
        $fKey .= "-----END RSA PRIVATE KEY-----";
        return $fKey;
    }
    function sign($data, $priKey) {
        //转换为 openssl 密钥
        $res = openssl_get_privatekey($priKey);
    	$content = json_encode($data);
        //调用 openssl 内置签名方法,生成签名$sign
        openssl_sign($content, $sign, $res, OPENSSL_ALGO_MD5);
    
        //释放资源
        openssl_free_key($res);
        
        //base64 编码
        $sign = base64_encode($sign);
        return $sign;
    }
    

    php 得到的结果是: YK5XuhB+ZhntOwm/riSCaCIqqLlrih+VgBRQa3H5VCUU6P/o38c+Q/UduQqFMQhLH7aZJ/z3ovSwgVxy+WFThGPthaQUPsLrALLZlReAcpuql28V8mD16WAnvxfY6R76jtdz4pF8gxNg4GeWXJXHc5M8RhInPeAai7F4gUlIbWI=

    nodejs 代码如下:

    function () {
        data = JSON.stringify(data);
        var p_key = '-----BEGIN RSA PRIVATE KEY-----\n';
        var strLength = Math.ceil(key.length / 64);
        for (var i = 0; i < strLength; i++) {
            var temp = key.substr(64 * i, 64);
            p_key += temp + '\n';
        }
        p_key += "-----END RSA PRIVATE KEY-----";
    
        var sign = crypto.createSign('RSA-SHA256'); // 这里 SHA1 和 SHA256 都试了一直不对
        var b = new Buffer(str);
        sign.update(b);
        return sign.sign(p_key, 'base64');
    };
    

    nodejs 结果: veNheq8kz/OyphVRNwHqXYYWhFJ/pqqkwDyKPwg29ig1wlzoEAzTfvDAN7Eoe+RGUW41dvRO7RjKaPRFdzihglmBwPQMBzzIeLGcJgb1vF41UFwNGIPnAa9HDqcIBWOLzSf72Qe26x0Qa15R80ZSJO8ztXxzshcqC/BqkaFAnMY=

    3 条回复    2017-05-28 05:30:52 +08:00
    twy2004
        1
    twy2004  
       2017-05-27 19:04:34 +08:00
    不是写的 MD5 么?

    怎么又成了 SHA1 ?
    imherer
        2
    imherer  
    OP
       2017-05-27 19:26:02 +08:00
    @twy2004 解决了。 确实是 MD5。 文档里说 RSA。我就一直在 RSA😂
    jyf007
        3
    jyf007  
       2017-05-28 05:30:52 +08:00
    2017 年已经 sha1 碰撞了,建议升级到 sha2-256 以上
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2807 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 03:06 · PVG 11:06 · LAX 19:06 · JFK 22:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.