PHP国密SM2\SM4对接Java SM2SignWithSM3 (招商银行云直联)
添加composer 包:
composer require lpilp/guomi
SM2签名
<?php use Mdanter\Ecc\Crypto\Key\PrivateKey; use Mdanter\Ecc\Crypto\Signature\Signature; use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer; use Rtgm\ecc\RtEccFactory; use Rtgm\sm\RtSm2; require 'vendor/autoload.php'; $data = '{"request":{"body":{"TEST":"中文","TEST2":"!@#$%^&*()","TEST3":12345,"TEST4":[{"arrItem1":"qaz","arrItem2":123,"arrItem3":true,"arrItem4":"中文"}],"buscod":"N02030"},"head":{"funcode":"DCLISMOD","userid":"N003261207"}},"signature":{"sigdat":"__signature_sigdat__"}}'; $key = 'NBtl7WnuUtA2v5FaebEkU0/Jj1IodLGT6lQqwkzmd2E='; $key = bin2hex(base64_decode($key));//转为16进制 $sm2 = new RtSm2('base64'); $userid = 'N003261207' . "0000000000000000"; $userid = substr($userid, 0, 16); //签名 $sign = $sm2->doSign($data, $key, $userid); $sign = base64_decode($sign); $a = \FG\ASN1\ASNObject::fromBinary($sign)->getChildren(); $aa = formatHex($a[0]->getContent()); $bb = formatHex($a[1]->getContent()); $sign = $aa. $bb; $sign = base64_encode(hex2bin($sign)); var_dump($sign); //验签 $signHex = bin2hex(base64_decode($sign)); var_dump($signHex); $r = substr($signHex, 0, 64); $s = substr($signHex, 64, 64); var_dump($r, $s); $r = gmp_init($r, 16); $s = gmp_init($s, 16); /*$r = gmp_init('90416529259334433398865842692135340273188180784859666141339740103133164395295', 10); $s = gmp_init('51927610271972364114244381230895889971736075490328811928131691394657016568041', 10);*/ $signature = new Signature( $r, $s ); $serializer = new DerSignatureSerializer(); $serializedSig = $serializer->serialize($signature); $sign = base64_encode($serializedSig); var_dump($sign); $adapter = RtEccFactory::getAdapter(); $generator = RtEccFactory::getSmCurves()->generatorSm2(); $secret = gmp_init($key, 16); $key = new PrivateKey($adapter, $generator, $secret); $pubkey = $key->getPublicKey()->getPoint(); $x = $pubkey->getX(); $y = $pubkey->getY(); $pub = gmp_strval($x, 16); $pub .= gmp_strval($y, 16); var_dump($pub); $b = $sm2->verifySign($data, $sign, $pub, $userid); var_dump($b); 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; }
SM4加密
$userid = 'N003261207' . "0000000000000000"; $userid = substr($userid, 0, 16); $sm4 = new RtSm4($key); $sign = $sm4->encrypt($data,'sm4',$userid ,'base64');
SM4解密
$userid = 'N003261207' . "0000000000000000"; $userid = substr($userid, 0, 16); $sm4 = new RtSm4($key); $data = $sm4->decrypt($sign,'sm4-cbc',$userid ,'base64');