当前位置:   article > 正文

平安银行esa接口对接 php生成sm2国密签名验签失败_php sm2

php sm2

难点

本次开发中主要的难点在于使用php生成sm2国密签名, 银行方面并没有专门的文档, 只给到一个java代码示例, 后续跟银行方开发要了一组数据和使用这组数据生成的sign (正是这组数据使开发过程走入了误区)

php类库

本次开发中使用了类库

composer require yuansir/php-gmssl
  • 1

误区

在php代码中存在配置

// 是否固定签名不随机,好处是同一段参数的签名固定,增大别人的猜测的难度,
// 同样的key + document每次签名是一样的,如果为false则每次不一样
protected $useDerandomizedSignatures = true;
  • 1
  • 2
  • 3

由注释可知当设置成false时相同参数每次生成的sign也是不同的
而之前银行方面给到的那组数据和sign一直作为了我们调试过程中是否正确的标准, 导致浪费了大量的时间,最后找java的朋友跑起了那段demo才发现这个问题每次sign都不一样,因此次数设置为

// 是否固定签名不随机,好处是同一段参数的签名固定,增大别人的猜测的难度,
// 同样的key + document每次签名是一样的,如果为false则每次不一样
protected $useDerandomizedSignatures = false;
  • 1
  • 2
  • 3

关键

当然使用类库的

$sign = $sm2->doSign($data, $sm2Secret)
  • 1

生成sign依然是不够的,如果给到的秘钥是base64格式还需要使用

$sign = $sm2->doSign($data, bin2hex(base64_decode($sm2Secret))
  • 1

以上生成的sign依然无法验签通过,还需要进一步处理

$sign = $sm2->doSign($data, bin2hex(base64_decode($sm2Secret)));
//关键
$sign = base64_decode($sign);
$a = ASNObject::fromBinary($sign)->getChildren();
$aa = self::formatHex($a[0]->getContent());
$bb = self::formatHex($a[1]->getContent());
$sign = $aa . $bb;
$sign = base64_encode(hex2bin($sign));

public static function formatHex($dec)
{

    $hex = gmp_strval(gmp_init($dec, 10), 16);
    $len = strlen($hex);
    if ($len == 64) {
        return $hex;
    }
    if ($len < 64) {
        $hex = str_pad($hex, 64, '0', STR_PAD_LEFT);
    } else {
        $hex = substr($hex, $len - 64, 64);
    }

    return $hex;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

此时拿到的sign才可以通过验签

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/118236
推荐阅读
相关标签
  

闽ICP备14008679号