PHP 转换 SM2 加密数据 ASN1 编码格式为 C1C3C2 格式数据
php 的 SM2 加密生成数据和解析数据格式基本为 C1C3C2 格式,JAVA 默认生成的加密数据为 ASN1 格式,PHP 解析可能会有问题,需要转换下才能使用,所以就写了一个转换函数。
下面是转换函数:
use phpseclib3\File\ASN1;
use phpseclib3\Math\BigInteger;
// sm2 加密数据 ASN1 格式转换为 c1c3c2 格式
// 需要 composer 安装 "phpseclib/phpseclib": "^3.0"
function sm2ASN1ToC1C3C2($data)
{
$der = ASN1::decodeBER(base64_decode($data));
$x = "";
$y = "";
if (isset($der[0]["content"][0]["content"])) {
$x = $der[0]["content"][0]["content"]->toHex();
}
if (isset($der[0]["content"][1]["content"])) {
$y = $der[0]["content"][1]["content"]->toHex();
}
$hash = bin2hex($der[0]["content"][2]["content"] ?? "");
$ct = bin2hex($der[0]["content"][3]["content"] ?? "");
$x = str_pad($x, 64, "0", STR_PAD_LEFT);
$y = str_pad($y, 64, "0", STR_PAD_LEFT);
$endata = $x . $y . $hash . $ct;
return $endata;
}
// sm2 加密数据 c1c3c2 格式转换为 ASN1 格式
function sm2C1C3C2ToASN1($data)
{
$data = hex2bin($data);
$x = substr($data, 0, 32);
$y = substr($data, 32, 32);
$hash = substr($data, 64, 32);
$ct = substr($data, 96);
$map = [
'type' => ASN1::TYPE_SEQUENCE,
'children' => [
'x' => ['type' => ASN1::TYPE_INTEGER],
'y' => ['type' => ASN1::TYPE_INTEGER],
'hash' => ['type' => ASN1::TYPE_OCTET_STRING],
'ct' => ['type' => ASN1::TYPE_OCTET_STRING]
]
];
$derData = [
'x' => new BigInteger($x, 256),
'y' => new BigInteger($y, 256),
'hash' => $hash,
'ct' => $ct
];
$der = ASN1::encodeDER($derData, $map);
return base64_encode($der);
}
测试:
use Rtgm\sm\RtSm2;
// 测试数据
$prikey = "6b4bb2cfe6d4e3499f74cfd05b048b380230d6d7837ebbe1a865850054fbafdb";
$data = "MGwCIQDafQBon8ZrC5fRya4oC6yAgONN6PIWN/I4fk/8wwhGIAIgJgJ/vmW0UmEGmzTp4sgPvigyafQXSU5gsfwLJvE1WYwEIM8nvAb2K7xoK/Q/yi7z/7jzq5XwO3/TtDyvluEiZD0yBAP1Ed4=";
$endata = sm2ASN1ToC1C3C2($data);
// 使用包: "lpilp/guomi": "1.0.*",
$sm2 = new RtSm2();
$res = $sm2->doDecrypt($endata, $prikey);
var_dump($res);
// 输出: 123
// 转为 ASN1 格式
$asn1data = sm2C1C3C2ToASN1($endata);
var_dump($asn1data);
解析 ASN1 编码格式和编码 ASN1 编码格式用到了第三方包 phpseclib/phpseclib
, SM2 解密测试用到的包 lpilp/guomi
。
其他 PHP 包解密 SM2 加密数据时请注意测试。
go 的 sm2解密可以查看 sm2 doc
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: