first commit
This commit is contained in:
3
pgserver/vendor/lpilp/guomi/.gitignore
vendored
Normal file
3
pgserver/vendor/lpilp/guomi/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
vendor2/
|
||||
vendor/
|
||||
composer.lock
|
||||
58
pgserver/vendor/lpilp/guomi/README.md
vendored
Normal file
58
pgserver/vendor/lpilp/guomi/README.md
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
# php sm2 sm3 sm4 国密算法整理
|
||||
* 本项目支持php版本的国密sm2的签名算法,非对称加解密算法(非对称加密刚上线,目前测试无问题,不能保证兼容其他语言,有问题可以提issues),sm3的hash, sm4的对称加解密,要求PHP7,打开gmp支持
|
||||
* 目前如果服务器配套的使用的是openssl 1.1.1x, 目前到1.1.1.l(L) ,sm3,sm4都可以直接用openssl_xxx系列函数直接实现,不必大量的代码,但不支持sm2的签名,sm2的加解密
|
||||
* 有一个sm3, sm4的比较好的代码: https://github.com/lizhichao/sm 可以使用composer安装,只是这个的ecb, cbc没有做补齐
|
||||
|
||||
### 使用(how to use)
|
||||
* composer require lpilp/guomi
|
||||
* please make sure you upgrade to Composer 2+
|
||||
* PHP >=7.2,打开gmp组件支持
|
||||
* 如需要使用php5.6 请使用wzhih童鞋fork修改的 https://github.com/wzhih/guomi ; composer require wzhih/guomi
|
||||
### SM2
|
||||
* 签名验签算法主体基于PHPECC算法架构,添加了sm2的椭圆参数,
|
||||
* 参考了 https://github.com/ToAnyWhere/phpsm2 童鞋的sm2验签算法,密钥生成算法
|
||||
* 添加了签名算法, 支持sm2的16进制,base64公私钥的签名,验签算法
|
||||
* 支持从文件中读取pem文件的签名,验签算法
|
||||
* 由于 openssl没有实现sm2withsm3算法,用系统函数无法实现签名及证书的自签名分发
|
||||
|
||||
### SM2非对称加密
|
||||
* 添加了sm2的非对称加密的算法,但速度一般,有待优化,不能保证兼容所有语言进行加解密,目前测试了js, python的相互加解密
|
||||
* sm2的加密解密算法在openssl 1.1.1的版本下自带的函数中暂无sm2的公钥私钥的加密函数,得自己实现,建议使用C,C++的算法,打包成PHP扩展的方式
|
||||
* SM2的非对称加密缺省的是c1c3c2, 请使用的时候注意下,对方返回的是c1c3c2还是c1c2c3,进行相应的修改更新,还有一点就是本项目中c1前面没有04, 视对接方的需求,看是否添加\x04, v1.0.6版已对c1c3c2还是c1c2c3做了兼容,缺省是c1c3c2,添加相应的modetype后可以兼容两种模式,使用方法见 test/tsm2_encrypt.php
|
||||
|
||||
### SM3
|
||||
* 该算法直接使用 https://github.com/ToAnyWhere/phpsm2 中sm2签名用到的匹配sm3, 未做修改
|
||||
* 也可使用 openssl的函数, 详见openssl_tsm3.php
|
||||
|
||||
### SM4
|
||||
* 该算法直接封装使用 https://github.com/lizhichao/sm 的sm4算法, 同时该项目支持 sm3,sm4 ,可以composer安装
|
||||
* 由于sm4-ecb, sm4-cbc加密需要补齐,项目lizhichao/sm项目未做补齐操作,这里封装的时候,针对这两个算法做了补齐操作, 其他如sm4-ctr,sm4-cfb,sm4-ofb等,可以直接用
|
||||
* 在openssl 1.1.1下可使用系统的函数,已支持sm4-cbc,sm4-cfb,sm4-ctr,sm4-ecb,sm4-ofb, 详见openssl_tsm4.php
|
||||
|
||||
### SM2各语言总结
|
||||
* 这里封装的测试函数已与相关的js,python,java,go等都可以互签互认
|
||||
* js: https://github.com/JuneAndGreen/sm-crypto 一个注意点就是: js的中文字符转成byte[]时,缺省的是unicode编码两字节,需要转成utf8的三字节编码,一个简单的方案 unescape(encodeURIComponent(str)) 然后再一个字节一个字节读就行了
|
||||
* python: https://github.com/duanhongyi/gmssl 使用 pip install gmssl 安装就可, 注意的就是在python2下 , string与byte[] 是可以隐式转换的,在python3下需要显式地将string转成byte[]
|
||||
* java: https://github.com/ZZMarquis/gmhelper 注意下java中文的转码问题,getBytes("UTF-8"), 要加上编码类型, 因为 getBytes()函数的缺省编码是随操作系统的,如果是在中文版的windows中使用,缺省是GBK编码,就会出现中文的编码的问题,而造成签名无法通过
|
||||
* openssl: 升到1.1.1以后,支持sm3,sm4的加解密,还不支持sm2的公私钥加解密,也不支持sm2的签名,得使用原生代码实现,签名中需要实现sm2withsm3, openssl1.1.1只实现了sm2whithsha256;还有一点很诡异,用yum/dnf安装的openssl只支持sm3, 如果是自己编译安装的就支持sm3,sm4
|
||||
+ go: https://github.com/tjfoc/gmsm 一家做区块链的公司开源的项目,在go方面可以说是最早开源的了,sm2主要有两个问题:
|
||||
1. 暂无使用外部密码明文生成公私钥构造函数,比较简单可自行添加
|
||||
2. sm2的非对称加解密例子中使用EncryptAsn1这个函数,asn1是将 c1拆开为px,py两部分,asn1(px,py,c3,c2)的编码;在sm2类中也有直接Encrypt函数,生成的是'\x04'+c1+c3+c2 与其它语言生成的加密串在c1部分多加了一个\x04, 看互通代码的需求自行处理
|
||||
3. 签名与验签的方法可与本项目的PHP语言是互签互认的
|
||||
4. sm4的对称加解密cbc等需要IV向量的模式,将iv做为全局变量了,对于不同的串要使用不同的iv时,就会出现麻烦,请根据需要修改代码,将iv加到参数里
|
||||
+ C#: 项目也比较少,基本是基于https://www.bouncycastle.org/ 的BC加密库(java也是基于该库),该库1.8.4后版本支持sm2,sm3,sm4,考察搜索到的几个项目,https://github.com/hz281529512/SecretTest 完整性算比较好
|
||||
1. 项目提供sm2的签名,加解密都加入的项目,其他的项目里没有签名算法,sm2的加解密的返回值与上面的go项目一样返回的是asn1编码过的,如需要原始的请自行修改更新
|
||||
2. sm4的cbc的封装后把 key与iv弄成一个值了,如需要请自行修改更新
|
||||
### SM2签名常见问题
|
||||
* 提供的私钥是base64的短串,一般直接 bin2hex(base64_decode(str)) 就是明文的密钥了
|
||||
* 文件格式的密钥一般有pkcs1与pkcs8两个格式,本项目只支持pkcs1格式的密钥,使用前请先进行相关的转换,一般 pkcs8是四行,pkcs1是三行,区别见 https://www.jianshu.com/p/a428e183e72e
|
||||
* 关于签名的字符串的问题,有些项目会将原始字符串哈稀后,再对哈稀值进行签名,有些对这哈稀值又进行了hex2bin操作后再签名,请双方按约定的标准确定最后签名的数据值,双方保持一致即可
|
||||
* 个别项目会碰到asn1的时候解析不了,如果是密钥解析不了,一般就是pkcs8的问题,如果只是数据解析不了的话看报错,调试下,目前碰到的是招行的一个问题,对int数据的asn1编码有前面补0与否不按标准来,全都补0
|
||||
* 签名的结果是asn1(r,s),有极个别的项目签名出来的只是 r+s的字符串组合,验证签名的时候注意下。
|
||||
* ***招行*** 的签名回调系统在做asn1编码的int类型的时候,标准是最高位大于7D是要补0,反之则不要补0,而招行返回的统一32字节长度,对于一些不用补0的也强制补0,使用的第三方phpasn1会报错,可以屏蔽该错误,或是将返回的签名过滤下,项目提供了一个过滤的类 src/util/FormatSign->run(),使用测试见 test/tfsign.php
|
||||
* 同样的,在用本项目给 ***招行*** 签名的时候,就会出现上面同样的问题,编码int的时候,招行认为签名的r,s都是32字节,这时对于偶发的小于32字节的r,s,就得补0操作,src/util/FormatSign->format_cmbc()函数,目前只针对招行, 所以只是以补丁的方式,没有加入主程序
|
||||
* 以上是现行的招行的程序打的补丁,不能保证招行修复了这个bug, 假设招行修复了这个bug,使用了format_cmbc(),那个小概率的反而会错了,请根据实际情况使用,招行有提供相关的sdk,看是否更新就知道了
|
||||
|
||||
|
||||
|
||||
|
||||
31
pgserver/vendor/lpilp/guomi/composer.json
vendored
Normal file
31
pgserver/vendor/lpilp/guomi/composer.json
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "lpilp/guomi",
|
||||
"description": "国密sm2",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "recent",
|
||||
"email": "lpilp@126.com"
|
||||
}
|
||||
],
|
||||
"minimum-stability": "stable",
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"mdanter/ecc": "^1.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Rtgm\\": "src"
|
||||
},
|
||||
"files": ["src/overwrite.php"]
|
||||
|
||||
},
|
||||
"repositories": {
|
||||
"packagist": {
|
||||
"type": "composer",
|
||||
"url": "https://mirrors.aliyun.com/composer/"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
125
pgserver/vendor/lpilp/guomi/src/ecc/Curves/CurveFactory.php
vendored
Normal file
125
pgserver/vendor/lpilp/guomi/src/ecc/Curves/CurveFactory.php
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
/**
|
||||
* 覆盖ecc里的椭圆类,添加sm2
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mdanter\Ecc\Curves;
|
||||
|
||||
// use Mdanter\Ecc\Exception\UnknownCurveException;
|
||||
use Mdanter\Ecc\Exception\UnsupportedCurveException;
|
||||
use Mdanter\Ecc\Math\GmpMathInterface;
|
||||
use Mdanter\Ecc\Math\MathAdapterFactory;
|
||||
use Mdanter\Ecc\Primitives\GeneratorPoint;
|
||||
use Rtgm\ecc\Sm2Curve;
|
||||
|
||||
class CurveFactory
|
||||
{
|
||||
/**
|
||||
* @param string $name
|
||||
* @return NamedCurveFp
|
||||
*/
|
||||
public static function getCurveByName(string $name): NamedCurveFp
|
||||
{
|
||||
$adapter = MathAdapterFactory::getAdapter();
|
||||
if($name == Sm2Curve::NAME_PSM2){
|
||||
return self::getSm2Factory($adapter)->curveSm2();
|
||||
}
|
||||
$nistFactory = self::getNistFactory($adapter);
|
||||
$secpFactory = self::getSecpFactory($adapter);
|
||||
|
||||
switch ($name) {
|
||||
case NistCurve::NAME_P192:
|
||||
return $nistFactory->curve192();
|
||||
case NistCurve::NAME_P224:
|
||||
return $nistFactory->curve224();
|
||||
case NistCurve::NAME_P256:
|
||||
return $nistFactory->curve256();
|
||||
case NistCurve::NAME_P384:
|
||||
return $nistFactory->curve384();
|
||||
case NistCurve::NAME_P521:
|
||||
return $nistFactory->curve521();
|
||||
case SecgCurve::NAME_SECP_112R1:
|
||||
return $secpFactory->curve112r1();
|
||||
case SecgCurve::NAME_SECP_192K1:
|
||||
return $secpFactory->curve192k1();
|
||||
case SecgCurve::NAME_SECP_256K1:
|
||||
return $secpFactory->curve256k1();
|
||||
case SecgCurve::NAME_SECP_256R1:
|
||||
return $secpFactory->curve256r1();
|
||||
case SecgCurve::NAME_SECP_384R1:
|
||||
return $secpFactory->curve384r1();
|
||||
default:
|
||||
$error = new UnsupportedCurveException('Unknown curve.');
|
||||
$error->setCurveName($name);
|
||||
throw $error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return GeneratorPoint
|
||||
*/
|
||||
public static function getGeneratorByName(string $name): GeneratorPoint
|
||||
{
|
||||
$adapter = MathAdapterFactory::getAdapter();
|
||||
if($name == Sm2Curve::NAME_PSM2){
|
||||
return self::getSm2Factory($adapter)->generatorSm2();
|
||||
}
|
||||
$nistFactory = self::getNistFactory($adapter);
|
||||
$secpFactory = self::getSecpFactory($adapter);
|
||||
|
||||
switch ($name) {
|
||||
case NistCurve::NAME_P192:
|
||||
return $nistFactory->generator192();
|
||||
case NistCurve::NAME_P224:
|
||||
return $nistFactory->generator224();
|
||||
case NistCurve::NAME_P256:
|
||||
return $nistFactory->generator256();
|
||||
case NistCurve::NAME_P384:
|
||||
return $nistFactory->generator384();
|
||||
case NistCurve::NAME_P521:
|
||||
return $nistFactory->generator521();
|
||||
case SecgCurve::NAME_SECP_112R1:
|
||||
return $secpFactory->generator112r1();
|
||||
case SecgCurve::NAME_SECP_192K1:
|
||||
return $secpFactory->generator192k1();
|
||||
case SecgCurve::NAME_SECP_256K1:
|
||||
return $secpFactory->generator256k1();
|
||||
case SecgCurve::NAME_SECP_256R1:
|
||||
return $secpFactory->generator256r1();
|
||||
case SecgCurve::NAME_SECP_384R1:
|
||||
return $secpFactory->generator384r1();
|
||||
default:
|
||||
$error = new UnsupportedCurveException('Unknown generator.');
|
||||
$error->setCurveName($name);
|
||||
throw $error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GmpMathInterface $math
|
||||
* @return NistCurve
|
||||
*/
|
||||
private static function getNistFactory(GmpMathInterface $math): NistCurve
|
||||
{
|
||||
return new NistCurve($math);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GmpMathInterface $math
|
||||
* @return SecgCurve
|
||||
*/
|
||||
private static function getSecpFactory(GmpMathInterface $math): SecgCurve
|
||||
{
|
||||
return new SecgCurve($math);
|
||||
}
|
||||
/**
|
||||
* @param GmpMathInterface $math
|
||||
* @return Sm2
|
||||
*/
|
||||
private static function getSm2Factory(GmpMathInterface $math): Sm2Curve
|
||||
{
|
||||
return new Sm2Curve($math);
|
||||
}
|
||||
}
|
||||
44
pgserver/vendor/lpilp/guomi/src/ecc/RtEccFactory.php
vendored
Normal file
44
pgserver/vendor/lpilp/guomi/src/ecc/RtEccFactory.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
namespace Rtgm\ecc;
|
||||
|
||||
use Mdanter\Ecc\Math\GmpMathInterface;
|
||||
use Mdanter\Ecc\Math\MathAdapterFactory;
|
||||
use Mdanter\Ecc\EccFactory;
|
||||
|
||||
// use Rtgm\sm\ecc\NistCurve;
|
||||
use Rtgm\ecc\Sm2Curve;
|
||||
/**
|
||||
* 添加sm2的工厂,采用类的继承方式,这里也可以采用如 \Curves\CurveFctory的覆盖的方式
|
||||
*/
|
||||
class RtEccFactory extends EccFactory{
|
||||
|
||||
/**
|
||||
* Selects and creates the most appropriate adapter for the running environment.
|
||||
*
|
||||
* @param bool $debug [optional] Set to true to get a trace of all mathematical operations
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @return GmpMathInterface
|
||||
*/
|
||||
public static function getAdapter(bool $debug = false): GmpMathInterface
|
||||
{
|
||||
|
||||
$adapter = MathAdapterFactory::getAdapter($debug);
|
||||
return $adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a factory to create NIST Recommended curves and generators.
|
||||
*
|
||||
* @param GmpMathInterface $adapter [optional] Defaults to the return value of EccFactory::getAdapter().
|
||||
* @return Sm2Curve
|
||||
*/
|
||||
public static function getSmCurves(GmpMathInterface $adapter = null): Sm2Curve
|
||||
{
|
||||
$adapter = $adapter ?: self::getAdapter();
|
||||
// var_dump($adapter);
|
||||
return new Sm2Curve($adapter);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
149
pgserver/vendor/lpilp/guomi/src/ecc/Serializer/Util/CurveOidMapper.php
vendored
Normal file
149
pgserver/vendor/lpilp/guomi/src/ecc/Serializer/Util/CurveOidMapper.php
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/**
|
||||
* 覆盖ecc里的oid与椭圆的对照数组,添加sm2
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mdanter\Ecc\Serializer\Util;
|
||||
|
||||
use FG\ASN1\Universal\ObjectIdentifier;
|
||||
use Mdanter\Ecc\Curves\NamedCurveFp;
|
||||
use Mdanter\Ecc\Curves\CurveFactory;
|
||||
use Mdanter\Ecc\Curves\NistCurve;
|
||||
use Mdanter\Ecc\Curves\SecgCurve;
|
||||
use Rtgm\ecc\Sm2Curve;
|
||||
use Mdanter\Ecc\Exception\UnsupportedCurveException;
|
||||
use Mdanter\Ecc\Primitives\CurveFpInterface;
|
||||
use Mdanter\Ecc\Primitives\GeneratorPoint;
|
||||
class CurveOidMapper
|
||||
{
|
||||
|
||||
const NIST_P192_OID = '1.2.840.10045.3.1.1';
|
||||
|
||||
const NIST_P224_OID = '1.3.132.0.33';
|
||||
|
||||
const NIST_P256_OID = '1.2.840.10045.3.1.7';
|
||||
|
||||
const NIST_P384_OID = '1.3.132.0.34';
|
||||
|
||||
const NIST_P521_OID = '1.3.132.0.35';
|
||||
|
||||
const SECP_112R1_OID = '1.3.132.0.6';
|
||||
|
||||
const SECP_192K1_OID = '1.3.132.0.31';
|
||||
|
||||
const SECP_256K1_OID = '1.3.132.0.10';
|
||||
|
||||
const SECP_256R1_OID = '1.2.840.10045.3.1.7';
|
||||
|
||||
const SECP_384R1_OID = '1.3.132.0.34';
|
||||
|
||||
const SM2_OID = '1.2.156.10197.1.301';
|
||||
// const SM2_OID = '1.2.840.10045.2.1';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $oidMap = array(
|
||||
NistCurve::NAME_P192 => self::NIST_P192_OID,
|
||||
NistCurve::NAME_P224 => self::NIST_P224_OID,
|
||||
NistCurve::NAME_P256 => self::NIST_P256_OID,
|
||||
NistCurve::NAME_P384 => self::NIST_P384_OID,
|
||||
NistCurve::NAME_P521 => self::NIST_P521_OID,
|
||||
SecgCurve::NAME_SECP_112R1 => self::SECP_112R1_OID,
|
||||
SecgCurve::NAME_SECP_192K1 => self::SECP_192K1_OID,
|
||||
SecgCurve::NAME_SECP_256K1 => self::SECP_256K1_OID,
|
||||
SecgCurve::NAME_SECP_256R1 => self::SECP_256R1_OID,
|
||||
SecgCurve::NAME_SECP_384R1 => self::SECP_384R1_OID,
|
||||
Sm2Curve::NAME_PSM2 => self::SM2_OID,
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $sizeMap = array(
|
||||
NistCurve::NAME_P192 => 24,
|
||||
NistCurve::NAME_P224 => 28,
|
||||
NistCurve::NAME_P256 => 32,
|
||||
NistCurve::NAME_P384 => 48,
|
||||
NistCurve::NAME_P521 => 66,
|
||||
SecgCurve::NAME_SECP_112R1 => 14,
|
||||
SecgCurve::NAME_SECP_192K1 => 24,
|
||||
SecgCurve::NAME_SECP_256K1 => 32,
|
||||
SecgCurve::NAME_SECP_256R1 => 32,
|
||||
SecgCurve::NAME_SECP_384R1 => 48,
|
||||
Sm2Curve::NAME_PSM2 =>32, //sm2 也是256位的,32个字节的密码
|
||||
);
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getNames(): array
|
||||
{
|
||||
return array_keys(self::$oidMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CurveFpInterface $curve
|
||||
* @return int
|
||||
*/
|
||||
public static function getByteSize(CurveFpInterface $curve): int
|
||||
{
|
||||
if ($curve instanceof NamedCurveFp && array_key_exists($curve->getName(), self::$sizeMap)) {
|
||||
return self::$sizeMap[$curve->getName()];
|
||||
}
|
||||
|
||||
throw new UnsupportedCurveException('Unsupported curve type');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param NamedCurveFp $curve
|
||||
* @return ObjectIdentifier
|
||||
*/
|
||||
public static function getCurveOid(NamedCurveFp $curve): ObjectIdentifier
|
||||
{
|
||||
if (array_key_exists($curve->getName(), self::$oidMap)) {
|
||||
$oidString = self::$oidMap[$curve->getName()];
|
||||
|
||||
return new ObjectIdentifier($oidString);
|
||||
}
|
||||
|
||||
throw new UnsupportedCurveException('Unsupported curve type');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ObjectIdentifier $oid
|
||||
* @return NamedCurveFp
|
||||
*/
|
||||
public static function getCurveFromOid(ObjectIdentifier $oid): NamedCurveFp
|
||||
{
|
||||
$oidString = $oid->getContent();
|
||||
$invertedMap = array_flip(self::$oidMap);
|
||||
|
||||
if (array_key_exists($oidString, $invertedMap)) {
|
||||
return CurveFactory::getCurveByName($invertedMap[$oidString]);
|
||||
}
|
||||
|
||||
$error = new UnsupportedCurveException('Invalid data: unsupported curve.');
|
||||
$error->setOid($oidString);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ObjectIdentifier $oid
|
||||
* @return GeneratorPoint
|
||||
*/
|
||||
public static function getGeneratorFromOid(ObjectIdentifier $oid): GeneratorPoint
|
||||
{
|
||||
$oidString = $oid->getContent();
|
||||
$invertedMap = array_flip(self::$oidMap);
|
||||
|
||||
if (array_key_exists($oidString, $invertedMap)) {
|
||||
return CurveFactory::getGeneratorByName($invertedMap[$oidString]);
|
||||
}
|
||||
|
||||
$error = new UnsupportedCurveException('Invalid data: unsupported generator.');
|
||||
$error->setOid($oidString);
|
||||
throw $error;
|
||||
}
|
||||
}
|
||||
60
pgserver/vendor/lpilp/guomi/src/ecc/Sm2Curve.php
vendored
Normal file
60
pgserver/vendor/lpilp/guomi/src/ecc/Sm2Curve.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
namespace Rtgm\ecc;
|
||||
|
||||
use Mdanter\Ecc\Curves\NamedCurveFp;
|
||||
use Mdanter\Ecc\Math\GmpMathInterface;
|
||||
use Mdanter\Ecc\Primitives\CurveParameters;
|
||||
use Mdanter\Ecc\Primitives\GeneratorPoint;
|
||||
use Mdanter\Ecc\Random\RandomNumberGeneratorInterface;
|
||||
|
||||
/**
|
||||
* 国密sm2椭圆
|
||||
*/
|
||||
class Sm2Curve
|
||||
{
|
||||
const NAME_PSM2 = 'SM2';
|
||||
/**
|
||||
* @var GmpMathInterface
|
||||
*/
|
||||
private $adapter;
|
||||
|
||||
/**
|
||||
* @param GmpMathInterface $adapter
|
||||
*/
|
||||
public function __construct(GmpMathInterface $adapter)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
// echo "I am sm ecc\n";
|
||||
}
|
||||
/**
|
||||
* Returns an sm2国密 curve.
|
||||
*
|
||||
* @return NamedCurveFp
|
||||
*/
|
||||
public function curveSm2(): NamedCurveFp
|
||||
{
|
||||
$p = gmp_init('0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF', 16);
|
||||
$b = gmp_init('0x28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93', 16);
|
||||
$a = gmp_init('0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC', 16);
|
||||
$parameters = new CurveParameters(256, $p, $a, $b);
|
||||
|
||||
return new NamedCurveFp(self::NAME_PSM2, $parameters, $this->adapter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an sm2 generator.
|
||||
*
|
||||
* @param RandomNumberGeneratorInterface $randomGenerator
|
||||
* @return GeneratorPoint
|
||||
*/
|
||||
public function generatorSm2(RandomNumberGeneratorInterface $randomGenerator = null): GeneratorPoint
|
||||
{
|
||||
$curve = $this->curveSm2();
|
||||
$order = gmp_init('0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123', 16);
|
||||
|
||||
$x = gmp_init('0x32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7', 16);
|
||||
$y = gmp_init('0xBC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0', 16);
|
||||
|
||||
return $curve->getGenerator($x, $y, $order, $randomGenerator);
|
||||
}
|
||||
}
|
||||
126
pgserver/vendor/lpilp/guomi/src/ecc/Sm2Signer.php
vendored
Normal file
126
pgserver/vendor/lpilp/guomi/src/ecc/Sm2Signer.php
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
declare( strict_types = 1 );
|
||||
|
||||
// namespace Mdanter\Ecc\Crypto\Signature;
|
||||
namespace Rtgm\ecc;
|
||||
|
||||
use Mdanter\Ecc\Math\GmpMathInterface;
|
||||
use Mdanter\Ecc\Crypto\Key\PrivateKeyInterface;
|
||||
use Mdanter\Ecc\Crypto\Key\PublicKeyInterface;
|
||||
use Mdanter\Ecc\Util\BinaryString;
|
||||
use Mdanter\Ecc\Crypto\Signature\SignatureInterface;
|
||||
use Mdanter\Ecc\Crypto\Signature\Signature;
|
||||
/**
|
||||
* sm2签名算法
|
||||
*/
|
||||
class Sm2Signer {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var GmpMathInterface
|
||||
*/
|
||||
private $adapter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param GmpMathInterface $adapter
|
||||
*/
|
||||
|
||||
public function __construct( GmpMathInterface $adapter ) {
|
||||
$this->adapter = $adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PrivateKeyInterface $key
|
||||
* @param \GMP $truncatedHash - hash truncated for use in ECDSA hash算法然后truncated by 相关的椭圆字节
|
||||
* @param \GMP $randomK
|
||||
* @return SignatureInterface
|
||||
*/
|
||||
|
||||
public function sign( PrivateKeyInterface $key, \GMP $truncatedHash, \GMP $randomK ): SignatureInterface {
|
||||
$math = $this->adapter;
|
||||
$generator = $key->getPoint();
|
||||
// var_dump($generator);die();
|
||||
$n = $generator->getOrder();
|
||||
$modMath = $math->getModularArithmetic( $n );
|
||||
$prikey = $key->getSecret();
|
||||
//第一二步是userid, msg 生成 trucatedhash ,
|
||||
$count = 0;
|
||||
while (true) {
|
||||
$count++;
|
||||
// echo "count: $count\n";
|
||||
if($count >5){
|
||||
throw new \RuntimeException( 'Error: sign R or S = 0' );
|
||||
}
|
||||
// 第三步生成随机数
|
||||
$k = $math->mod( $randomK, $n );
|
||||
// 第四步 计算pt1(x1,y1) = [K]G这个点
|
||||
// 生成一个新的点P = kG
|
||||
$p1 = $generator->mul( $k );
|
||||
// var_dump($p1);die();
|
||||
// 第五步 计算 r = (truncatedHash + x1) mod n
|
||||
$r = $modMath->add($truncatedHash,$p1->getX());
|
||||
// var_dump(gmp_strval($r,16));die();
|
||||
$zero = gmp_init( 0, 10 );
|
||||
if ( $math->equals( $r, $zero ) ) {
|
||||
// @todo 如报错,重来
|
||||
// continue; //报错重来一次
|
||||
// @todo
|
||||
throw new \RuntimeException( 'Error: random number R = 0' );
|
||||
}
|
||||
// 第六步 计算 s = ((1 + d)^-1 * (k - rd)) mod n
|
||||
|
||||
$one = gmp_init(1,10);
|
||||
$s1 = $math->inverseMod($math->add($one, $prikey),$n );
|
||||
// print_r(gmp_strval($s1,16));die();
|
||||
$s2 = $math->sub($k,$math->mul($r,$prikey));
|
||||
// print_r(gmp_strval($s2,16));die();
|
||||
$s = $modMath->mul($s1,$s2);
|
||||
// var_dump($generator->mul($s));die();
|
||||
if ( $math->equals( $s, $zero ) ) {
|
||||
// continue;
|
||||
throw new \RuntimeException( 'Error: random number S = 0' );
|
||||
}
|
||||
return new Signature( $r, $s );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PublicKeyInterface $key
|
||||
* @param SignatureInterface $signature
|
||||
* @param \GMP $hash
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function verify( PublicKeyInterface $key, SignatureInterface $signature, \GMP $hash ): bool {
|
||||
|
||||
$generator = $key->getGenerator();
|
||||
// var_dump($generator);die();
|
||||
$n = $generator->getOrder();
|
||||
$r = $signature->getR();
|
||||
$s = $signature->getS();
|
||||
$math = $this->adapter;
|
||||
$one = gmp_init( 1, 10 );
|
||||
if ( $math->cmp( $r, $one ) < 0 || $math->cmp( $r, $math->sub( $n, $one ) ) > 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $math->cmp( $s, $one ) < 0 || $math->cmp( $s, $math->sub( $n, $one ) ) > 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 1.2.3.4 sm3 取msg,userid的 hash值,这里直接就传过来了,
|
||||
$modMath = $math->getModularArithmetic( $n );
|
||||
// 第五步 计算t=(r'+s')mod n
|
||||
$t = $modMath->add($r,$s);
|
||||
// // 第六步 计算(x1,y1) = [s]G + [t]PA
|
||||
$p1 = $generator->mul($s); // p1 = sG 是OK的与签名生成的sG一样
|
||||
$p2 = $key->getPoint()->mul($t);
|
||||
$xy = $p1->add($p2);
|
||||
// // 第七步 R=(e' + x1') 验证R==r'?
|
||||
$v = $modMath->add($hash, $xy->getX());
|
||||
|
||||
return BinaryString::constantTimeCompare( $math->toString( $v ), $math->toString( $r ) );
|
||||
}
|
||||
}
|
||||
14
pgserver/vendor/lpilp/guomi/src/overwrite.php
vendored
Normal file
14
pgserver/vendor/lpilp/guomi/src/overwrite.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
spl_autoload_register(function ($cls) {
|
||||
$map = array(
|
||||
'Mdanter\Ecc\Serializer\Util\CurveOidMapper' => __DIR__ .'/ecc/Serializer/Util/CurveOidMapper.php',
|
||||
'Mdanter\Ecc\Curves\CurveFactory'=>__DIR__ .'/ecc/Curves/CurveFactory.php',
|
||||
);
|
||||
|
||||
|
||||
if (isset($map[$cls])) {
|
||||
// echo $cls . ' loaded abc '. $map[$cls]. PHP_EOL;
|
||||
include_once $map[$cls];
|
||||
return true;
|
||||
}
|
||||
}, true, true);
|
||||
396
pgserver/vendor/lpilp/guomi/src/sm/RtSm2.php
vendored
Normal file
396
pgserver/vendor/lpilp/guomi/src/sm/RtSm2.php
vendored
Normal file
@@ -0,0 +1,396 @@
|
||||
<?php
|
||||
namespace Rtgm\sm;
|
||||
define("C1C3C2",1);
|
||||
define("C1C2C3",0);
|
||||
use Rtgm\ecc\RtEccFactory;
|
||||
use Rtgm\ecc\Sm2Signer;
|
||||
use Mdanter\Ecc\Crypto\Key\PrivateKey;
|
||||
use Mdanter\Ecc\Crypto\Key\PublicKey;
|
||||
use Mdanter\Ecc\Primitives\Point;
|
||||
use Mdanter\Ecc\Serializer\PrivateKey\PemPrivateKeySerializer;
|
||||
use Mdanter\Ecc\Serializer\PrivateKey\DerPrivateKeySerializer;
|
||||
use Mdanter\Ecc\Serializer\PublicKey\PemPublicKeySerializer;
|
||||
use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer;
|
||||
use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer;
|
||||
|
||||
use Rtgm\smecc\SM2\Sm2WithSm3;
|
||||
use Rtgm\smecc\SM2\Hex2ByteBuf;
|
||||
|
||||
class RtSm2 {
|
||||
protected $adapter = null;
|
||||
protected $generator = null;
|
||||
protected $userId = '1234567812345678';
|
||||
// 是否固定签名不随机,好处是同一段参数的签名固定,增大别人的猜测的难度,
|
||||
// 同样的key + document每次签名是一样的,如果为false则每次不一样
|
||||
protected $useDerandomizedSignatures = true;
|
||||
// 是否固定加密不随机,算法中的是否每次都用不同的中间椭圆,如果固定的话,
|
||||
// 同样的文本加密后的数据是一样的,但速度会更快一些,随机的话,每次加密出来的数据不一样
|
||||
protected $useDerandomizedEncrypt = false;
|
||||
// 输入输出的签名方式 16进制的还是base64
|
||||
protected $formatSign = 'hex';
|
||||
// 可扩展自定义多种返回签名方式
|
||||
protected $arrFormat = ['hex','base64'];
|
||||
// 加密时的中间椭圆,取任意的sm2中间椭圆都可以,useDerandomizedEncrypt = true时使用,为false时每次加密,重新生成一个
|
||||
protected $foreignKey= [
|
||||
'21fbd478026e2d668e3570e514de0d312e443d1e294c1ca785dfbfb5f74de225',
|
||||
'04e27c3780e7069bda7082a23a489d77587ce309583ed99253f66e1d9833ed1a1d0b5ce86dc6714e9974cf258589139d7b1855e8c9fa2f2c1175ee123a95a23e9b'
|
||||
];
|
||||
protected $cipher = null;
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $formatSign
|
||||
* @param boolean $randFixed 是否使用中间椭圆,使用中间椭圆的话,速度会快一些,但同样的数据的签名或加密的值就固定了
|
||||
*/
|
||||
function __construct($formatSign='hex', $randFixed = true) {
|
||||
$this->adapter = RtEccFactory::getAdapter();
|
||||
$this->generator = RtEccFactory::getSmCurves()->generatorSm2();
|
||||
if(in_array($formatSign,$this->arrFormat)){
|
||||
$this->formatSign = $formatSign;
|
||||
} else {
|
||||
$this->formatSign = 'hex';
|
||||
}
|
||||
if(!$randFixed){
|
||||
$this->useDerandomizedSignatures = false;
|
||||
$this->useDerandomizedEncrypt = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 随机生成一对16进制明文公私钥
|
||||
*/
|
||||
public function generatekey() {
|
||||
// $adapter = $this->adapter;
|
||||
$generator = $this->generator;
|
||||
//随机生成一个私钥类
|
||||
$private = $generator->createPrivateKey();
|
||||
//取出私钥16进制表示出来
|
||||
$privateKey = $this->decHex( $private->getSecret() );
|
||||
//取出公钥的椭圆点
|
||||
|
||||
$pubPoint = $private->getPublicKey()->getPoint();
|
||||
//公钥上的点x, y
|
||||
$pubX = $this->decHex( $pubPoint->getX() );
|
||||
$pubY = $this->decHex( $pubPoint->getY() );
|
||||
$publicKey = '04'.$pubX.$pubY;
|
||||
return [$privateKey, $publicKey];
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成一对PEM编码公私钥
|
||||
*/
|
||||
public function generatePemkey() {
|
||||
$adapter = $this->adapter;
|
||||
$generator = $this->generator;
|
||||
$private = $generator->createPrivateKey();
|
||||
$derSerializer = new DerPrivateKeySerializer( $adapter );
|
||||
// der包 ans1编码 1 版本号 2私钥 3 oid 4 公钥 四组数据
|
||||
// $der = $derSerializer->serialize( $private );
|
||||
$pemSerializer = new PemPrivateKeySerializer( $derSerializer );
|
||||
$privateKeyPem = $pemSerializer->serialize( $private );
|
||||
|
||||
$derPubSerializer = new DerPublicKeySerializer( $adapter );
|
||||
$pemPubSerializer = new PemPublicKeySerializer( $derPubSerializer );
|
||||
$publicKeyPem = $pemPubSerializer->serialize( $private->getPublicKey() );
|
||||
|
||||
|
||||
return [$privateKeyPem, $publicKeyPem];
|
||||
}
|
||||
/**
|
||||
* SM2 公钥加密算法
|
||||
*
|
||||
* @param string $document
|
||||
* @param string $publicKey 如提供的base64的,可使用 bin2hex(base64_decode($publicKey))
|
||||
* @return string
|
||||
*/
|
||||
public function doEncrypt($document, $publicKey, $model = C1C3C2)
|
||||
{
|
||||
$adapter = $this->adapter;
|
||||
$generator = $this->generator;
|
||||
$this->cipher = new \Rtgm\smecc\SM2\Cipher();
|
||||
$arrMsg = Hex2ByteBuf::HexStringToByteArray2(bin2hex($document));
|
||||
|
||||
list( $pubKeyX, $pubKeyY ) = $this->_getKeyXY( $publicKey );
|
||||
// $key = $this->_getPubKeyObject( $pubKeyX, $pubKeyY );
|
||||
$point = new Point( $adapter, $generator->getCurve(), gmp_init( $pubKeyX, 16 ), gmp_init( $pubKeyY, 16 ) );
|
||||
// 是否使用固定的中间椭圆加密,
|
||||
if($this->useDerandomizedEncrypt){
|
||||
$c1 = $this->cipher->initEncipher($point,$this->foreignKey);
|
||||
} else {
|
||||
$c1 = $this->cipher->initEncipher($point,null);
|
||||
}
|
||||
|
||||
// print_r($c1);
|
||||
|
||||
$arrMsg = $this->cipher->encryptBlock($arrMsg);
|
||||
$c2 = strtolower(Hex2ByteBuf::ByteArrayToHexString($arrMsg)) ;
|
||||
// print_R($c2);echo "\n";
|
||||
$c3 = strtolower(Hex2ByteBuf::ByteArrayToHexString($this->cipher->Dofinal()));
|
||||
// print_r($c1.$c3.$c2);
|
||||
if($model == C1C3C2){
|
||||
return $c1.$c3.$c2;
|
||||
} else {
|
||||
return $c1.$c2.$c3;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* SM2 私钥解密算法,
|
||||
*
|
||||
* @param string $document
|
||||
* @param string $privateKey 如提供的base64的,可使用 bin2hex(base64_decode($privateKey))
|
||||
* @param bool $trim 是否做04开头的去除,看业务返回
|
||||
* @return string
|
||||
*/
|
||||
public function doDecrypt($encryptData,$privateKey,$trim = true,$model = C1C3C2)
|
||||
{
|
||||
// $encryptData = $c1.$c3.$c2
|
||||
if(substr($encryptData,0,2)=='04' && $trim){
|
||||
$encryptData = substr($encryptData,2);
|
||||
}
|
||||
if(strlen($privateKey)==66 && substr($privateKey,0,2)=='00') {
|
||||
$privateKey = substr($privateKey,2); // 个别的key 前面带着00
|
||||
}
|
||||
$adapter = $this->adapter;
|
||||
$generator = $this->generator;
|
||||
$this->cipher = new \Rtgm\smecc\SM2\Cipher();
|
||||
$c1X = substr($encryptData,0,64);
|
||||
$c1Y = substr($encryptData,strlen($c1X),64);
|
||||
$c1Length = strlen($c1X) + strlen($c1Y);
|
||||
if($model == C1C3C2){
|
||||
$c3 = substr($encryptData,$c1Length,64);
|
||||
$c2 = substr($encryptData,$c1Length+strlen($c3));
|
||||
} else {
|
||||
$c3 = substr($encryptData,-64);
|
||||
$c2 = substr($encryptData,$c1Length,strlen($encryptData)-$c1Length-64);
|
||||
}
|
||||
|
||||
$p1 = new Point( $adapter, $generator->getCurve(), gmp_init($c1X, 16 ), gmp_init( $c1Y, 16 ) );
|
||||
$this->cipher->initDecipher($p1,$privateKey);
|
||||
|
||||
$arrMsg = Hex2ByteBuf::HexStringToByteArray2($c2);
|
||||
$arrMsg = $this->cipher->decryptBlock($arrMsg);
|
||||
$document = hex2bin(Hex2ByteBuf::ByteArrayToHexString($arrMsg));
|
||||
|
||||
$c3_ = strtolower(Hex2ByteBuf::ByteArrayToHexString($this->cipher->Dofinal()));
|
||||
$c3 = strtolower($c3);
|
||||
if($c3 == $c3_){ //hash签名相同,
|
||||
return $document;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* SM2 签名明文16进制密码, 如提供的base64的,可使用 bin2hex(base64_decode($privateKey))
|
||||
*
|
||||
*/
|
||||
public function doSign( $document, $privateKey, $userId = null ) {
|
||||
if ( empty( $userId ) ) {
|
||||
$userId = $this->userId;
|
||||
}
|
||||
$adapter = $this->adapter;
|
||||
$generator = $this->generator;
|
||||
$algorithm = 'sha256';
|
||||
$secret = gmp_init( $privateKey, 16 );
|
||||
$key = new PrivateKey( $adapter, $generator, $secret );
|
||||
return $this->_dosign( $document, $key, $adapter, $generator, $userId, $algorithm );
|
||||
}
|
||||
/**
|
||||
* SM2 签名pem密码
|
||||
*
|
||||
*/
|
||||
public function doSignOutKey( $document, $privateKeyFile, $userId = null ) {
|
||||
if ( empty( $userId ) ) {
|
||||
$userId = $this->userId;
|
||||
}
|
||||
if ( !file_exists( $privateKeyFile ) ) {
|
||||
throw new \Exception( 'privatekey file not exists' );
|
||||
}
|
||||
$adapter = $this->adapter;
|
||||
$generator = $this->generator;
|
||||
//这个sha256 只是生成随机数时用到,和主体算法无关
|
||||
$algorithm = 'sha256';
|
||||
|
||||
$pemSerializer = new PemPrivateKeySerializer( new DerPrivateKeySerializer( $adapter ) );
|
||||
$keyData = file_get_contents( $privateKeyFile );
|
||||
|
||||
$key = $pemSerializer->parse( $keyData );
|
||||
|
||||
return $this->_dosign( $document, $key, $adapter, $generator, $userId, $algorithm );
|
||||
}
|
||||
|
||||
protected function _dosign( $document, $key, $adapter,$generator, $userId, $algorithm = 'sha256' ) {
|
||||
// $publickey = $key->getPublicKey();
|
||||
|
||||
$obPoint = $key->getPublicKey()->getPoint();
|
||||
|
||||
$pubKeyX = $adapter->decHex( $obPoint->getX() );
|
||||
$pubKeyY = $adapter->decHex( $obPoint->getY() );
|
||||
|
||||
$hash = $this->_doS3Hash( $document, $pubKeyX, $pubKeyY, $generator, $userId );
|
||||
|
||||
# Derandomized signatures are not necessary, but is avoids
|
||||
# the risk of a low entropy RNG, causing accidental reuse
|
||||
# of a k value for a different message, which leaks the
|
||||
# private key.
|
||||
if ( $this->useDerandomizedSignatures ) {
|
||||
$random = \Mdanter\Ecc\Random\RandomGeneratorFactory::getHmacRandomGenerator( $key, $hash, $algorithm );
|
||||
} else {
|
||||
$random = \Mdanter\Ecc\Random\RandomGeneratorFactory::getRandomGenerator();
|
||||
}
|
||||
|
||||
$randomK = $random->generate( $generator->getOrder() );
|
||||
|
||||
$signer = new Sm2Signer( $adapter );
|
||||
$signature = $signer->sign( $key, $hash, $randomK );
|
||||
|
||||
$serializer = new DerSignatureSerializer();
|
||||
$serializedSig = $serializer->serialize( $signature );
|
||||
|
||||
if($this->formatSign == 'hex') {
|
||||
return bin2hex($serializedSig);
|
||||
} else if($this->formatSign == 'base64' ) {
|
||||
return base64_encode( $serializedSig );
|
||||
}
|
||||
//缺省 hex
|
||||
return bin2hex($serializedSig);
|
||||
}
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string $document
|
||||
* @param string $sign
|
||||
* @param string $publicKey 如提供的base64的,可使用 bin2hex(base64_decode($publicKey))
|
||||
* @param string|null $userId
|
||||
* @return bool
|
||||
*/
|
||||
public function verifySign( $document, $sign, $publicKey, $userId = null ) {
|
||||
$adapter = $this->adapter;
|
||||
$generator = $this->generator;
|
||||
if ( empty( $userId ) ) {
|
||||
$userId = $this->userId;
|
||||
}
|
||||
|
||||
if($this->formatSign == 'hex') {
|
||||
$sigData = hex2bin($sign);
|
||||
} else if($this->formatSign == 'base64' ) {
|
||||
$sigData = base64_decode( $sign );
|
||||
} else {
|
||||
$sigData = hex2bin($sign);
|
||||
}
|
||||
// Parse signature
|
||||
$sigSerializer = new DerSignatureSerializer();
|
||||
$sig = $sigSerializer->parse( $sigData );
|
||||
|
||||
// get hash
|
||||
list( $pubKeyX, $pubKeyY ) = $this->_getKeyXY( $publicKey );
|
||||
|
||||
$hash = $this->_doS3Hash( $document, $pubKeyX, $pubKeyY, $generator, $userId );
|
||||
|
||||
// get pubkey parse
|
||||
$key = $this->_getPubKeyObject( $pubKeyX, $pubKeyY );
|
||||
|
||||
$signer = new Sm2Signer( $adapter );
|
||||
return $signer->verify( $key, $sig, $hash );
|
||||
}
|
||||
|
||||
public function verifySignOutKey( $document, $sign, $publickeyFile, $userId = null ) {
|
||||
|
||||
if ( empty( $userId ) ) {
|
||||
$userId = $this->userId;
|
||||
}
|
||||
if ( !file_exists( $publickeyFile ) ) {
|
||||
throw new \Exception( 'publickey file not exists' );
|
||||
}
|
||||
$adapter = $this->adapter;
|
||||
$generator = $this->generator;
|
||||
|
||||
if($this->formatSign == 'hex') {
|
||||
$sigData = hex2bin($sign);
|
||||
} else if($this->formatSign == 'base64' ) {
|
||||
$sigData = base64_decode( $sign );
|
||||
} else {
|
||||
$sigData = hex2bin($sign);
|
||||
}
|
||||
|
||||
// Parse signature
|
||||
$sigSerializer = new DerSignatureSerializer();
|
||||
$sig = $sigSerializer->parse( $sigData );
|
||||
|
||||
// Parse public key
|
||||
$keyData = file_get_contents( $publickeyFile );
|
||||
$derSerializer = new DerPublicKeySerializer( $adapter );
|
||||
$pemSerializer = new PemPublicKeySerializer( $derSerializer );
|
||||
$key = $pemSerializer->parse( $keyData );
|
||||
|
||||
$pubKeyX = $this->decHex( $key->getPoint()->getX() );
|
||||
$pubKeyY = $this->decHex( $key->getPoint()->getY() );
|
||||
$hash = $this->_doS3Hash( $document, $pubKeyX, $pubKeyY, $generator, $userId );
|
||||
$signer = new Sm2Signer( $adapter );
|
||||
|
||||
return $signer->verify( $key, $sig, $hash );
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function _doS3Hash( $document, $pubKeyX, $pubKeyY, $generator, $userId ) {
|
||||
$hasher = new Sm2WithSm3();
|
||||
$hash = $hasher->getSm3Hash( $document, $pubKeyX, $pubKeyY, $generator, $userId );
|
||||
return gmp_init( Hex2ByteBuf::ByteArrayToHexString( $hash ), 16 );
|
||||
}
|
||||
|
||||
protected function _getKeyXY( $publicKey ) {
|
||||
if ( strlen( $publicKey ) == 128 ) {
|
||||
$pubKeyX = substr( $publicKey, 0, 64 );
|
||||
$pubKeyY = substr( $publicKey, -64 );
|
||||
} else if ( strlen( $publicKey ) == 130 && substr( $publicKey, 0, 2 ) == '04' ) {
|
||||
$pubKeyX = substr( $publicKey, 2, 64 );
|
||||
$pubKeyY = substr( $publicKey, -64 );
|
||||
} else {
|
||||
throw new \Exception( 'publickey format error' );
|
||||
}
|
||||
return [$pubKeyX, $pubKeyY];
|
||||
}
|
||||
|
||||
protected function _getPubKeyObject( $pubKeyX, $pubKeyY ) {
|
||||
$generator = $this->generator;
|
||||
// __construct( GmpMathInterface $adapter, CurveFpInterface $curve, \GMP $x, \GMP $y, \GMP $order = null, bool $infinity = false )
|
||||
$x = gmp_init( $pubKeyX, 16 );
|
||||
$y = gmp_init( $pubKeyY, 16 );
|
||||
$point = new Point( $this->adapter, $generator->getCurve(), $x, $y );
|
||||
|
||||
// __construct( GmpMathInterface $adapter, GeneratorPoint $generator, PointInterface $point )
|
||||
return new PublicKey( $this->adapter, $this->generator, $point );
|
||||
}
|
||||
|
||||
protected function _str2hex($str){
|
||||
$res = array();
|
||||
for($i=0; $i<strlen($str);$i++){
|
||||
$res[$i] = sprintf("%02x",ord($str[$i]));
|
||||
}
|
||||
return implode("",$res);
|
||||
}
|
||||
public function decHex($dec,$len=64): string
|
||||
{
|
||||
if(gettype($dec)=='string'){
|
||||
$dec = gmp_init($dec, 10);
|
||||
}
|
||||
if (gmp_cmp($dec, 0) < 0) {
|
||||
throw new \InvalidArgumentException('Unable to convert negative integer to string');
|
||||
}
|
||||
|
||||
$hex = gmp_strval($dec, 16);
|
||||
|
||||
/* if (strlen($hex) % 2 != 0) {
|
||||
$hex = '0'.$hex;
|
||||
} */
|
||||
$left = $len - strlen($hex) ;
|
||||
if($left >0){
|
||||
$hex = str_repeat('0',$left) . $hex;
|
||||
}
|
||||
|
||||
return $hex;
|
||||
}
|
||||
}
|
||||
27
pgserver/vendor/lpilp/guomi/src/sm/RtSm3.php
vendored
Normal file
27
pgserver/vendor/lpilp/guomi/src/sm/RtSm3.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace Rtgm\sm;
|
||||
|
||||
use Rtgm\smecc\SM3\SM3Digest;
|
||||
|
||||
class RtSm3 {
|
||||
public function digest($msg,$format=1){
|
||||
$md = array();
|
||||
$sm3 = new SM3Digest();
|
||||
$msgArray = unpack("C*",$msg);
|
||||
$sm3->BlockUpdate($msgArray, 1, sizeof($msgArray));
|
||||
$sm3->DoFinal($md, 0);
|
||||
if($format){
|
||||
return $this->_dec2hex($md);
|
||||
} else {
|
||||
return $md;
|
||||
}
|
||||
}
|
||||
|
||||
protected function _dec2hex($md){
|
||||
$res = array();
|
||||
for($i=0; $i<count($md);$i++){
|
||||
$res[$i] = sprintf("%02x",$md[$i]);
|
||||
}
|
||||
return implode("",$res);
|
||||
}
|
||||
}
|
||||
113
pgserver/vendor/lpilp/guomi/src/sm/RtSm4.php
vendored
Normal file
113
pgserver/vendor/lpilp/guomi/src/sm/RtSm4.php
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace Rtgm\sm;
|
||||
|
||||
/**
|
||||
* Sm4 from https://github.com/lizhichao/sm
|
||||
*/
|
||||
|
||||
use Exception;
|
||||
use Rtgm\smecc\SM4\Sm4;
|
||||
|
||||
class RtSm4
|
||||
{
|
||||
protected $sm4;
|
||||
protected $keyLen = 16;
|
||||
protected $ivLen = 16;
|
||||
|
||||
function __construct($key)
|
||||
{
|
||||
$this->sm4 = new Sm4($key);
|
||||
}
|
||||
|
||||
public function encrypt($data, $type = 'sm4', $iv = '', $formatOut = 'hex')
|
||||
{
|
||||
|
||||
if ($type != 'sm4-ecb') {
|
||||
$this->check_iv($iv);
|
||||
}
|
||||
$ret = '';
|
||||
switch ($type) {
|
||||
case 'sm4':
|
||||
case 'sm4-cbc':
|
||||
$data = $this->mystr_pad($data, $this->keyLen); //需要补齐
|
||||
$ret = $this->sm4->enDataCbc($data, $iv);
|
||||
break;
|
||||
case 'sm4-ecb':
|
||||
$data = $this->mystr_pad($data, $this->keyLen); //需要补齐
|
||||
$ret = $this->sm4->enDataEcb($data);
|
||||
break;
|
||||
case 'sm4-ctr':
|
||||
$ret = $this->sm4->enDataCtr($data, $iv);
|
||||
break;
|
||||
case 'sm4-ofb':
|
||||
$ret = $this->sm4->enDataOfb($data, $iv);
|
||||
break;
|
||||
case 'sm4-cfb':
|
||||
$ret = $this->sm4->enDataCfb($data, $iv);
|
||||
break;
|
||||
default:
|
||||
throw new Exception('bad type');
|
||||
}
|
||||
if ($formatOut == 'hex') {
|
||||
return bin2hex($ret);
|
||||
} else if ($formatOut == 'base64') {
|
||||
return base64_encode($ret);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function decrypt($data, $type = 'sm4', $iv = '', $formatInput = 'hex')
|
||||
{
|
||||
if ($type != 'sm4-ecb') {
|
||||
$this->check_iv($iv);
|
||||
}
|
||||
if ($formatInput == 'hex') {
|
||||
$data = hex2bin($data);
|
||||
} else if ($formatInput == 'base64') {
|
||||
$data = base64_decode($data);
|
||||
}
|
||||
//else is raw
|
||||
switch ($type) {
|
||||
case 'sm4':
|
||||
case 'sm4-cbc':
|
||||
$ret = $this->sm4->deDataCbc($data, $iv);
|
||||
$ret = $this->mystr_unpad($ret);
|
||||
break;
|
||||
case 'sm4-ecb':
|
||||
$ret = $this->sm4->deDataEcb($data);
|
||||
$ret = $this->mystr_unpad($ret);
|
||||
break;
|
||||
case 'sm4-ctr':
|
||||
$ret = $this->sm4->deDataCtr($data, $iv);
|
||||
break;
|
||||
case 'sm4-ofb':
|
||||
$ret = $this->sm4->deDataOfb($data, $iv);
|
||||
break;
|
||||
case 'sm4-cfb':
|
||||
$ret = $this->sm4->deDataCfb($data, $iv);
|
||||
break;
|
||||
default:
|
||||
throw new Exception('bad type');
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
//加密前补齐
|
||||
protected function mystr_pad($data, $len = 16)
|
||||
{
|
||||
$n = $len - strlen($data) % $len;
|
||||
return $data . str_repeat(chr($n), $n);
|
||||
}
|
||||
// 解密后去掉补齐
|
||||
protected function mystr_unpad($data)
|
||||
{
|
||||
$n = ord(substr($data, -1));
|
||||
return substr($data, 0, -$n);
|
||||
}
|
||||
protected function check_iv($iv)
|
||||
{
|
||||
if (strlen($iv) != $this->ivLen) {
|
||||
throw new Exception('bad iv');
|
||||
}
|
||||
}
|
||||
}
|
||||
116
pgserver/vendor/lpilp/guomi/src/smecc/SM2/Cipher.php
vendored
Normal file
116
pgserver/vendor/lpilp/guomi/src/smecc/SM2/Cipher.php
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
//
|
||||
namespace Rtgm\smecc\SM2;
|
||||
|
||||
use Rtgm\smecc\SM3\SM3Digest;
|
||||
use Rtgm\sm\RtSm2;
|
||||
|
||||
class Cipher
|
||||
{
|
||||
private $ct = 1;
|
||||
|
||||
private $p2;
|
||||
/**
|
||||
* @var SM3Digest
|
||||
*/
|
||||
private $sm3keybase;
|
||||
/**
|
||||
* @var SM3Digest
|
||||
*/
|
||||
private $sm3c3;
|
||||
|
||||
private $key = array();
|
||||
private $keyOff = 0;
|
||||
|
||||
|
||||
private function Reset() //注意,加密使用无符号的数组转换,以便与硬件相一致
|
||||
{
|
||||
$this->sm3keybase = new SM3Digest();
|
||||
$this->sm3c3 = new SM3Digest();
|
||||
|
||||
$p = array();
|
||||
|
||||
$gmp_x = $this->p2->GetX();
|
||||
$x = Hex2ByteBuf::ConvertGmp2ByteArray($gmp_x);
|
||||
$this->sm3keybase->BlockUpdate($x, 0, sizeof($x));
|
||||
$this->sm3c3->BlockUpdate($x, 0, sizeof($x));
|
||||
|
||||
$gmp_y = $this->p2->GetY();
|
||||
$y = Hex2ByteBuf::ConvertGmp2ByteArray($gmp_y);
|
||||
$this->sm3keybase->BlockUpdate($y, 0, sizeof($y));
|
||||
|
||||
$this->ct = 1;
|
||||
$this->NextKey();
|
||||
}
|
||||
public function initEncipher($userPoint, $foreignKey = null)
|
||||
{
|
||||
if (empty($foreignKey)) {
|
||||
$sm2 = new RtSm2();
|
||||
$foreignKey = $sm2->generatekey();
|
||||
}
|
||||
$foreignPriKey = $foreignKey[0];
|
||||
$foreignPubKey = $foreignKey[1];
|
||||
$this->p2 = $userPoint->mul(gmp_init($foreignPriKey, 16));
|
||||
$this->reset();
|
||||
return substr($foreignPubKey, -128);
|
||||
}
|
||||
public function initDecipher($userPoint, $privateKey)
|
||||
{
|
||||
$this->p2 = $userPoint->mul(gmp_init($privateKey, 16));
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
private function NextKey()
|
||||
{
|
||||
$sm3keycur = new SM3Digest();
|
||||
$sm3keycur->setSM3Digest($this->sm3keybase);
|
||||
$sm3keycur->Update(($this->ct >> 24 & 0x00ff));
|
||||
$sm3keycur->Update(($this->ct >> 16 & 0x00ff));
|
||||
$sm3keycur->Update(($this->ct >> 8 & 0x00ff));
|
||||
$sm3keycur->Update(($this->ct & 0x00ff));
|
||||
$sm3keycur->DoFinal($this->key, 0);
|
||||
$this->keyOff = 0;
|
||||
$this->ct++;
|
||||
}
|
||||
|
||||
public function encryptBlock($data)
|
||||
{
|
||||
$len = count($data);
|
||||
$this->sm3c3->BlockUpdate($data, 0, $len);
|
||||
// print_r($data);die();
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
if ($this->keyOff == sizeof($this->key)) {
|
||||
$this->NextKey();
|
||||
}
|
||||
|
||||
$data[$i] ^= $this->key[$this->keyOff++];
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function decryptBlock($data)
|
||||
{
|
||||
$len = count($data);
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
if ($this->keyOff == sizeof($this->key))
|
||||
$this->NextKey();
|
||||
|
||||
$data[$i] ^= $this->key[$this->keyOff++];
|
||||
}
|
||||
$this->sm3c3->BlockUpdate($data, 0, $len);
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function Dofinal()
|
||||
{
|
||||
$c3 = array();
|
||||
$gmp_p = $this->p2->GetY();
|
||||
$p = Hex2ByteBuf::ConvertGmp2ByteArray($gmp_p);
|
||||
$this->sm3c3->BlockUpdate($p, 0, sizeof($p));
|
||||
$this->sm3c3->DoFinal($c3, 0);
|
||||
$this->Reset();
|
||||
return $c3;
|
||||
}
|
||||
}
|
||||
107
pgserver/vendor/lpilp/guomi/src/smecc/SM2/Hex2ByteBuf.php
vendored
Normal file
107
pgserver/vendor/lpilp/guomi/src/smecc/SM2/Hex2ByteBuf.php
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
//
|
||||
namespace Rtgm\smecc\SM2;
|
||||
|
||||
class Hex2ByteBuf
|
||||
{
|
||||
|
||||
public static function ConvertGmp2ByteArray($GmpData)
|
||||
{
|
||||
$HexStr = gmp_strval($GmpData, 16);
|
||||
$OutBuf = array();
|
||||
$OutBuf = Hex2ByteBuf::HexStringToByteArray($HexStr);
|
||||
return $OutBuf;
|
||||
}
|
||||
|
||||
public static function ByteArrayToHexString($b, $nlen = null)
|
||||
{
|
||||
$outstring = array();
|
||||
$nlen = $nlen == null ? count($b) : 0;
|
||||
// var_dump($nlen);
|
||||
for ($n = 0; $n < $nlen; $n++) {
|
||||
$outstring[] = Hex2ByteBuf::myhex($b[$n]);
|
||||
}
|
||||
// echo (implode("x",$outstring));
|
||||
return implode("", $outstring);
|
||||
}
|
||||
|
||||
private static function myhex($indata)
|
||||
{
|
||||
$temp_1 = $indata / 16;
|
||||
if ($temp_1 < 10)
|
||||
$temp_1 = $temp_1 + 0x30;
|
||||
else
|
||||
$temp_1 = $temp_1 + 0x41 - 10;
|
||||
|
||||
$temp_2 = $indata % 16;
|
||||
if ($temp_2 < 10)
|
||||
$temp_2 = $temp_2 + 0x30;
|
||||
else
|
||||
$temp_2 = $temp_2 + 0x41 - 10;
|
||||
|
||||
return chr($temp_1) . chr($temp_2);
|
||||
}
|
||||
|
||||
public static function HexStringToByteArray($InString)
|
||||
{
|
||||
for (
|
||||
$m = strlen($InString);
|
||||
$m < 64;
|
||||
$m++
|
||||
) {
|
||||
$InString = '0' . $InString;
|
||||
}
|
||||
$g_len = 0;
|
||||
$nlen = 0;
|
||||
$n = 0;
|
||||
$i = 0;
|
||||
$temp = '';
|
||||
$nlen = strlen($InString);
|
||||
if ($nlen < 16) $g_len = 16;
|
||||
$g_len = $nlen / 2;
|
||||
|
||||
for (
|
||||
$n = 0;
|
||||
$n < $nlen;
|
||||
$n = $n + 2
|
||||
) {
|
||||
$temp = substr($InString, $n, 2);
|
||||
$temp = '0x' . $temp;
|
||||
$b[$i] = hexdec($temp);
|
||||
$i = $i + 1;
|
||||
}
|
||||
|
||||
return $b;
|
||||
}
|
||||
public static function HexStringToByteArray2($InString)
|
||||
{
|
||||
// for (
|
||||
// $m = strlen($InString);
|
||||
// $m < 64;
|
||||
// $m++
|
||||
// ) {
|
||||
// $InString = '0' . $InString;
|
||||
// }
|
||||
$g_len = 0;
|
||||
$nlen = 0;
|
||||
$n = 0;
|
||||
$i = 0;
|
||||
$temp = '';
|
||||
$nlen = strlen($InString);
|
||||
if ($nlen < 16) $g_len = 16;
|
||||
$g_len = $nlen / 2;
|
||||
|
||||
for (
|
||||
$n = 0;
|
||||
$n < $nlen;
|
||||
$n = $n + 2
|
||||
) {
|
||||
$temp = substr($InString, $n, 2);
|
||||
$temp = '0x' . $temp;
|
||||
$b[$i] = hexdec($temp);
|
||||
$i = $i + 1;
|
||||
}
|
||||
|
||||
return $b;
|
||||
}
|
||||
}
|
||||
100
pgserver/vendor/lpilp/guomi/src/smecc/SM2/Sm2Enc.php
vendored
Normal file
100
pgserver/vendor/lpilp/guomi/src/smecc/SM2/Sm2Enc.php
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
namespace Rtgm\smecc\SM2;
|
||||
|
||||
use Rtgm\smecc\SM3\SM3Digest;
|
||||
|
||||
class SM2Enc
|
||||
{
|
||||
|
||||
private const SM2_ADDBYTE = 97;//加密后的数据会增加的长度
|
||||
private const MAX_ENCLEN = 128; //最大的加密长度分组
|
||||
private const MAX_DECLEN = (self::MAX_ENCLEN + self::SM2_ADDBYTE); //最大的解密长度分组
|
||||
|
||||
/* public function SM2_EncStringBySoft($InString, $PubKeyX, $PubKeyY, $generator)
|
||||
{
|
||||
|
||||
$Kx = gmp_init($PubKeyX, 16);
|
||||
$Ky = gmp_init($PubKeyY, 16);
|
||||
$userKey = $generator->getPublicKeyFrom($Kx,$Ky,null);
|
||||
|
||||
$n = 0;
|
||||
$incount = 0;
|
||||
$outcount = 0;
|
||||
$temp_InBuf = array();
|
||||
$temp_OutBuf = array();
|
||||
$inlen = strlen($InString) + 1;
|
||||
$outlen = ($inlen / $this::MAX_ENCLEN + 1) * $this::SM2_ADDBYTE + $inlen;
|
||||
$OutBuf = array();
|
||||
$InBuf = array();
|
||||
$InBuf=unpack("C*",$InString);
|
||||
$InBuf[$inlen]=0;//这样是为了保挂与其它开发语言一致
|
||||
$ret = 0;
|
||||
$temp_inlen = 0;
|
||||
while ( $inlen > 0)
|
||||
{
|
||||
if ( $inlen > $this::MAX_ENCLEN)
|
||||
$temp_inlen = $this::MAX_ENCLEN;
|
||||
else
|
||||
$temp_inlen = $inlen;
|
||||
for ( $n = 0; $n < $temp_inlen; $n++)
|
||||
{
|
||||
$temp_InBuf[$n] = $InBuf[$incount + $n + 1];//注意,这里要加1,因为UNPACK后是从1开始
|
||||
}
|
||||
$temp_OutBuf=$this->sub_EncBufBySoft($temp_InBuf, $temp_inlen, $userKey);
|
||||
for ( $n = 0; $n < ($temp_inlen + $this::SM2_ADDBYTE); $n++)
|
||||
{
|
||||
$OutBuf[ $outcount + $n] = $temp_OutBuf[$n];
|
||||
}
|
||||
$inlen = $inlen - $this::MAX_ENCLEN;
|
||||
$incount = $incount + $this::MAX_ENCLEN;
|
||||
$outcount = $outcount + $this::MAX_DECLEN;
|
||||
}
|
||||
return Hex2ByteBuf::ByteArrayToHexString( $OutBuf, sizeof($OutBuf));
|
||||
}
|
||||
|
||||
|
||||
private function sub_EncBufBySoft($InBuf, $InBuflen, $userKey)
|
||||
{
|
||||
|
||||
$n = 0 ;
|
||||
$data = array();
|
||||
|
||||
$data = $InBuf;
|
||||
|
||||
|
||||
$cipher = new Cipher();
|
||||
$c1 = $cipher->Init_enc( $userKey);
|
||||
|
||||
$bc1[0]=4;
|
||||
$gmp_x = $c1->getPoint()->GetX();
|
||||
$x=Hex2ByteBuf::ConvertGmp2ByteArray($gmp_x);
|
||||
SM3Digest::arraycopy($x,0,$bc1,1,sizeof($x));
|
||||
|
||||
$gmp_y = $c1->getPoint()->GetY();
|
||||
$y=Hex2ByteBuf::ConvertGmp2ByteArray($gmp_y);
|
||||
SM3Digest::arraycopy($y,0,$bc1,1+32,sizeof($y));
|
||||
|
||||
$c1_len = sizeof($bc1);
|
||||
|
||||
$data=$cipher->Encrypt( $data ,$InBuflen);
|
||||
|
||||
$c3 = array();
|
||||
$c3=$cipher->Dofinal( );
|
||||
|
||||
$OutBuf=array();
|
||||
for ( $n = 0; $n < $c1_len; $n++)
|
||||
{
|
||||
|
||||
$OutBuf[$n] = $bc1[ $n];
|
||||
}
|
||||
for ( $n = 0; $n < $InBuflen; $n++)
|
||||
{
|
||||
$OutBuf[ $n + $c1_len] = $data[ $n];
|
||||
}
|
||||
for ( $n = 0; $n < 32; $n++)
|
||||
{
|
||||
$OutBuf[ $n + $c1_len + $InBuflen] = $c3[ $n];
|
||||
}
|
||||
return $OutBuf;
|
||||
} */
|
||||
}
|
||||
172
pgserver/vendor/lpilp/guomi/src/smecc/SM2/Sm2WithSm3.php
vendored
Normal file
172
pgserver/vendor/lpilp/guomi/src/smecc/SM2/Sm2WithSm3.php
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
//
|
||||
namespace Rtgm\smecc\SM2;
|
||||
|
||||
|
||||
use Rtgm\smecc\SM3\SM3Digest;
|
||||
|
||||
class Sm2WithSm3
|
||||
{
|
||||
|
||||
|
||||
private function GetZ($userId, $HexPubKeyX,$HexPubKeyY,$generator)
|
||||
{
|
||||
//$PubKeyX_gmp = gmp_init($HexPubKeyX, 16);
|
||||
// $PubKeyY_gmp = gmp_init($HexPubKeyY, 16);
|
||||
|
||||
$md = array();
|
||||
$sm3 = new SM3Digest();
|
||||
|
||||
// userId length
|
||||
|
||||
$id=unpack("C*",$userId);
|
||||
$len = sizeof($id)*8;
|
||||
$sm3->Update( ($len >> 8 & 0x00ff));
|
||||
$sm3->Update( ($len & 0x00ff));
|
||||
|
||||
// userId
|
||||
$sm3->BlockUpdate($id, 1, sizeof($id));
|
||||
|
||||
// a,b
|
||||
$gmp_a = $generator->getCurve()->GetA();
|
||||
$a=Hex2ByteBuf::ConvertGmp2ByteArray($gmp_a);
|
||||
$sm3->BlockUpdate($a, 0, sizeof($a));
|
||||
|
||||
$gmp_b = $generator->getCurve()->GetB();
|
||||
$b=Hex2ByteBuf::ConvertGmp2ByteArray($gmp_b);
|
||||
$sm3->BlockUpdate($b, 0, sizeof($b));
|
||||
// gx,gy
|
||||
$gmp_gx = $generator->GetX();
|
||||
$gx=Hex2ByteBuf::ConvertGmp2ByteArray($gmp_gx);
|
||||
$sm3->BlockUpdate($gx, 0, sizeof($gx));
|
||||
|
||||
$gmp_gy = $generator->GetY();
|
||||
$gy=Hex2ByteBuf::ConvertGmp2ByteArray($gmp_gy);
|
||||
$sm3->BlockUpdate($gy, 0, sizeof($gy));
|
||||
// x,y
|
||||
$bPubKeyX=array();
|
||||
$bPubKeyX=Hex2ByteBuf::HexStringToByteArray($HexPubKeyX);
|
||||
$sm3->BlockUpdate($bPubKeyX, 0, sizeof($bPubKeyX));
|
||||
$bPubKeyY=array();
|
||||
$bPubKeyY=Hex2ByteBuf::HexStringToByteArray($HexPubKeyY);
|
||||
$sm3->BlockUpdate($bPubKeyY, 0, sizeof($bPubKeyY));
|
||||
|
||||
$sm3->DoFinal($md, 0);
|
||||
return $md;
|
||||
|
||||
}
|
||||
|
||||
private function GetE($z, $HashMsgValue)
|
||||
{
|
||||
$md = array();
|
||||
$sm3 = new SM3Digest();
|
||||
|
||||
$sm3->BlockUpdate($z, 0, sizeof($z));
|
||||
// byte[] p = Encoding.Default.GetBytes(msg);
|
||||
// sm3.BlockUpdate(p, 0, p.Length);
|
||||
|
||||
$sm3->BlockUpdate($HashMsgValue, 0, 32);
|
||||
|
||||
$sm3->DoFinal($md, 0);
|
||||
return $md;
|
||||
|
||||
}
|
||||
|
||||
public function GetMsgHash( $msg)
|
||||
{
|
||||
$md = array();
|
||||
$sm3 = new SM3Digest();
|
||||
$msgArray=unpack("C*",$msg);
|
||||
$sm3->BlockUpdate($msgArray, 1, sizeof($msgArray));
|
||||
$sm3->DoFinal($md, 0);
|
||||
return $md;
|
||||
}
|
||||
|
||||
|
||||
private function Sm2Verify($md, $PubKeyX, $PubKeyY, $VerfiySign,$generator)
|
||||
{
|
||||
//SM2Result sm2Ret = new SM2Result();
|
||||
$InSignBuf = array();
|
||||
|
||||
$InSignBuf=Hex2ByteBuf::HexStringToByteArray($VerfiySign);
|
||||
|
||||
|
||||
$Kx = gmp_init($PubKeyX, 16);
|
||||
$Ky = gmp_init($PubKeyY, 16);
|
||||
|
||||
$PubKey = $generator->getPublicKeyFrom($Kx,$Ky,null);
|
||||
$r = gmp_init(substr($VerfiySign,0, 64), 16);
|
||||
$s = gmp_init(substr($VerfiySign,64, 64), 16);
|
||||
|
||||
$ecc_point_g=$generator->getCurve()->getPoint($generator->GetX(), $generator->GetY());
|
||||
|
||||
$Sm2Ret=$this->sub_Sm2Verify($md, $PubKey , $r, $s,$ecc_point_g,$generator);
|
||||
|
||||
if (gmp_cmp($r,$Sm2Ret)==0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
private function sub_Sm2Verify($md, $userKey,$r, $s,$ecc_point_g,$generator)
|
||||
{
|
||||
|
||||
$generator = $userKey->getGenerator();
|
||||
$ecc_n = $generator->getOrder();
|
||||
|
||||
// e_
|
||||
$md_gmp=Hex2ByteBuf::ByteArrayToHexString($md,sizeof($md));
|
||||
$e =gmp_init($md_gmp,16);
|
||||
// t
|
||||
$t=gmp_add($r,$s);
|
||||
$t=gmp_mod($t,$ecc_n);
|
||||
|
||||
$zero = gmp_init(0, 10);
|
||||
|
||||
if (gmp_cmp($t,$zero)==0)
|
||||
return null;
|
||||
|
||||
|
||||
// x1y1
|
||||
$x1y1 = $ecc_point_g->mul($s);
|
||||
$x1y1 = $x1y1->add($userKey->getPoint()->mul($t));
|
||||
|
||||
// R
|
||||
return gmp_mod(gmp_add($e,$x1y1->GetX()),$ecc_n);
|
||||
}
|
||||
|
||||
public function YtVerfiyBySoft($id, $msg, $PubKeyX, $PubKeyY, $VerfiySign,$generator)
|
||||
{
|
||||
|
||||
|
||||
$Z = array();
|
||||
$E = array();
|
||||
$MsgHashValue = array();
|
||||
|
||||
$Z = $this->GetZ($id, $PubKeyX, $PubKeyY,$generator);
|
||||
$MsgHashValue = $this->GetMsgHash($msg);
|
||||
$E = $this->GetE($Z, $MsgHashValue);
|
||||
|
||||
|
||||
|
||||
$IsVailSign = $this->Sm2Verify($E, $PubKeyX, $PubKeyY, $VerfiySign,$generator);
|
||||
return $IsVailSign;
|
||||
|
||||
}
|
||||
public function getSm3Hash($msg,$PubKeyX, $PubKeyY, $generator, $userId="1234567812345678") {
|
||||
// sm3(z+msg)
|
||||
$z = $this->GetZ($userId, $PubKeyX, $PubKeyY,$generator);
|
||||
|
||||
$md = array();
|
||||
$sm3 = new SM3Digest();
|
||||
$sm3->BlockUpdate($z, 0, sizeof($z));
|
||||
$msgArray=unpack("C*",$msg);
|
||||
$sm3->BlockUpdate($msgArray, 1, sizeof($msgArray));
|
||||
$sm3->DoFinal($md, 0);
|
||||
return $md;
|
||||
}
|
||||
|
||||
}
|
||||
112
pgserver/vendor/lpilp/guomi/src/smecc/SM3/GeneralDigest.php
vendored
Normal file
112
pgserver/vendor/lpilp/guomi/src/smecc/SM3/GeneralDigest.php
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
//
|
||||
namespace Rtgm\smecc\SM3;
|
||||
|
||||
class GeneralDigest
|
||||
{
|
||||
private const BYTE_LENGTH = 64;
|
||||
|
||||
private $xBuf=array();
|
||||
private $xBufOff;
|
||||
|
||||
private $byteCount;
|
||||
|
||||
|
||||
public function setGeneralDigest($t)
|
||||
{
|
||||
$this->arraycopy($t->xBuf, 0, $this->xBuf, 0, sizeof($t->xBuf));
|
||||
|
||||
$this->xBufOff = $t->xBufOff;
|
||||
$this->byteCount = $t->byteCount;
|
||||
}
|
||||
|
||||
public function __construct( )
|
||||
{
|
||||
$this->xBuf[0]=0;
|
||||
$this->xBuf[1]=0;
|
||||
$this->xBuf[2]=0; $this->xBuf[3]=0;
|
||||
}
|
||||
|
||||
|
||||
public function Update($input)
|
||||
{
|
||||
$this->xBuf[$this->xBufOff++] = $input;
|
||||
|
||||
if ($this->xBufOff == sizeof($this->xBuf))
|
||||
{
|
||||
$this->ProcessWord($this->xBuf, 0);
|
||||
$this->xBufOff = 0;
|
||||
}
|
||||
|
||||
$this->byteCount++;
|
||||
}
|
||||
|
||||
public function BlockUpdate(
|
||||
$input,
|
||||
$inOff,
|
||||
$length)
|
||||
{
|
||||
//
|
||||
// fill the current word
|
||||
//
|
||||
while (($this->xBufOff != 0) && ($length > 0))
|
||||
{
|
||||
$this->Update($input[$inOff]);
|
||||
$inOff++;
|
||||
$length--;
|
||||
}
|
||||
|
||||
//
|
||||
// process whole words.
|
||||
//
|
||||
while ($length > sizeof($this->xBuf))
|
||||
{
|
||||
$this->ProcessWord($input, $inOff);
|
||||
|
||||
$inOff += sizeof($this->xBuf);
|
||||
$length -= sizeof($this->xBuf);
|
||||
$this->byteCount += sizeof($this->xBuf);
|
||||
}
|
||||
|
||||
//
|
||||
// load in the remainder.
|
||||
//
|
||||
while ($length > 0)
|
||||
{
|
||||
$this->Update($input[$inOff]);
|
||||
|
||||
$inOff++;
|
||||
$length--;
|
||||
}
|
||||
}
|
||||
|
||||
public function Finish()
|
||||
{
|
||||
// $bitLength = ($this->byteCount << 3);
|
||||
$bitLength = $this->LeftRotateLong($this->byteCount , 3);
|
||||
//
|
||||
// add the pad bytes.
|
||||
//
|
||||
$this->Update(128);
|
||||
|
||||
while ($this->xBufOff != 0) $this->Update(0);
|
||||
$this->ProcessLength($bitLength);
|
||||
$this->ProcessBlock();
|
||||
}
|
||||
|
||||
public function Reset()
|
||||
{
|
||||
$this->byteCount = 0;
|
||||
$this->xBufOff = 0;
|
||||
$this->xBuf[0]=0;
|
||||
$this->xBuf[1]=0;
|
||||
$this->xBuf[2]=0; $this->xBuf[3]=0;
|
||||
}
|
||||
|
||||
public function GetByteLength():int
|
||||
{
|
||||
return $this::BYTE_LENGTH;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
348
pgserver/vendor/lpilp/guomi/src/smecc/SM3/SM3Digest.php
vendored
Normal file
348
pgserver/vendor/lpilp/guomi/src/smecc/SM3/SM3Digest.php
vendored
Normal file
@@ -0,0 +1,348 @@
|
||||
<?php
|
||||
//declare(strict_types=1);
|
||||
namespace Rtgm\smecc\SM3;
|
||||
|
||||
use Rtgm\smecc\SM3\GeneralDigest;
|
||||
|
||||
class SM3Digest extends GeneralDigest
|
||||
{
|
||||
public static $AlgorithmName="SM3";
|
||||
|
||||
private const DIGEST_LENGTH = 32;
|
||||
|
||||
public function GetDigestSize():int
|
||||
{
|
||||
return $this::DIGEST_LENGTH;
|
||||
}
|
||||
|
||||
|
||||
private static $v0 = array(0x7380166f, 0x4914b2b9, 0x172442d7, -628488704, -1452330820, 0x163138aa,-477237683, -1325724082);
|
||||
|
||||
private $v = array(0, 0, 0, 0, 0, 0, 0, 0);
|
||||
private $v_ = array(0, 0, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
private static $X0 = array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
private $X = array();
|
||||
private $XOff;
|
||||
|
||||
private $T_00_15 = 0x79cc4519;
|
||||
private $T_16_63 = 0x7a879d8a;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
// parent::$gSM3Digest=$this;
|
||||
$this->Reset();
|
||||
}
|
||||
|
||||
|
||||
public function setSM3Digest($t)
|
||||
{
|
||||
parent::setGeneralDigest($t);
|
||||
$this->arraycopy($t->X, 0, $this->X, 0, sizeof($t->X));
|
||||
$this->xOff = $t->xOff;
|
||||
$this->arraycopy($t->v, 0, $this->v, 0, sizeof($t->v));
|
||||
}
|
||||
|
||||
public function Reset()
|
||||
{
|
||||
parent::Reset();
|
||||
|
||||
$this->arraycopy(SM3Digest::$v0, 0, $this->v, 0, sizeof(SM3Digest::$v0));
|
||||
|
||||
$this->xOff = 0;
|
||||
$this->arraycopy(SM3Digest::$X0, 0, $this->X, 0, sizeof(SM3Digest::$X0));
|
||||
}
|
||||
|
||||
public static function arraycopy($InBuf,$InBufPos,&$OutBuf,$OutBufPos,$Len)
|
||||
{
|
||||
for( $n = 0 ;$n< $Len;$n++)
|
||||
{
|
||||
$OutBuf[$n + $OutBufPos] =$InBuf[$n+$InBufPos];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function ProcessBlock()
|
||||
{
|
||||
$ww = $this->X;
|
||||
$ww_ = array();
|
||||
|
||||
for ($i = 16; $i < 68; $i++)
|
||||
{
|
||||
$ww[$i] = $this->P1( $ww[ $i - 16] ^ $ww[$i - 9] ^ ($this->ROTATE($ww[$i - 3], 15))) ^ ($this->ROTATE($ww[$i - 13], 7)) ^ $ww[$i - 6];
|
||||
}
|
||||
|
||||
for ($i = 0; $i < 64; $i++)
|
||||
{
|
||||
$ww_[$i] = $ww[$i] ^ $ww[$i + 4];
|
||||
}
|
||||
|
||||
$vv = $this->v;
|
||||
$vv_ = $this->v_;
|
||||
|
||||
$this->arraycopy($vv, 0, $vv_, 0, sizeof($vv));
|
||||
|
||||
// int SS1, SS2, TT1, TT2, aaa;
|
||||
for ($i = 0; $i < 16; $i++)
|
||||
{
|
||||
$aaa = $this->ROTATE($vv_[0], 12);
|
||||
$SS1 = $this->MyAdd($aaa , $vv_[4]);
|
||||
$SS1 = $this->MyAdd($SS1, $this->ROTATE($this->T_00_15, $i));
|
||||
$SS1 = $this->ROTATE($SS1, 7);
|
||||
$SS2 = $SS1 ^ $aaa;
|
||||
|
||||
$TT1=$this->FF_00_15($vv_[0], $vv_[1], $vv_[2]);
|
||||
$TT1=$this->MyAdd($TT1, $vv_[3]);
|
||||
$TT1=$this->MyAdd($TT1, $SS2);
|
||||
$TT1=$this->MyAdd($TT1, $ww_[$i]);
|
||||
|
||||
$TT2=$this->GG_00_15($vv_[4], $vv_[5], $vv_[6]);
|
||||
$TT2=$this->MyAdd($TT2, $vv_[7]);
|
||||
$TT2=$this->MyAdd($TT2, $SS1);
|
||||
$TT2=$this->MyAdd($TT2, $ww[$i]);
|
||||
|
||||
$vv_[3] = $vv_[2];
|
||||
$vv_[2] = $this->ROTATE($vv_[1], 9);
|
||||
$vv_[1] = $vv_[0];
|
||||
$vv_[0] = $TT1;
|
||||
$vv_[7] = $vv_[6];
|
||||
$vv_[6] = $this->ROTATE($vv_[5], 19);
|
||||
$vv_[5] = $vv_[4];
|
||||
$vv_[4] = $this->P0($TT2);
|
||||
}
|
||||
for ($i = 16; $i < 64; $i++)
|
||||
{
|
||||
|
||||
$aaa = $this->ROTATE($vv_[0], 12);
|
||||
$SS1 = $this->MyAdd($aaa , $vv_[4]);
|
||||
$z= $this->ROTATE($this->T_16_63, $i);
|
||||
$SS1 = $this->MyAdd( $SS1, $this->ROTATE($this->T_16_63, $i));
|
||||
$SS1 = $this->ROTATE($SS1, 7);
|
||||
$SS2 = $SS1 ^ $aaa;
|
||||
|
||||
$TT1 = $this->MyAdd($this->FF_16_63($vv_[0], $vv_[1], $vv_[2]) , $vv_[3]);
|
||||
$TT1 = $this->MyAdd( $TT1, $SS2);
|
||||
$TT1 = $this->MyAdd( $TT1, $ww_[$i]);
|
||||
|
||||
$TT2 = $this->MyAdd($this->GG_16_63($vv_[4], $vv_[5], $vv_[6]) , $vv_[7]);
|
||||
$TT2 = $this->MyAdd( $TT2, $SS1);
|
||||
$TT2 = $this->MyAdd($TT2 , $ww[$i]);
|
||||
$vv_[3] = $vv_[2];
|
||||
$vv_[2] = $this->ROTATE($vv_[1], 9);
|
||||
$vv_[1] = $vv_[0];
|
||||
$vv_[0] = $TT1;
|
||||
$vv_[7] = $vv_[6];
|
||||
$vv_[6] = $this->ROTATE($vv_[5], 19);
|
||||
$vv_[5] = $vv_[4];
|
||||
$vv_[4] = $this->P0($TT2);
|
||||
}
|
||||
for ($i = 0; $i < 8; $i++)
|
||||
{
|
||||
$vv[$i] ^= $vv_[$i];
|
||||
}
|
||||
$this->v=$vv;
|
||||
$this->v_=$vv_;
|
||||
|
||||
// Reset
|
||||
$this->xOff = 0;
|
||||
$this->arraycopy(SM3Digest::$X0, 0, $this->X, 0, sizeof(SM3Digest::$X0));
|
||||
}
|
||||
|
||||
public function ProcessWord($in_Renamed, $inOff)
|
||||
{
|
||||
|
||||
$n = $this->LeftRotateLong($in_Renamed[$inOff] , 24);
|
||||
$n |= $this->LeftRotateLong(($in_Renamed[++$inOff] & 0xff) , 16);
|
||||
$n |= $this->LeftRotateLong(($in_Renamed[++$inOff] & 0xff) , 8);
|
||||
$n |= ($in_Renamed[++$inOff] & 0xff);
|
||||
|
||||
$this->X[$this->xOff] = $n;
|
||||
|
||||
if (++$this->xOff == 16)
|
||||
{
|
||||
$this->ProcessBlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function ProcessLength($bitLength)
|
||||
{
|
||||
if ($this->xOff > 14)
|
||||
{
|
||||
$this->ProcessBlock();
|
||||
}
|
||||
|
||||
$this->X[14] = ($this->RightRotateLong($bitLength, 32));
|
||||
$this->X[15] = ($bitLength & 0xffffffff);
|
||||
}
|
||||
|
||||
public function IntToBigEndian($n, &$bs, $off)
|
||||
{
|
||||
$bs[$off] = ($this->RightRotateLong($n, 24)) & 0xff;
|
||||
$bs[++$off] = ($this->RightRotateLong($n, 16)) & 0xff;
|
||||
$bs[++$off] = ($this->RightRotateLong($n, 8)) & 0xff;
|
||||
$bs[++$off] = ($n) & 0xff ;
|
||||
}
|
||||
|
||||
public function DoFinal(&$out_Renamed, $outOff):int
|
||||
{
|
||||
$this->Finish();
|
||||
|
||||
for ($i = 0; $i < 8; $i++)
|
||||
{
|
||||
$this->IntToBigEndian($this->v[$i], $out_Renamed, $outOff + $i * 4);
|
||||
}
|
||||
|
||||
$this->Reset();
|
||||
|
||||
return $this::DIGEST_LENGTH;
|
||||
}
|
||||
|
||||
private function HandleSign($lValue)
|
||||
{
|
||||
$lValue = $lValue & 0xFFFFFFFF;
|
||||
if($lValue>=0x80000000)
|
||||
{
|
||||
$lValue=$lValue-(0xffffffff+1);
|
||||
}
|
||||
return $lValue;
|
||||
}
|
||||
|
||||
private function MyAdd($A,$B)
|
||||
{
|
||||
$lValue=$this->HandleSign($A) + $this->HandleSign($B);
|
||||
|
||||
|
||||
return $this->HandleSign($lValue);
|
||||
}
|
||||
|
||||
public function LeftRotateLong($lValue, $lBits )
|
||||
{
|
||||
$lBits = $lBits % 32;
|
||||
$lValue=$lValue<< $lBits;
|
||||
$lValue=$lValue & 0xffffffff;
|
||||
if($lValue>=0x80000000)
|
||||
{
|
||||
$lValue=$lValue-(0xffffffff+1);
|
||||
}
|
||||
return $lValue;
|
||||
/* $lngSign=0; $intI=0;
|
||||
$mValue=0;
|
||||
|
||||
$lBits = $lBits % 32;
|
||||
$mValue = $lValue;
|
||||
if($lBits == 0) return $mValue;
|
||||
|
||||
For ($intI = 1 ;$intI<= $lBits;$intI++)
|
||||
{
|
||||
$lngSign = $mValue & 0x40000000;
|
||||
$mValue = ($mValue & 0x3FFFFFFF) * 2;
|
||||
|
||||
if($lngSign & 0x40000000)
|
||||
$mValue = $mValue | 0x80000000;
|
||||
}
|
||||
|
||||
return $mValue;*/
|
||||
}
|
||||
|
||||
|
||||
private function RightRotateLong($lValue , $lBits)
|
||||
{
|
||||
$lngSign=0;$intI=0;
|
||||
$mValue =0;
|
||||
|
||||
$mValue = $lValue;
|
||||
// $lBits = $lBits % 32;
|
||||
|
||||
if( $lBits == 0 )
|
||||
{
|
||||
return $mValue ;
|
||||
}
|
||||
|
||||
if ($lValue >= 0)
|
||||
{
|
||||
if($lBits<0) $lBits= 32+ $lBits;
|
||||
$r = $lValue >> $lBits;
|
||||
}
|
||||
else
|
||||
{
|
||||
$t=~$lBits;
|
||||
if($t<0) $t= 32+ $t;
|
||||
// $t = $t % 32;
|
||||
$r= ($lValue >> $lBits) + (2 << $t);
|
||||
}
|
||||
return $r;
|
||||
|
||||
/* For ($intI = 1 ;$intI<= $lBits;$intI++)
|
||||
{
|
||||
$lngSign = $mValue & 0x80000000;
|
||||
$mValue = ($mValue & 0x7FFFFFFF) / 2;
|
||||
if ($lngSign)
|
||||
$mValue = $mValue | 0x40000000;
|
||||
}
|
||||
return $mValue;*/
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private function FFj($X, $Y, $Z, $j) :int
|
||||
{
|
||||
if($j>=0 && $j<=15) {
|
||||
return $this->FF_00_15($X, $Y, $Z);
|
||||
} else {
|
||||
return $this->FF_16_63($X, $Y, $Z);
|
||||
}
|
||||
}
|
||||
private function GGj($X, $Y, $Z, $j) :int
|
||||
{
|
||||
if($j>=0 && $j<=15) {
|
||||
return $this->GG_00_15($X, $Y, $Z);
|
||||
} else {
|
||||
return $this->GG_16_63($X, $Y, $Z);
|
||||
}
|
||||
}
|
||||
|
||||
private function ROTATE($X, $n):int
|
||||
{
|
||||
// $r=($this->RightRotateLong($X, (32 - $n)));
|
||||
//$r1=$this->LeftRotateLong($X , $n);
|
||||
// $r2=($X << $n);
|
||||
return $this->LeftRotateLong($X , $n) | ($this->RightRotateLong($X, (32 - $n)));
|
||||
}
|
||||
|
||||
private function P0($X):int
|
||||
{
|
||||
$a=$this->ROTATE(($X), 9);
|
||||
$b= $this->ROTATE(($X), 17);
|
||||
return (($X) ^ $this->ROTATE(($X), 9) ^ $this->ROTATE(($X), 17));
|
||||
}
|
||||
|
||||
private function P1($X):int
|
||||
{
|
||||
return (($X) ^ $this->ROTATE(($X), 15) ^ $this->ROTATE(($X), 23));
|
||||
}
|
||||
|
||||
private static function FF_00_15($X, $Y, $Z):int
|
||||
{
|
||||
return ($X ^ $Y ^ $Z);
|
||||
}
|
||||
|
||||
private static function FF_16_63($X, $Y, $Z):int
|
||||
{
|
||||
return (($X & $Y) | ($X & $Z) | ($Y & $Z));
|
||||
}
|
||||
|
||||
private static function GG_00_15($X, $Y, $Z):int
|
||||
{
|
||||
return ($X ^ $Y ^ $Z);
|
||||
}
|
||||
|
||||
private static function GG_16_63($X, $Y, $Z):int
|
||||
{
|
||||
return (($X & $Y) | (~ $X & $Z));
|
||||
}
|
||||
}
|
||||
349
pgserver/vendor/lpilp/guomi/src/smecc/SM4/Sm4.php
vendored
Normal file
349
pgserver/vendor/lpilp/guomi/src/smecc/SM4/Sm4.php
vendored
Normal file
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
/**
|
||||
* source: https://github.com/lizhichao/sm
|
||||
*/
|
||||
namespace Rtgm\smecc\SM4;
|
||||
class Sm4
|
||||
{
|
||||
private $ck = [
|
||||
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
|
||||
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
|
||||
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
|
||||
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
|
||||
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
|
||||
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
|
||||
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
|
||||
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
|
||||
];
|
||||
|
||||
private $Sbox = [
|
||||
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
|
||||
0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
|
||||
0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
|
||||
0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
|
||||
0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
|
||||
0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
|
||||
0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
|
||||
0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
|
||||
0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
|
||||
0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
|
||||
0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
|
||||
0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
|
||||
0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
|
||||
0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
|
||||
0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
|
||||
0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
|
||||
];
|
||||
|
||||
private $fk = [0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC];
|
||||
|
||||
private $rk = [];
|
||||
|
||||
private $b = '';
|
||||
|
||||
private $len = 16;
|
||||
|
||||
|
||||
/**
|
||||
* Sm4 constructor.
|
||||
* @param string $key 秘钥长度16位
|
||||
* @param string $b 不是16的倍数 需要的补码
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct($key, $b = ' ')
|
||||
{
|
||||
$this->ck16($key);
|
||||
$this->crk($key);
|
||||
}
|
||||
|
||||
private function dd(&$data)
|
||||
{
|
||||
$n = strlen($data) % $this->len;
|
||||
$data = $data . str_repeat($this->b, $n);
|
||||
}
|
||||
|
||||
private function ck16($str)
|
||||
{
|
||||
if (strlen($str) !== $this->len) {
|
||||
throw new \Exception('秘钥长度为16位');
|
||||
}
|
||||
}
|
||||
|
||||
private function add($v)
|
||||
{
|
||||
$arr = unpack('N*', $v);
|
||||
$max = 0xffffffff;
|
||||
$j = 1;
|
||||
for ($i = 4; $i > 0; $i--) {
|
||||
if ($arr[$i] > $max - $j) {
|
||||
$j = 1;
|
||||
$arr[$i] = 0;
|
||||
} else {
|
||||
$arr[$i] += $j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return pack('N*', ...$arr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str 加密字符串
|
||||
* @param string $iv 初始化字符串16位
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function deDataCtr($str, $iv)
|
||||
{
|
||||
return $this->enDataCtr($str, $iv);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str 加密字符串
|
||||
* @param string $iv 初始化字符串16位
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function enDataCtr($str, $iv)
|
||||
{
|
||||
$this->ck16($iv);
|
||||
$r = '';
|
||||
$this->dd($str);
|
||||
$l = strlen($str) / $this->len;
|
||||
for ($i = 0; $i < $l; $i++) {
|
||||
$s = substr($str, $i * $this->len, $this->len);
|
||||
$tr = [];
|
||||
$this->encode(array_values(unpack('N*', $iv)), $tr);
|
||||
$s1 = pack('N*', ...$tr);
|
||||
$s1 = $s1 ^ $s;
|
||||
$iv = $this->add($iv);
|
||||
$r .= $s1;
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $str 加密字符串
|
||||
* @param string $iv 初始化字符串16位
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function enDataOfb($str, $iv)
|
||||
{
|
||||
$this->ck16($iv);
|
||||
$r = '';
|
||||
$this->dd($str);
|
||||
$l = strlen($str) / $this->len;
|
||||
for ($i = 0; $i < $l; $i++) {
|
||||
$s = substr($str, $i * $this->len, $this->len);
|
||||
$tr = [];
|
||||
$this->encode(array_values(unpack('N*', $iv)), $tr);
|
||||
$iv = pack('N*', ...$tr);
|
||||
$s1 = $s ^ $iv;
|
||||
$r .= $s1;
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str 加密字符串
|
||||
* @param string $iv 初始化字符串16位
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function deDataOfb($str, $iv)
|
||||
{
|
||||
return $this->enDataOfb($str, $iv);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str 加密字符串
|
||||
* @param string $iv 初始化字符串16位
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function deDataCfb($str, $iv)
|
||||
{
|
||||
$this->ck16($iv);
|
||||
$r = '';
|
||||
$this->dd($str);
|
||||
$l = strlen($str) / $this->len;
|
||||
for ($i = 0; $i < $l; $i++) {
|
||||
$s = substr($str, $i * $this->len, $this->len);
|
||||
$tr = [];
|
||||
$this->encode(array_values(unpack('N*', $iv)), $tr);
|
||||
$s1 = pack('N*', ...$tr);
|
||||
$s1 = $s ^ $s1;
|
||||
$iv = $s;
|
||||
$r .= $s1;
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str 加密字符串
|
||||
* @param string $iv 初始化字符串16位
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function enDataCfb($str, $iv)
|
||||
{
|
||||
$this->ck16($iv);
|
||||
$r = '';
|
||||
$this->dd($str);
|
||||
$l = strlen($str) / $this->len;
|
||||
for ($i = 0; $i < $l; $i++) {
|
||||
$s = substr($str, $i * $this->len, $this->len);
|
||||
$tr = [];
|
||||
$this->encode(array_values(unpack('N*', $iv)), $tr);
|
||||
$s1 = pack('N*', ...$tr);
|
||||
$iv = $s ^ $s1;
|
||||
$r .= $iv;
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $str 加密字符串
|
||||
* @param string $iv 初始化字符串16位
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function enDataCbc($str, $iv)
|
||||
{
|
||||
$this->ck16($iv);
|
||||
$r = '';
|
||||
$this->dd($str);
|
||||
$l = strlen($str) / $this->len;
|
||||
for ($i = 0; $i < $l; $i++) {
|
||||
$s = substr($str, $i * $this->len, $this->len);
|
||||
$s = $iv ^ $s;
|
||||
$tr = [];
|
||||
$this->encode(array_values(unpack('N*', $s)), $tr);
|
||||
$iv = pack('N*', ...$tr);
|
||||
$r .= $iv;
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str 加密字符串
|
||||
* @param string $iv 初始化字符串16位
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function deDataCbc($str, $iv)
|
||||
{
|
||||
$this->ck16($iv);
|
||||
$r = '';
|
||||
$this->dd($str);
|
||||
$l = strlen($str) / $this->len;
|
||||
for ($i = 0; $i < $l; $i++) {
|
||||
$s = substr($str, $i * $this->len, $this->len);
|
||||
$tr = [];
|
||||
$this->decode(array_values(unpack('N*', $s)), $tr);
|
||||
$s1 = pack('N*', ...$tr);
|
||||
$s1 = $iv ^ $s1;
|
||||
$iv = $s;
|
||||
$r .= $s1;
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $str 加密字符串
|
||||
* @return string
|
||||
*/
|
||||
public function enDataEcb($str)
|
||||
{
|
||||
$r = [];
|
||||
$this->dd($str);
|
||||
$ar = unpack('N*', $str);
|
||||
do {
|
||||
$this->encode([current($ar), next($ar), next($ar), next($ar)], $r);
|
||||
} while (next($ar));
|
||||
return pack('N*', ...$r);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str 解密字符串
|
||||
* @return string
|
||||
*/
|
||||
public function deDataEcb($str)
|
||||
{
|
||||
$r = [];
|
||||
$this->dd($str);
|
||||
$ar = unpack('N*', $str);
|
||||
do {
|
||||
$this->decode([current($ar), next($ar), next($ar), next($ar)], $r);
|
||||
} while (next($ar));
|
||||
return pack('N*', ...$r);
|
||||
}
|
||||
|
||||
private function encode($ar, &$r)
|
||||
{
|
||||
for ($i = 0; $i < 32; $i++) {
|
||||
$ar[$i + 4] = $this->f($ar[$i], $ar[$i + 1], $ar[$i + 2], $ar[$i + 3], $this->rk[$i]);
|
||||
}
|
||||
$r[] = $ar[35];
|
||||
$r[] = $ar[34];
|
||||
$r[] = $ar[33];
|
||||
$r[] = $ar[32];
|
||||
}
|
||||
|
||||
private function decode($ar, &$r)
|
||||
{
|
||||
for ($i = 0; $i < 32; $i++) {
|
||||
$ar[$i + 4] = $this->f($ar[$i], $ar[$i + 1], $ar[$i + 2], $ar[$i + 3], $this->rk[31 - $i]);
|
||||
}
|
||||
$r[] = $ar[35];
|
||||
$r[] = $ar[34];
|
||||
$r[] = $ar[33];
|
||||
$r[] = $ar[32];
|
||||
}
|
||||
|
||||
private function crk($key)
|
||||
{
|
||||
$keys = array_values(unpack('N*', $key));
|
||||
$keys = [
|
||||
$keys[0] ^ $this->fk[0],
|
||||
$keys[1] ^ $this->fk[1],
|
||||
$keys[2] ^ $this->fk[2],
|
||||
$keys[3] ^ $this->fk[3]
|
||||
];
|
||||
for ($i = 0; $i < 32; $i++) {
|
||||
$this->rk[] = $keys[] = $keys[$i] ^ $this->t1($keys[$i + 1] ^ $keys[$i + 2] ^ $keys[$i + 3] ^ $this->ck[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
private function lm($a, $n)
|
||||
{
|
||||
return ($a >> (32 - $n) | (($a << $n) & 0xffffffff));
|
||||
}
|
||||
|
||||
private function f($x0, $x1, $x2, $x3, $r)
|
||||
{
|
||||
return $x0 ^ $this->t($x1 ^ $x2 ^ $x3 ^ $r);
|
||||
}
|
||||
|
||||
private function s($n)
|
||||
{
|
||||
return $this->Sbox[($n & 0xff)] | $this->Sbox[(($n >> 8) & 0xff)] << 8 | $this->Sbox[(($n >> 16) & 0xff)] << 16 | $this->Sbox[(($n >> 24) & 0xff)] << 24;
|
||||
}
|
||||
|
||||
private function t($n)
|
||||
{
|
||||
$b = $this->s($n);
|
||||
return $b ^ $this->lm($b, 2) ^ $this->lm($b, 10) ^ $this->lm($b, 18) ^ $this->lm($b, 24);
|
||||
}
|
||||
|
||||
private function t1($n)
|
||||
{
|
||||
$b = $this->s($n);
|
||||
return $b ^ $this->lm($b, 13) ^ $this->lm($b, 23);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
2
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/README.md
vendored
Normal file
2
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/README.md
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# sm
|
||||
国密sm3,sm4 ECB加密源码
|
||||
196
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/SM3.php
vendored
Normal file
196
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/SM3.php
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
namespace icequeen\sm\smecc\SM4;
|
||||
|
||||
|
||||
use ErrorException;
|
||||
use Rtgm\smecc\SM4\handler\ExtendedCompression;
|
||||
use Rtgm\smecc\SM4\libs\WordConversion;
|
||||
use Rtgm\smecc\SM4\types\BitString;
|
||||
|
||||
/**
|
||||
* 入口类
|
||||
* Class Sm3
|
||||
*
|
||||
* @package SM3
|
||||
* @error_code 90xxx
|
||||
*/
|
||||
class SM3 implements \ArrayAccess
|
||||
{
|
||||
/** @var string 初始值常数 */
|
||||
const IV = '7380166f4914b2b9172442d7da8a0600a96f30bc163138aae38dee4db0fb0e4e';
|
||||
|
||||
/** @var string 消息(加密前的结果) */
|
||||
private $message = '';
|
||||
/** @var string 杂凑值(加密后的结果) */
|
||||
private $hash_value = '';
|
||||
|
||||
/**
|
||||
* 实例化时直接调用将参数传给主方法
|
||||
* Sm3 constructor.
|
||||
*
|
||||
* @param $message string|mixed 传入的消息
|
||||
*
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public function __construct($message)
|
||||
{
|
||||
// 输入验证
|
||||
if (is_int($message)) {
|
||||
$message = (string)$message;
|
||||
}
|
||||
if (empty($message)) {
|
||||
$message = '';
|
||||
}
|
||||
if (!is_string($message)) {
|
||||
throw new ErrorException('参数类型必须为string,请检查后重新输入', 90001);
|
||||
}
|
||||
|
||||
/** @var string message 消息 */
|
||||
$this->message = $message;
|
||||
/** @var string hash_value 杂凑值 */
|
||||
$this->hash_value = $this->sm3();
|
||||
}
|
||||
|
||||
/**
|
||||
* 主方法
|
||||
*
|
||||
* @return string
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
private function sm3()
|
||||
{
|
||||
/** @var string $m 转化后的消息(二进制码) */
|
||||
// $json = json_encode($this->message);
|
||||
$m = new BitString($this->message, false);
|
||||
//var_dump($m);die(); //11010010 10111011
|
||||
// 一、填充
|
||||
$l = strlen($m);
|
||||
|
||||
// 满足l + 1 + k ≡ 448mod512 的最小的非负整数
|
||||
$k = $l % 512;
|
||||
$k = $k + 64 >= 512
|
||||
? 512 - ($k % 448) - 1
|
||||
: 512 - 64 - $k - 1;
|
||||
|
||||
$bin_l = new BitString($l);
|
||||
// 填充后的消息
|
||||
$m_fill = new BitString(
|
||||
$m # 原始消息m
|
||||
. '1' # 拼个1
|
||||
. str_pad('', $k, '0') # 拼上k个比特的0
|
||||
. (
|
||||
strlen($bin_l) >= 64
|
||||
? substr($bin_l, 0, 64)
|
||||
: str_pad($bin_l, 64, '0', STR_PAD_LEFT)
|
||||
) # 64比特,l的二进制表示
|
||||
);
|
||||
// 二、迭代压缩
|
||||
// 迭代过程
|
||||
$B = str_split($m_fill, 512);
|
||||
/** @var int $n m'可分为的组数 */
|
||||
$n = ($l + $k + 65) / 512;
|
||||
if (count($B) !== $n) {
|
||||
throw new ErrorException();
|
||||
}
|
||||
|
||||
$V = array(
|
||||
WordConversion::hex2bin(self::IV),
|
||||
);
|
||||
$extended = new ExtendedCompression();
|
||||
foreach ($B as $key => $Bi) {
|
||||
// print_r($Bi."\n"."====== $key ========\n".strlen($Bi)."\n");
|
||||
$V[$key + 1] = $extended->CF($V[$key], $Bi)->getBitString();
|
||||
}
|
||||
|
||||
krsort($V);
|
||||
reset($V);
|
||||
$binary = current($V);
|
||||
$rt = WordConversion::bin2hex($binary);
|
||||
return $rt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 方便直接输出实例化的对象
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->hash_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a offset exists
|
||||
*
|
||||
* @link https://php.net/manual/en/arrayaccess.offsetexists.php
|
||||
*
|
||||
* @param mixed $offset <p>
|
||||
* An offset to check for.
|
||||
* </p>
|
||||
*
|
||||
* @return bool true on success or false on failure.
|
||||
* </p>
|
||||
* <p>
|
||||
* The return value will be casted to boolean if non-boolean was returned.
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->hash_value[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to retrieve
|
||||
*
|
||||
* @link https://php.net/manual/en/arrayaccess.offsetget.php
|
||||
*
|
||||
* @param mixed $offset <p>
|
||||
* The offset to retrieve.
|
||||
* </p>
|
||||
*
|
||||
* @return mixed Can return all value types.
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->hash_value[$offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to set
|
||||
*
|
||||
* @link https://php.net/manual/en/arrayaccess.offsetset.php
|
||||
*
|
||||
* @param mixed $offset <p>
|
||||
* The offset to assign the value to.
|
||||
* </p>
|
||||
* @param mixed $value <p>
|
||||
* The value to set.
|
||||
* </p>
|
||||
*
|
||||
* @return \SM3\SM3
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->hash_value[$offset] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to unset
|
||||
*
|
||||
* @link https://php.net/manual/en/arrayaccess.offsetunset.php
|
||||
*
|
||||
* @param mixed $offset <p>
|
||||
* The offset to unset.
|
||||
* </p>
|
||||
*
|
||||
* @return void
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->hash_value[$offset]);
|
||||
}
|
||||
}
|
||||
196
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/Sm4.php
vendored
Normal file
196
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/Sm4.php
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
namespace Rtgm\smecc\SM4;
|
||||
|
||||
class Sm4
|
||||
{
|
||||
static $SM4_CK = array(
|
||||
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
|
||||
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
|
||||
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
|
||||
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
|
||||
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
|
||||
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
|
||||
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
|
||||
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
|
||||
);
|
||||
|
||||
static $SM4_SBOX = array(
|
||||
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
|
||||
0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
|
||||
0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
|
||||
0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
|
||||
0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
|
||||
0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
|
||||
0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
|
||||
0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
|
||||
0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
|
||||
0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
|
||||
0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
|
||||
0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
|
||||
0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
|
||||
0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
|
||||
0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
|
||||
0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
|
||||
);
|
||||
|
||||
static $SM4_FK = array(0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC);
|
||||
|
||||
private $_rk = array();
|
||||
private $_block_size = 16;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (PHP_INT_SIZE < 8) {
|
||||
throw new \Exception('64bit OS supported only');
|
||||
}
|
||||
if (version_compare(PHP_VERSION, "7.0", "<")) {
|
||||
throw new \Exception('php version 7.0 or greater');
|
||||
}
|
||||
}
|
||||
|
||||
public function encrypt($key, $data)
|
||||
{
|
||||
$this->_rk = array();
|
||||
$this->sM4KeySchedule($key);
|
||||
$bytes = $this->pad($data);
|
||||
$chunks = array_chunk($bytes, $this->_block_size);
|
||||
$ciphertext = "";
|
||||
foreach ($chunks as $chunk) {
|
||||
$ciphertext .= $this->sM4Encrypt($chunk);
|
||||
}
|
||||
return bin2hex($ciphertext);
|
||||
return base64_encode($ciphertext);
|
||||
}
|
||||
|
||||
|
||||
public function decrypt($key, $data)
|
||||
{
|
||||
$this->_rk = array();
|
||||
// $data = base64_decode($data);
|
||||
$data = hex2bin($data);
|
||||
if (strlen($data) < 0 || strlen($data) % $this->_block_size != 0) {
|
||||
return false;
|
||||
}
|
||||
$this->sM4KeySchedule($key);
|
||||
$bytes = unpack("C*", $data);
|
||||
$chunks = array_chunk($bytes, $this->_block_size);
|
||||
$plaintext = "";
|
||||
foreach ($chunks as $chunk) {
|
||||
$plaintext .= substr($this->sM4Decrypt($chunk), 0, 16);
|
||||
}
|
||||
$plaintext = $this->un_pad($plaintext);
|
||||
return $plaintext;
|
||||
}
|
||||
|
||||
private function sM4Decrypt($cipherText)
|
||||
{
|
||||
$x = array();
|
||||
for ($j = 0; $j < 4; $j++) {
|
||||
$x[$j] = ($cipherText[$j * 4] << 24) | ($cipherText[$j * 4 + 1] << 16) | ($cipherText[$j * 4 + 2] << 8)
|
||||
| ($cipherText[$j * 4 + 3]);
|
||||
}
|
||||
for ($i = 0; $i < 32; $i++) {
|
||||
$tmp = $x[$i + 1] ^ $x[$i + 2] ^ $x[$i + 3] ^ $this->_rk[31 - $i];
|
||||
$buf = (self::$SM4_SBOX[($tmp >> 24) & 0xFF]) << 24 | (self::$SM4_SBOX[($tmp >> 16) & 0xFF]) << 16
|
||||
| (self::$SM4_SBOX[($tmp >> 8) & 0xFF]) << 8 | (self::$SM4_SBOX[$tmp & 0xFF]);
|
||||
$x[$i + 4] = $x[$i] ^ ($buf ^ $this->sm4Rotl32(($buf), 2) ^ $this->sm4Rotl32(($buf), 10)
|
||||
^ $this->sm4Rotl32(($buf), 18) ^ $this->sm4Rotl32(($buf), 24));
|
||||
}
|
||||
$plainText = array();
|
||||
for ($k = 0; $k < 4; $k++) {
|
||||
$plainText[4 * $k] = ($x[35 - $k] >> 24) & 0xFF;
|
||||
$plainText[4 * $k + 1] = ($x[35 - $k] >> 16) & 0xFF;
|
||||
$plainText[4 * $k + 2] = ($x[35 - $k] >> 8) & 0xFF;
|
||||
$plainText[4 * $k + 3] = ($x[35 - $k]) & 0xFF;
|
||||
}
|
||||
return $this->bytesToString($plainText);
|
||||
}
|
||||
|
||||
private function sM4Encrypt($plainText)
|
||||
{
|
||||
$x = array();
|
||||
for ($j = 0; $j < 4; $j++) {
|
||||
$x[$j] = ($plainText[$j * 4] << 24) | ($plainText[$j * 4 + 1] << 16) | ($plainText[$j * 4 + 2] << 8)
|
||||
| ($plainText[$j * 4 + 3]);
|
||||
}
|
||||
for ($i = 0; $i < 32; $i++) {
|
||||
$tmp = $x[$i + 1] ^ $x[$i + 2] ^ $x[$i + 3] ^ $this->_rk[$i];
|
||||
$buf = (self::$SM4_SBOX[($tmp >> 24) & 0xFF]) << 24 | (self::$SM4_SBOX[($tmp >> 16) & 0xFF]) << 16
|
||||
| (self::$SM4_SBOX[($tmp >> 8) & 0xFF]) << 8 | (self::$SM4_SBOX[$tmp & 0xFF]);
|
||||
$x[$i + 4] = $x[$i] ^ ($buf ^ $this->sm4Rotl32(($buf), 2) ^ $this->sm4Rotl32(($buf), 10)
|
||||
^ $this->sm4Rotl32(($buf), 18) ^ $this->sm4Rotl32(($buf), 24));
|
||||
}
|
||||
$cipherText = array();
|
||||
for ($k = 0; $k < 4; $k++) {
|
||||
$cipherText[4 * $k] = ($x[35 - $k] >> 24) & 0xFF;
|
||||
$cipherText[4 * $k + 1] = ($x[35 - $k] >> 16) & 0xFF;
|
||||
$cipherText[4 * $k + 2] = ($x[35 - $k] >> 8) & 0xFF;
|
||||
$cipherText[4 * $k + 3] = ($x[35 - $k]) & 0xFF;
|
||||
}
|
||||
return $this->bytesToString($cipherText);
|
||||
}
|
||||
|
||||
private function stringToBytes($string)
|
||||
{
|
||||
return unpack('C*', $string);
|
||||
}
|
||||
|
||||
private function bytesToString($bytes)
|
||||
{
|
||||
return vsprintf(str_repeat('%c', count($bytes)), $bytes);
|
||||
}
|
||||
|
||||
private function pad($data)
|
||||
{
|
||||
$bytes = $this->stringToBytes($data);
|
||||
$rem = $this->_block_size - count($bytes) % $this->_block_size;
|
||||
for ($i = 0; $i < $rem; $i++) {
|
||||
array_push($bytes, $rem);
|
||||
}
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
private function un_pad($data)
|
||||
{
|
||||
$bytes = $this->stringToBytes($data);
|
||||
$rem = $bytes[count($bytes)];
|
||||
$bytes = array_slice($bytes, 0, count($bytes) - $rem);
|
||||
return $this->bytesToString($bytes);
|
||||
}
|
||||
|
||||
private function sm4Rotl32($buf, $n)
|
||||
{
|
||||
return (($buf << $n) & 0xffffffff) | ($buf >> (32 - $n));
|
||||
}
|
||||
|
||||
private function sM4KeySchedule($key)
|
||||
{
|
||||
$this->_rk = array();
|
||||
$key = array_values(unpack("C*", $key));
|
||||
$k = array();
|
||||
// for ($i = 0; $i < 4; $i++) {
|
||||
// $k[$i] = self::$SM4_FK[$i]
|
||||
// ^ ((($key[4 * $i] ?? 0) << 24)
|
||||
// | (($key[4 * $i + 1] ?? 0) << 16)
|
||||
// | (($key[4 * $i + 2] ?? 0) << 8)
|
||||
// | ($key[4 * $i + 3] ?? null));
|
||||
// }
|
||||
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$k[$i] = self::$SM4_FK[$i]
|
||||
^ (((isset($key[4 * $i]) ? $key[4 * $i] : 0) << 24)
|
||||
| ((isset($key[4 * $i + 1]) ? $key[4 * $i + 1] : 0) << 16)
|
||||
| ((isset($key[4 * $i + 2]) ? $key[4 * $i + 2] : 0) << 8)
|
||||
| (isset($key[4 * $i + 3]) ? $key[4 * $i + 3] : null));
|
||||
}
|
||||
for ($j = 0; $j < 32; $j++) {
|
||||
$tmp = $k[$j + 1] ^ $k[$j + 2] ^ $k[$j + 3] ^ self::$SM4_CK[$j];
|
||||
$buf = (self::$SM4_SBOX[($tmp >> 24) & 0xFF]) << 24 | (self::$SM4_SBOX[($tmp >> 16) & 0xFF]) << 16
|
||||
| (self::$SM4_SBOX[($tmp >> 8) & 0xFF]) << 8 | (self::$SM4_SBOX[$tmp & 0xFF]);
|
||||
$k[$j + 4] = $k[$j] ^ (($buf) ^ ($this->sm4Rotl32(($buf), 13)) ^ ($this->sm4Rotl32(($buf), 23)));
|
||||
$this->_rk[$j] = $k[$j + 4];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
80
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/handler/BigJHandler.php
vendored
Normal file
80
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/handler/BigJHandler.php
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
namespace Rtgm\smecc\SM4\handler;
|
||||
use Rtgm\smecc\SM4\libs\WordConversion;
|
||||
|
||||
/**
|
||||
* BigJHandler @ SM3-PHP
|
||||
*
|
||||
* Code BY ch4o5
|
||||
* 10月. 14日 2019年
|
||||
* Powered by PhpStorm
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 小j处理类
|
||||
* Class BigJHandler
|
||||
*
|
||||
* @package SM3\handler
|
||||
*/
|
||||
class BigJHandler extends JHandler
|
||||
{
|
||||
/** @var int j的最大可用值 */
|
||||
const SMALLEST_J = 16;
|
||||
/** @var int j的最小可用值 */
|
||||
const BIGGEST_J = 63;
|
||||
/** @var string T常量 */
|
||||
const T = '7a879d8a';
|
||||
|
||||
/**
|
||||
* 补充父类
|
||||
* SmallJHandler constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(self::T, self::SMALLEST_J, self::BIGGEST_J);
|
||||
}
|
||||
|
||||
/**
|
||||
* 布尔函数
|
||||
*
|
||||
* @param $X string 长度32的比特串
|
||||
* @param $Y string
|
||||
* @param $Z string
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function FF($X, $Y, $Z)
|
||||
{
|
||||
$X_and_Y = WordConversion::andConversion(array($X, $Y));
|
||||
$X_and_Z = WordConversion::andConversion(array($X, $Z));
|
||||
$Y_and_Z = WordConversion::andConversion(array($Y, $Z));
|
||||
|
||||
return WordConversion::orConversion(
|
||||
array(
|
||||
$X_and_Y,
|
||||
$X_and_Z,
|
||||
$Y_and_Z
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 布尔函数
|
||||
*
|
||||
* @param $X
|
||||
* @param $Y
|
||||
* @param $Z
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GG($X, $Y, $Z)
|
||||
{
|
||||
$X_and_Y = WordConversion::andConversion(array($X, $Y));
|
||||
|
||||
$not_X = WordConversion::notConversion($X);
|
||||
$not_X_and_Z = WordConversion::andConversion(array($not_X, $Z));
|
||||
|
||||
return WordConversion::orConversion(array($X_and_Y, $not_X_and_Z));
|
||||
}
|
||||
}
|
||||
207
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/handler/ExtendedCompression.php
vendored
Normal file
207
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/handler/ExtendedCompression.php
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
namespace Rtgm\smecc\SM4\handler;
|
||||
/**
|
||||
* ExtendedCompression @ SM3-PHP
|
||||
*
|
||||
* Code BY ch4o5
|
||||
* 10月. 15日 2019年
|
||||
* Powered by PhpStorm
|
||||
*/
|
||||
|
||||
use Rtgm\smecc\SM4\libs\WordConversion;
|
||||
use Rtgm\smecc\SM4\types\Word;
|
||||
|
||||
|
||||
/**
|
||||
* 扩展压缩算法
|
||||
* Class ExtendedCompression
|
||||
*
|
||||
* @package SM3\handler
|
||||
*/
|
||||
class ExtendedCompression
|
||||
{
|
||||
/** @var array $W */
|
||||
private $W;
|
||||
/** @var array $W ' */
|
||||
private $W_s;
|
||||
|
||||
/**
|
||||
* 压缩函数
|
||||
*
|
||||
* @param $Vi
|
||||
* @param $Bi
|
||||
*
|
||||
* @return Word
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public function CF($Vi, $Bi)
|
||||
{
|
||||
// 消息扩展
|
||||
$this->extended($Bi);
|
||||
|
||||
/** @var array $registers 八个寄存器的名字 */
|
||||
$registers = array(
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
'D',
|
||||
'E',
|
||||
'F',
|
||||
'G',
|
||||
'H'
|
||||
);
|
||||
|
||||
// 将 Vi 的值依次放入八个寄存器中
|
||||
// 下列注释用于防止IDE报错
|
||||
/** @var Word $A */
|
||||
/** @var Word $B */
|
||||
/** @var Word $C */
|
||||
/** @var Word $D */
|
||||
/** @var Word $E */
|
||||
/** @var Word $F */
|
||||
/** @var Word $G */
|
||||
/** @var Word $H */
|
||||
foreach ($registers as $i => $register) {
|
||||
$$register = new Word(substr($Vi, $i * 32, 32));
|
||||
}
|
||||
|
||||
|
||||
$small_j_handler = new SmallJHandler();
|
||||
$big_j_handler = new BigJHandler();
|
||||
|
||||
for ($j = 0; $j < 64; $j++) {
|
||||
$j_handler = ($j >= SmallJHandler::SMALLEST_J && $j < BigJHandler::SMALLEST_J)
|
||||
? $small_j_handler
|
||||
: $big_j_handler;
|
||||
|
||||
$SS1 = WordConversion::shiftLeftConversion(
|
||||
WordConversion::addConversion(
|
||||
array(
|
||||
WordConversion::shiftLeftConversion($A, 12),
|
||||
$E,
|
||||
WordConversion::shiftLeftConversion($j_handler->getT(), $j)
|
||||
)
|
||||
),
|
||||
7
|
||||
);
|
||||
|
||||
$SS2 = WordConversion::xorConversion(
|
||||
array(
|
||||
$SS1,
|
||||
WordConversion::shiftLeftConversion($A, 12)
|
||||
)
|
||||
);
|
||||
|
||||
$TT1 = WordConversion::addConversion(
|
||||
array(
|
||||
$j_handler->FF($A, $B, $C),
|
||||
$D,
|
||||
$SS2,
|
||||
$this->W_s[$j]
|
||||
)
|
||||
);
|
||||
|
||||
$TT2 = WordConversion::addConversion(
|
||||
array(
|
||||
$j_handler->GG($E, $F, $G),
|
||||
$H,
|
||||
$SS1,
|
||||
$this->W[$j]
|
||||
)
|
||||
);
|
||||
|
||||
$D = $C;
|
||||
|
||||
$C = WordConversion::shiftLeftConversion($B, 9);
|
||||
|
||||
$B = $A;
|
||||
|
||||
$A = $TT1;
|
||||
|
||||
$H = $G;
|
||||
|
||||
$G = WordConversion::shiftLeftConversion($F, 19);
|
||||
|
||||
$F = $E;
|
||||
|
||||
$TT2_object = new Substitution($TT2);
|
||||
$E = $TT2_object->P0();
|
||||
}
|
||||
|
||||
return WordConversion::xorConversion(
|
||||
array(
|
||||
join(
|
||||
'',
|
||||
array(
|
||||
(new Word($A)),
|
||||
(new Word($B)),
|
||||
(new Word($C)),
|
||||
(new Word($D)),
|
||||
(new Word($E)),
|
||||
(new Word($F)),
|
||||
(new Word($G)),
|
||||
(new Word($H))
|
||||
)
|
||||
),
|
||||
$Vi
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息扩展
|
||||
*
|
||||
* 将消息分组B(i)按以下方法扩展生成132个字W0, W1, · · · , W67, W′0, W′1, · · · , W′63,
|
||||
* 用于压缩函数CF
|
||||
*
|
||||
* @param $Bi 消息分组中的第i个,最大512位 (\SM3\types\BitString)
|
||||
*
|
||||
* @return void
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public function extended($Bi)
|
||||
{
|
||||
// 将消息分组B(i)划分为16个字W0, W1, · · · , W15。
|
||||
$this->W = $this->W_s = array();
|
||||
|
||||
$word_per_times = (int)ceil(strlen($Bi) / 16);
|
||||
for ($i = 0; $i < 16; $i++) {
|
||||
$this->W[$i] = new Word(
|
||||
substr($Bi, $i * $word_per_times, $word_per_times)
|
||||
);
|
||||
}
|
||||
|
||||
// 计算W
|
||||
for ($j = 16; $j <= 67; $j++) {
|
||||
$param_1 = (new Substitution(
|
||||
WordConversion::xorConversion(
|
||||
array(
|
||||
$this->W[$j - 16],
|
||||
$this->W[$j - 9],
|
||||
WordConversion::shiftLeftConversion($this->W[$j - 3], 15)
|
||||
)
|
||||
)
|
||||
));
|
||||
|
||||
$this->W[$j] = WordConversion::xorConversion(
|
||||
array(
|
||||
$param_1->P1(),
|
||||
WordConversion::shiftLeftConversion($this->W[$j - 13], 7),
|
||||
$this->W[$j - 6]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
unset($j);
|
||||
|
||||
// 计算W'
|
||||
for ($j = 0; $j <= 63; $j++) {
|
||||
$this->W_s[$j] = WordConversion::xorConversion(
|
||||
array(
|
||||
$this->W[$j],
|
||||
$this->W[$j + 4]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
94
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/handler/JHandler.php
vendored
Normal file
94
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/handler/JHandler.php
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
namespace Rtgm\smecc\SM4\handler;
|
||||
use Rtgm\smecc\SM4\libs\WordConversion;
|
||||
use Rtgm\smecc\SM4\types\Word;
|
||||
|
||||
/**
|
||||
* JHandler @ SM3-PHP
|
||||
*
|
||||
* Code BY ch4o5
|
||||
* 10月. 14th 2019
|
||||
* Powered by PhpStorm
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* j处理抽象类
|
||||
* Class JHandler
|
||||
*
|
||||
* @package SM3\instantiation
|
||||
*/
|
||||
abstract class JHandler
|
||||
{
|
||||
/** @var string 常量T */
|
||||
protected $T = '';
|
||||
/** @var array j的长度区间 */
|
||||
protected $section_j = array();
|
||||
|
||||
/**
|
||||
* JHandler constructor.
|
||||
*
|
||||
* @param $T string 常量T
|
||||
* @param $smallest int j的最小可用值
|
||||
* @param $biggest int j的最大可用值
|
||||
*/
|
||||
public function __construct($T, $smallest, $biggest)
|
||||
{
|
||||
$this->setT($T);
|
||||
$this->setSectionJ($smallest, $biggest);
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置 继承本抽象类的子类可以处理的j的大小
|
||||
*
|
||||
* @param $smallest int j的最小长度
|
||||
* @param $biggest int j的最大长度
|
||||
*/
|
||||
public function setSectionJ($smallest, $biggest)
|
||||
{
|
||||
$this->section_j = array($smallest, $biggest);
|
||||
}
|
||||
|
||||
/**
|
||||
* 布尔函数
|
||||
*
|
||||
* @param $X string 长度32的比特串
|
||||
* @param $Y string
|
||||
* @param $Z string
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function FF($X, $Y, $Z);
|
||||
|
||||
/**
|
||||
* 布尔函数
|
||||
*
|
||||
* @param $X
|
||||
* @param $Y
|
||||
* @param $Z
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function GG($X, $Y, $Z);
|
||||
|
||||
/**
|
||||
* 读取常量T
|
||||
* @return Word
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public function getT()
|
||||
{
|
||||
return new Word($this->T);
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置常量T
|
||||
*
|
||||
* @param string $T
|
||||
*/
|
||||
public function setT($T)
|
||||
{
|
||||
$this->T = WordConversion::hex2bin($T);
|
||||
}
|
||||
}
|
||||
12
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/handler/README.md
vendored
Normal file
12
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/handler/README.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# *handle/* 目录
|
||||
|
||||
本目录包含了加密过程中的核心算法
|
||||
|
||||
* `\SM3\handler\JHandler`
|
||||
根据J的不同,进行不同处理的抽象类
|
||||
* `\SM3\handler\SmalJHandler`
|
||||
变量j处于较小值时的处理类
|
||||
* `\SM3\handler\BigJHandler`
|
||||
变量j处于较大值时的处理类
|
||||
* `\SM3\handler\Substitution`
|
||||
置换函数类
|
||||
79
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/handler/SmallJHandler.php
vendored
Normal file
79
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/handler/SmallJHandler.php
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
namespace Rtgm\smecc\SM4\handler;
|
||||
|
||||
|
||||
|
||||
use Rtgm\smecc\SM4\libs\WordConversion;
|
||||
|
||||
/**
|
||||
* 小j处理类
|
||||
* Class SmallJHandler
|
||||
*
|
||||
* @package SM3\handler
|
||||
*/
|
||||
class SmallJHandler extends JHandler
|
||||
{
|
||||
/** @var int j的最大可用值 */
|
||||
const SMALLEST_J = 0;
|
||||
/** @var int j的最小可用值 */
|
||||
const BIGGEST_J = 15;
|
||||
/** @var string T常量 */
|
||||
const T = '79cc4519';
|
||||
|
||||
/**
|
||||
* 补充父类
|
||||
* SmallJHandler constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(self::T, self::SMALLEST_J, self::BIGGEST_J);
|
||||
}
|
||||
|
||||
/**
|
||||
* 布尔函数
|
||||
*
|
||||
* @param $X \SM3\types\Word 长度32的比特串
|
||||
* @param $Y \SM3\types\Word 长度32的比特串
|
||||
* @param $Z \SM3\types\Word 长度32的比特串
|
||||
*
|
||||
* @return \SM3\types\Word
|
||||
*/
|
||||
public function FF($X, $Y, $Z)
|
||||
{
|
||||
return self::boolFunction($X, $Y, $Z);
|
||||
}
|
||||
|
||||
/**
|
||||
* 小j值的布尔函数公共方法
|
||||
*
|
||||
* @param $X \SM3\types\Word 长度32的比特串
|
||||
* @param $Y \SM3\types\Word 长度32的比特串
|
||||
* @param $Z \SM3\types\Word 长度32的比特串
|
||||
*
|
||||
* @return \SM3\types\Word
|
||||
*/
|
||||
private static function boolFunction($X, $Y, $Z)
|
||||
{
|
||||
return WordConversion::xorConversion(
|
||||
array(
|
||||
$X,
|
||||
$Y,
|
||||
$Z
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 布尔函数
|
||||
*
|
||||
* @param $X \SM3\types\Word 长度32的比特串
|
||||
* @param $Y \SM3\types\Word 长度32的比特串
|
||||
* @param $Z \SM3\types\Word 长度32的比特串
|
||||
*
|
||||
* @return \SM3\types\Word
|
||||
*/
|
||||
public function GG($X, $Y, $Z)
|
||||
{
|
||||
return self::boolFunction($X, $Y, $Z);
|
||||
}
|
||||
}
|
||||
89
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/handler/Substitution.php
vendored
Normal file
89
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/handler/Substitution.php
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
namespace Rtgm\smecc\SM4\handler;
|
||||
use Rtgm\smecc\SM4\libs\WordConversion;
|
||||
use Rtgm\smecc\SM4\types\Word;
|
||||
|
||||
/**
|
||||
* Substitution @ SM3-PHP
|
||||
*
|
||||
* Code BY ch4o5
|
||||
* 10月. 14日 2019年
|
||||
* Powered by PhpStorm
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 置换函数
|
||||
* Class Substitution
|
||||
*
|
||||
* @package SM3\handler
|
||||
*/
|
||||
class Substitution
|
||||
{
|
||||
/** @var \SM3\types\Word 待置换的字 */
|
||||
private $X;
|
||||
|
||||
/** @var array P0函数中两次左移的位数 */
|
||||
private $P0_shiftLeft_times = array(9, 17);
|
||||
/** @var array P1函数中两次左移的位数 */
|
||||
private $P1_shiftLeft_times = array(15, 23);
|
||||
|
||||
/**
|
||||
* Substitution constructor.
|
||||
*
|
||||
* @param $X
|
||||
*/
|
||||
public function __construct($X)
|
||||
{
|
||||
$this->X = $X;
|
||||
}
|
||||
|
||||
/**
|
||||
* 压缩函数中的置换函数
|
||||
*
|
||||
* @return \SM3\types\Word 置换结果
|
||||
*/
|
||||
public function P0()
|
||||
{
|
||||
return $this->substitutionFunction(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 置换函数的公共函数
|
||||
* @param $type
|
||||
* @return Word
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
private function substitutionFunction($type)
|
||||
{
|
||||
if (!in_array($type, array(0, '0', 1, '1'))) {
|
||||
return new Word('');
|
||||
}
|
||||
|
||||
$times_name = $type == 1
|
||||
? $this->P1_shiftLeft_times
|
||||
: $this->P0_shiftLeft_times;
|
||||
|
||||
$X_shiftLeft_1 = WordConversion::shiftLeftConversion($this->X, $times_name[0]);
|
||||
$X_shiftLeft_2 = WordConversion::shiftLeftConversion($this->X, $times_name[1]);
|
||||
|
||||
return WordConversion::xorConversion(
|
||||
array(
|
||||
$this->X,
|
||||
$X_shiftLeft_1,
|
||||
$X_shiftLeft_2
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息扩展中的置换函数
|
||||
* @return Word
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public function P1()
|
||||
{
|
||||
return $this->substitutionFunction(1);
|
||||
}
|
||||
}
|
||||
8
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/libs/README.md
vendored
Normal file
8
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/libs/README.md
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# *libs/* 目录
|
||||
|
||||
本目录包含了 *动态读写配置* 和 *一些底层的基础操作(如:按位运算)*
|
||||
|
||||
* `\SM3\libs\Config`
|
||||
配置类,获取和动态设定配置
|
||||
* `\SM3\libs\WordConversion`
|
||||
字的位运算类,包含了位的各种运算
|
||||
271
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/libs/WordConversion.php
vendored
Normal file
271
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/libs/WordConversion.php
vendored
Normal file
@@ -0,0 +1,271 @@
|
||||
<?php
|
||||
namespace Rtgm\smecc\SM4\libs;
|
||||
/**
|
||||
* Conversion @ SM3-PHP
|
||||
*
|
||||
* Code BY ch4o5
|
||||
* 10月. 14th 2019
|
||||
* Powered by PhpStorm
|
||||
*/
|
||||
|
||||
use Rtgm\smecc\SM4\types\Word;
|
||||
|
||||
/**
|
||||
* 字的位运算类
|
||||
* Class Conversion
|
||||
*
|
||||
* @package SM3\libs
|
||||
*/
|
||||
class WordConversion
|
||||
{
|
||||
/**
|
||||
* 字的异或运算
|
||||
*
|
||||
* @param $params array 需要进行异或运算的字列表
|
||||
*
|
||||
* @return Word
|
||||
* @api $value \SM3\types\Word
|
||||
*
|
||||
*/
|
||||
public static function xorConversion($params)
|
||||
{
|
||||
return self::conversion($params, 3);
|
||||
}
|
||||
|
||||
public static function conversion_func($prevent, $current, $type)
|
||||
{
|
||||
if (is_null($prevent)) {
|
||||
return $current;
|
||||
}
|
||||
|
||||
$prevent = strval($prevent);
|
||||
$current = strval($current);
|
||||
|
||||
if (strlen($current) >= strlen($prevent)) {
|
||||
$longest = strlen($current);
|
||||
$longest_value = $current;
|
||||
$shortest = strlen($prevent);
|
||||
} else {
|
||||
$longest = strlen($prevent);
|
||||
$longest_value = $prevent;
|
||||
$shortest = strlen($current);
|
||||
}
|
||||
|
||||
if ($prevent === '0' || $current === '0') {
|
||||
switch ($type) {
|
||||
// and
|
||||
case 1:
|
||||
return 0;
|
||||
// or
|
||||
case 2:
|
||||
// xor
|
||||
case 3:
|
||||
// add
|
||||
case 5:
|
||||
return $prevent == '0' ? $current : $prevent;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$value = array();
|
||||
/**
|
||||
* 加运算时需要,用来储存需要进几
|
||||
*
|
||||
* @var int 向前一位进的数字
|
||||
*/
|
||||
$carry = 0;
|
||||
/**
|
||||
* 大端
|
||||
*
|
||||
* 这里从大端跑完之后,结果数组的序号是从大到小排列的
|
||||
* 还需要根据键名排序一次
|
||||
*
|
||||
* 个人感觉区分不区分大端并没有什么意义
|
||||
* 如果换成字符串拼接的话更好用
|
||||
* 但是方便你理解,还是按照大端+数组的方式进行的排列
|
||||
*/
|
||||
for ($i = $longest - 1; $i >= 0; $i--) {
|
||||
$prevent_number = $prevent[$i];
|
||||
switch ($type) {
|
||||
// 与
|
||||
case 1:
|
||||
$value[$i] = ($i >= $shortest)
|
||||
? $longest_value[$i]
|
||||
: ($prevent_number & $current[$i]);
|
||||
break;
|
||||
// 或
|
||||
case 2:
|
||||
$value[$i] = ($i >= $shortest)
|
||||
? ~$longest_value[$i]
|
||||
: ($prevent_number | $current[$i]);
|
||||
break;
|
||||
// 异或
|
||||
case 3:
|
||||
$value[$i] = $i > $shortest
|
||||
? 1
|
||||
: (intval($prevent_number) ^ intval($current[$i]));
|
||||
break;
|
||||
// 非(按位取反)
|
||||
case 4:
|
||||
$value[$i] = $prevent_number === '1'
|
||||
? '0'
|
||||
: '1';
|
||||
break;
|
||||
// 加
|
||||
case 5:
|
||||
$add = $prevent_number + $current[$i] + $carry;
|
||||
$value[$i] = $add % 2;
|
||||
$carry = ($add - $value[$i]) / 2;
|
||||
break;
|
||||
// 特殊情况
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ksort($value);
|
||||
return new Word(join('', $value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $params array 需要进行异或运算的字列表
|
||||
* @param $type int 位运算类型
|
||||
* @return Word|null 运算结果
|
||||
*/
|
||||
private static function conversion($params, $type)
|
||||
{
|
||||
$prevent = null;
|
||||
foreach ($params as $param){
|
||||
$prevent = self::conversion_func($prevent,$param,$type);
|
||||
}
|
||||
return $prevent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字的与运算
|
||||
*
|
||||
* @param $params array 需要进行与运算的字列表
|
||||
*
|
||||
* @return Word
|
||||
*/
|
||||
public static function andConversion($params)
|
||||
{
|
||||
return self::conversion($params, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字的或运算
|
||||
*
|
||||
* @param $params
|
||||
*
|
||||
* @return Word
|
||||
*/
|
||||
public static function orConversion($params)
|
||||
{
|
||||
return self::conversion($params, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字的非运算
|
||||
*
|
||||
* @param $word
|
||||
*
|
||||
* @return Word
|
||||
*/
|
||||
public static function notConversion($word)
|
||||
{
|
||||
return self::conversion(array($word, null), 4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param $word Word 待运算的字
|
||||
* @param $times int 左移的位数
|
||||
* @return Word
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public static function shiftLeftConversion($word, $times)
|
||||
{
|
||||
return new Word(
|
||||
substr(
|
||||
$word,
|
||||
($times % strlen($word))
|
||||
)
|
||||
. substr(
|
||||
$word,
|
||||
0,
|
||||
($times % strlen($word))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将16进制数串转换为二进制数据
|
||||
* 使用字符串形式实现,解决了PHP本身进制转换的时候受限于浮点数大小的问题
|
||||
*
|
||||
* @param int|string $hex
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function hex2bin($hex)
|
||||
{
|
||||
// 格式化为字符串
|
||||
$hex = strval($hex);
|
||||
|
||||
/** 十六进制转二进制,每1位一组 */
|
||||
defined('HEX_TO_BIN_NUM') || define('HEX_TO_BIN_NUM', 1);
|
||||
/** @var array $hex_array 把指定的十六进制数按位切片为数组 */
|
||||
$hex_array = str_split($hex, HEX_TO_BIN_NUM);
|
||||
// 最终的二进制数字(为确保长度不丢失,使用字符串类型)
|
||||
$binary = '';
|
||||
|
||||
foreach ($hex_array as $number) {
|
||||
$bin_number = strval(base_convert($number, 16, 2));
|
||||
if (strlen($bin_number) < 4) {
|
||||
$bin_number = str_pad($bin_number, 4, '0', STR_PAD_LEFT);
|
||||
}
|
||||
$binary .= $bin_number;
|
||||
}
|
||||
|
||||
return $binary;
|
||||
}
|
||||
|
||||
/**
|
||||
* 二进制转十六进制
|
||||
* @param $bin
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function bin2hex($bin)
|
||||
{
|
||||
// 格式化为字符串
|
||||
$bin = strval($bin);
|
||||
|
||||
/** 二进制转十六进制,每4位一组 */
|
||||
defined('BIN_TO_HEX_NUM') || define('BIN_TO_HEX_NUM', 4);
|
||||
/** @var array $bin_array 把指定的二进制数按位切片为数组 */
|
||||
$bin_array = str_split($bin, BIN_TO_HEX_NUM);
|
||||
// 最终的二进制数字(为确保长度不丢失,使用字符串类型)
|
||||
$hex = '';
|
||||
|
||||
foreach ($bin_array as $number) {
|
||||
$hex .= strval(base_convert($number, 2, 16));
|
||||
}
|
||||
|
||||
return $hex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 二进制加运算
|
||||
*
|
||||
* @param array $params
|
||||
*
|
||||
* @return Word
|
||||
*/
|
||||
public static function addConversion($params)
|
||||
{
|
||||
return self::conversion($params, 5);
|
||||
}
|
||||
}
|
||||
204
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/types/BitString.php
vendored
Normal file
204
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/types/BitString.php
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
namespace Rtgm\smecc\SM4\types;
|
||||
use ErrorException;
|
||||
|
||||
/**
|
||||
* BitString @ SM3-PHP
|
||||
*
|
||||
* Code BY ch4o5
|
||||
* 10月. 14th 2019
|
||||
* Powered by PhpStorm
|
||||
*/
|
||||
|
||||
/**
|
||||
* 比特串
|
||||
* 由0和1组成的二进制数字序列。
|
||||
* Class BitString
|
||||
*
|
||||
* @package SM3\types
|
||||
*/
|
||||
class BitString implements \ArrayAccess
|
||||
{
|
||||
/** @var string 一个比特串类型的变量 */
|
||||
protected $bit_string = '';
|
||||
|
||||
/**
|
||||
* BitString constructor.
|
||||
*
|
||||
* @param $string string|BitString|Word|mixed 传入的数据
|
||||
* @param false|null $is_bit_string 是否比特串(只有入口明确知道不是)
|
||||
*
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public function __construct($string, $is_bit_string = null)
|
||||
{
|
||||
if (is_object($string)) {
|
||||
$string = $string->getString();
|
||||
}
|
||||
|
||||
if ($is_bit_string === false) {
|
||||
// 指定不是比特串的,直接转换
|
||||
$this->bit_string = "{$this->str2bin($string)}";
|
||||
} else {
|
||||
// 默认走个验证试试
|
||||
$this->bit_string = $this->is_bit_string($string)
|
||||
? $string
|
||||
: "{$this->str2bin($string)}";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串转比特串
|
||||
*
|
||||
* @param $str int|string 普通字符串
|
||||
*
|
||||
* @return string 转换为比特串
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
private function str2bin($str)
|
||||
{
|
||||
if (!is_string($str) && !is_int($str)) {
|
||||
throw new ErrorException('输入的类型错误');
|
||||
}
|
||||
if (is_int($str)) {
|
||||
return decbin($str);
|
||||
}
|
||||
$fileType = mb_detect_encoding($str , array('UTF-8','GBK','LATIN1','BIG5')) ;
|
||||
if( $fileType != 'UTF-8'){
|
||||
$str = mb_convert_encoding($str ,'utf-8' , $fileType);
|
||||
}
|
||||
$arr = preg_split('/(?<!^)(?!$)/u', $str);
|
||||
foreach ($arr as &$v) {
|
||||
$fileType = mb_detect_encoding($v , array('UTF-8','GBK','LATIN1','BIG5')) ;
|
||||
/* if( $fileType != 'GBK'){
|
||||
$v = mb_convert_encoding($v ,'GBK' , $fileType); //这里也要utf8啊,
|
||||
} */
|
||||
if( $fileType != 'UTF-8'){
|
||||
$str = mb_convert_encoding($str ,'utf-8' , $fileType);
|
||||
}
|
||||
$temp = unpack('H*', $v);
|
||||
$v = base_convert($temp[1], 16, 2);
|
||||
|
||||
while (strlen($v) < 8) {
|
||||
$v = '0' . $v;
|
||||
}
|
||||
unset($temp);
|
||||
}
|
||||
return join('', $arr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为比特串类型
|
||||
*
|
||||
* @param string|Word $string
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_bit_string($string)
|
||||
{
|
||||
if (is_object($string)) {
|
||||
$string = $string->getString();
|
||||
}
|
||||
// 检查是否为字符串
|
||||
if (!is_string($string)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查是否为只有0和1组成的字符串
|
||||
$array = array_filter(str_split($string));
|
||||
foreach ($array as $value) {
|
||||
if (!in_array(
|
||||
$value,
|
||||
array(
|
||||
0,
|
||||
'0',
|
||||
1,
|
||||
'1'
|
||||
),
|
||||
true
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取比特串的值
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getString()
|
||||
{
|
||||
return $this->bit_string;
|
||||
}
|
||||
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->bit_string[$offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a offset exists
|
||||
*
|
||||
* @link https://php.net/manual/en/arrayaccess.offsetexists.php
|
||||
*
|
||||
* @param mixed $offset <p>
|
||||
* An offset to check for.
|
||||
* </p>
|
||||
*
|
||||
* @return bool true on success or false on failure.
|
||||
* </p>
|
||||
* <p>
|
||||
* The return value will be casted to boolean if non-boolean was returned.
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->bit_string[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to set
|
||||
*
|
||||
* @link https://php.net/manual/en/arrayaccess.offsetset.php
|
||||
*
|
||||
* @param mixed $offset <p>
|
||||
* The offset to assign the value to.
|
||||
* </p>
|
||||
* @param mixed $value <p>
|
||||
* The value to set.
|
||||
* </p>
|
||||
*
|
||||
* @return BitString
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->bit_string[$offset] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset to unset
|
||||
*
|
||||
* @link https://php.net/manual/en/arrayaccess.offsetunset.php
|
||||
*
|
||||
* @param mixed $offset <p>
|
||||
* The offset to unset.
|
||||
* </p>
|
||||
*
|
||||
* @return void
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->bit_string[$offset]);
|
||||
}
|
||||
}
|
||||
8
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/types/README.md
vendored
Normal file
8
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/types/README.md
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# *types/* 目录
|
||||
|
||||
本目录为自定义的扩展类型的目录
|
||||
|
||||
* `\SM3\types\BitString`
|
||||
比特串 类型
|
||||
* `\SM3\types\Word`
|
||||
字 类型
|
||||
73
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/types/Word.php
vendored
Normal file
73
pgserver/vendor/lpilp/guomi/src/smecc/SM4OLD/types/Word.php
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
namespace Rtgm\smecc\SM4\types;
|
||||
|
||||
|
||||
/**
|
||||
* 字类型
|
||||
* 长度32的比特串
|
||||
* Class Word
|
||||
*
|
||||
* @package SM3\types\
|
||||
*/
|
||||
class Word extends BitString implements \ArrayAccess
|
||||
{
|
||||
/** @var int 设置长度为32 */
|
||||
const length = 32;
|
||||
/** @var string */
|
||||
private $word = '';
|
||||
|
||||
/**
|
||||
* Word constructor.
|
||||
*
|
||||
* @param $string
|
||||
*
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public function __construct($string)
|
||||
{
|
||||
parent::__construct($string);
|
||||
|
||||
if (strlen($this->bit_string) === self::length) {
|
||||
$this->word = $this->bit_string;
|
||||
} else {
|
||||
$this->word = intval($this->bit_string) === 0
|
||||
? 0
|
||||
: $this->bit_string;
|
||||
|
||||
if (strlen($this->word) <= self::length) {
|
||||
$this->word = str_pad(
|
||||
$this->word,
|
||||
self::length,
|
||||
'0',
|
||||
STR_PAD_LEFT
|
||||
);
|
||||
} else {
|
||||
$this->word = substr($this->bit_string, -(self::length));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->word;
|
||||
}
|
||||
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->word[$offset];
|
||||
}
|
||||
|
||||
public function getString()
|
||||
{
|
||||
return $this->word;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBitString()
|
||||
{
|
||||
return $this->bit_string;
|
||||
}
|
||||
|
||||
}
|
||||
63
pgserver/vendor/lpilp/guomi/src/util/FormatSign.php
vendored
Normal file
63
pgserver/vendor/lpilp/guomi/src/util/FormatSign.php
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
namespace Rtgm\util;
|
||||
|
||||
class FormatSign
|
||||
{
|
||||
public function run($sign)
|
||||
{
|
||||
list($binR, $binS) = $this->_decode_rs(base64_decode($sign));
|
||||
$binR = $this->_trim_int_pad($binR);
|
||||
$binS = $this->_trim_int_pad($binS);
|
||||
$lenR = strlen($binR);
|
||||
$lenS = strlen($binS);
|
||||
$result = chr(48) . chr(2 + $lenR + 2 + $lenS) . chr(2) . chr($lenR) . $binR . chr(2) . chr($lenS) . $binS;
|
||||
return base64_encode($result);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
/**
|
||||
* 招行的解签,没有用标准的asn1解析函数,当出现r,s的位数不足的时候就报错了,只支持rs, 31,32字节,当字节数少时强制补0吧
|
||||
*
|
||||
* @param string $sign
|
||||
* @return string
|
||||
*/
|
||||
public function format_cmbc($sign){
|
||||
list($binR, $binS) = $this->_decode_rs(base64_decode($sign));
|
||||
while(strlen($binR)<32){
|
||||
$binR = chr(0).$binR;
|
||||
}
|
||||
while(strlen($binS)<32){
|
||||
$binS = chr(0).$binS;
|
||||
}
|
||||
$lenR = strlen($binR);
|
||||
$lenS = strlen($binS);
|
||||
$result = chr(48) . chr(2 + $lenR + 2 + $lenS) . chr(2) . chr($lenR) . $binR . chr(2) . chr($lenS) . $binS;
|
||||
return base64_encode($result);
|
||||
}
|
||||
private function _trim_int_pad($binStr)
|
||||
{
|
||||
// echo bin2hex($binStr)."\n";
|
||||
//trim 0
|
||||
while(ord($binStr[0])==0){
|
||||
$binStr = substr($binStr,1);
|
||||
}
|
||||
// add 0 if necessary
|
||||
if(ord($binStr[0])>127){
|
||||
$binStr = chr(0).$binStr;
|
||||
}
|
||||
// echo bin2hex($binStr)."\n";
|
||||
return $binStr;
|
||||
|
||||
}
|
||||
private function _decode_rs($binSign)
|
||||
{
|
||||
$rLen = ord($binSign[3]);
|
||||
$binR = substr($binSign, 4, $rLen);
|
||||
$binS = substr($binSign, (4 + $rLen + 2));
|
||||
// echo bin2hex($binR) . "\n----------\n" . bin2hex($binS) . "\n";
|
||||
return [$binR, $binS];
|
||||
}
|
||||
}
|
||||
16
pgserver/vendor/lpilp/guomi/test/data/rsa.pem
vendored
Normal file
16
pgserver/vendor/lpilp/guomi/test/data/rsa.pem
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALjnVY4j/UG0tJ5o
|
||||
HZclp1R1+HsCQmUctzPiN5VO56ZYuFP4T3oDhVkmWReL52WGaKYGrxJymqM6mPt8
|
||||
C3AXNd/KGTpZtXaoBvjK21nPmgDpo6m5nifi+IQTXmjrwDPErr0yIrAvDMP+3wQl
|
||||
w/WJTXVMJb074bYpytmx9WXL2mRTAgMBAAECgYB8/TuTKvbOTKXvkne2LWjQKjK+
|
||||
jAdvrBqXQurJzh2/D6gCcw7ebrTcT5TX2uWfdl0VJd2AfeHURw8UqIRe0AHEzj98
|
||||
yLF4DNgJRbGLCbJm67idyt41E+jnc6zrboLmpOkQ0njYibNulqgbJQ2DaFhnoLI1
|
||||
1CoPW383WxUfV6LquQJBAPLbtfPs+tKrun7zOaJ0GWMYRZBFxVNKE9EQS4X2pg+g
|
||||
NHo+b3bNPPoE66Ug+D69R1AYKC7QkP/zvXqT8dC1UVcCQQDC6MjeJqX4M4C9sfm6
|
||||
x75VqmKNX6qaXzv28wrtMk7anSiR7YQUCs0kchHQz8hpYb+SQio4DhRYJyDHnO+f
|
||||
V/tlAkEAl33IbYVpHNs0tZYhYJ4NbAwq8IklQwRVgjco9ULbaankslCaFUCHhepl
|
||||
2BbN480MXAEFp9ZAbPjtPDZnRGqmdwJARxy1hM/nCAqKcyuHKM2NtSWoNVptHUuX
|
||||
zj7YgrgzKvHiBnP5F3Lla+GufFgDD+fZBFzdmHwSkiMcg5fPmXx5PQJAfKdeiisM
|
||||
1qDcCIFgHSD8JX3Di/oKPF/zyZ3dgFDC8SfqHh/0UuF3WBNUFHpHCO8CoZS/QioK
|
||||
YKN9KVMfaZThsw==
|
||||
-----END PRIVATE KEY-----
|
||||
6
pgserver/vendor/lpilp/guomi/test/data/rsapub.pem
vendored
Normal file
6
pgserver/vendor/lpilp/guomi/test/data/rsapub.pem
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC451WOI/1BtLSeaB2XJadUdfh7
|
||||
AkJlHLcz4jeVTuemWLhT+E96A4VZJlkXi+dlhmimBq8ScpqjOpj7fAtwFzXfyhk6
|
||||
WbV2qAb4yttZz5oA6aOpuZ4n4viEE15o68AzxK69MiKwLwzD/t8EJcP1iU11TCW9
|
||||
O+G2KcrZsfVly9pkUwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
5
pgserver/vendor/lpilp/guomi/test/data/sm2.pem
vendored
Normal file
5
pgserver/vendor/lpilp/guomi/test/data/sm2.pem
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIDMLq58c/Ox37b0NA4Ok65BcRRG+OmF1O+LtAIwRvmm8oAoGCCqBHM9V
|
||||
AYItoUQDQgAEyqo4GGHqDU6XIBpDCzEfi7Z2EpUzmU/s46pJioQkd7tNYAb3Em2J
|
||||
JJRFMK4l6WPlGze3zC66NaRZuyBagjDiVQ==
|
||||
-----END EC PRIVATE KEY-----
|
||||
6
pgserver/vendor/lpilp/guomi/test/data/sm2_cs8.pem
vendored
Normal file
6
pgserver/vendor/lpilp/guomi/test/data/sm2_cs8.pem
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgHaEvjmM9ZMt0xCHT
|
||||
Y65RBRkWxY9bBfl/Fag0bvP1r9OgCgYIKoEcz1UBgi2hRANCAATQeZSDbPzUA57d
|
||||
UZTQBjdiY36CNk6ecsEuMvG3XpNxoJzome32RDEUkDc/qihPAmHaK48SCuVaoG5B
|
||||
Hk+QBDaJ
|
||||
-----END PRIVATE KEY-----
|
||||
4
pgserver/vendor/lpilp/guomi/test/data/sm2pub.pem
vendored
Normal file
4
pgserver/vendor/lpilp/guomi/test/data/sm2pub.pem
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEyqo4GGHqDU6XIBpDCzEfi7Z2EpUz
|
||||
mU/s46pJioQkd7tNYAb3Em2JJJRFMK4l6WPlGze3zC66NaRZuyBagjDiVQ==
|
||||
-----END PUBLIC KEY-----
|
||||
40
pgserver/vendor/lpilp/guomi/test/openssl_encryptsm2.php
vendored
Normal file
40
pgserver/vendor/lpilp/guomi/test/openssl_encryptsm2.php
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
// 说明: PHP自带的函数好像不支持椭圆相关的非对称加密,只支持rsa
|
||||
|
||||
$prifile = 'data/sm2.pem';
|
||||
$pubfile = 'data/sm2pub.pem';
|
||||
|
||||
$prifile = 'data/rsa.pem';
|
||||
$pubfile = 'data/rsapub.pem';
|
||||
|
||||
$data = "I love you!";
|
||||
|
||||
$priKey = openssl_pkey_get_private(file_get_contents($prifile));
|
||||
$pubKey = openssl_pkey_get_public(file_get_contents($pubfile));
|
||||
// var_dump($priKey);die();
|
||||
// print_r(openssl_get_md_methods());
|
||||
openssl_sign($data,$sign,$priKey,'sha256');
|
||||
|
||||
openssl_sign($data,$sign2,$priKey,'sha256WithRSAEncryption');
|
||||
|
||||
echo bin2hex($sign) ."\n";
|
||||
echo bin2hex($sign2) ."\n";
|
||||
|
||||
|
||||
|
||||
exit();
|
||||
|
||||
echo "----------以下rsa的加解密----------------\n";
|
||||
$res = openssl_private_encrypt($data, $encrypted, $priKey);
|
||||
echo bin2hex($encrypted)."\n--------------------------\n";
|
||||
|
||||
$res = openssl_public_decrypt($encrypted,$decryptd,$pubKey);
|
||||
|
||||
echo $decryptd."\n--------------------------\n";
|
||||
if($decryptd == $data){
|
||||
echo "good !!!";
|
||||
} else {
|
||||
echo "bad !!!";
|
||||
}
|
||||
|
||||
|
||||
21
pgserver/vendor/lpilp/guomi/test/openssl_tsm2.php
vendored
Normal file
21
pgserver/vendor/lpilp/guomi/test/openssl_tsm2.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
// openssl支持密码对的生成
|
||||
// 但未支持解签名,证书颁发,openssl 1.1.1 版本目前 不支持 sm3withsm2, 因为sm3withsm2的算法,与普通的sha256 with ecdsa的椭圆算法不一样
|
||||
// git上有相关的gmssl或是tassl的基于openssl开发会支持,需要安装然后替换掉当前的openssl, 并且将替换的openssl用源码方式编译到PHP中,较麻烦
|
||||
// 操作请参考: http://gmssl.org/docs/php-api.html
|
||||
|
||||
// 生成密码对
|
||||
$config = array(
|
||||
"private_key_type" => OPENSSL_KEYTYPE_EC,
|
||||
"curve_name" => "SM2"
|
||||
);
|
||||
$sslconf = "/usr/local/php/extras/openssl/openssl.cnf";
|
||||
$config['config'] = $sslconf;
|
||||
$prikey = openssl_pkey_new($config);
|
||||
openssl_pkey_export($prikey, $prikeypem,null,$config);
|
||||
echo $prikeypem."\n";
|
||||
$pubkeypem = openssl_pkey_get_details($prikey)["key"];
|
||||
echo $pubkeypem."\n";
|
||||
|
||||
|
||||
|
||||
3
pgserver/vendor/lpilp/guomi/test/openssl_tsm3.php
vendored
Normal file
3
pgserver/vendor/lpilp/guomi/test/openssl_tsm3.php
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
$msg = '我爱你ILOVEYOU!';
|
||||
echo openssl_digest($msg, 'sm3');
|
||||
41
pgserver/vendor/lpilp/guomi/test/openssl_tsm4.php
vendored
Normal file
41
pgserver/vendor/lpilp/guomi/test/openssl_tsm4.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* openssl 1.1.1 已支持以下加密算法
|
||||
* aes-128-cbc,aes-128-cbc-hmac-sha1,aes-128-cbc-hmac-sha256,aes-128-ccm,aes-128-cfb,aes-128-cfb1,aes-128-cfb8,aes-128-ctr,aes-128-ecb,aes-128-gcm,aes-128-ocb,aes-128-ofb,aes-128-xts,aes-192-cbc,aes-192-ccm,aes-192-cfb,aes-192-cfb1,aes-192-cfb8,aes-192-ctr,aes-192-ecb,aes-192-gcm,aes-192-ocb,aes-192-ofb,aes-256-cbc,aes-256-cbc-hmac-sha1,aes-256-cbc-hmac-sha256,aes-256-ccm,aes-256-cfb,aes-256-cfb1,aes-256-cfb8,aes-256-ctr,aes-256-ecb,aes-256-gcm,aes-256-ocb,aes-256-ofb,aes-256-xts,aes128,aes128-wrap,aes192,aes192-wrap,aes256,aes256-wrap,aria-128-cbc,aria-128-ccm,aria-128-cfb,aria-128-cfb1,aria-128-cfb8,aria-128-ctr,aria-128-ecb,aria-128-gcm,aria-128-ofb,aria-192-cbc,aria-192-ccm,aria-192-cfb,aria-192-cfb1,aria-192-cfb8,aria-192-ctr,aria-192-ecb,aria-192-gcm,aria-192-ofb,aria-256-cbc,aria-256-ccm,aria-256-cfb,aria-256-cfb1,aria-256-cfb8,aria-256-ctr,aria-256-ecb,aria-256-gcm,aria-256-ofb,aria128,aria192,aria256,bf,bf-cbc,bf-cfb,bf-ecb,bf-ofb,blowfish,camellia-128-cbc,camellia-128-cfb,camellia-128-cfb1,camellia-128-cfb8,camellia-128-ctr,camellia-128-ecb,camellia-128-ofb,camellia-192-cbc,camellia-192-cfb,camellia-192-cfb1,camellia-192-cfb8,camellia-192-ctr,camellia-192-ecb,camellia-192-ofb,camellia-256-cbc,camellia-256-cfb,camellia-256-cfb1,camellia-256-cfb8,camellia-256-ctr,camellia-256-ecb,camellia-256-ofb,camellia128,camellia192,camellia256,cast,cast-cbc,cast5-cbc,cast5-cfb,cast5-ecb,cast5-ofb,chacha20,chacha20-poly1305,des,des-cbc,des-cfb,des-cfb1,des-cfb8,des-ecb,des-ede,des-ede-cbc,des-ede-cfb,des-ede-ecb,des-ede-ofb,des-ede3,des-ede3-cbc,des-ede3-cfb,des-ede3-cfb1,des-ede3-cfb8,des-ede3-ecb,des-ede3-ofb,des-ofb,des3,des3-wrap,desx,desx-cbc,id-aes128-CCM,id-aes128-GCM,id-aes128-wrap,id-aes128-wrap-pad,id-aes192-CCM,id-aes192-GCM,id-aes192-wrap,id-aes192-wrap-pad,id-aes256-CCM,id-aes256-GCM,id-aes256-wrap,id-aes256-wrap-pad,id-smime-alg-CMS3DESwrap,idea,idea-cbc,idea-cfb,idea-ecb,idea-ofb,rc2,rc2-128,rc2-40,rc2-40-cbc,rc2-64,rc2-64-cbc,rc2-cbc,rc2-cfb,rc2-ecb,rc2-ofb,rc4,rc4-40,rc4-hmac-md5,seed,seed-cbc,seed-cfb,seed-ecb,seed-ofb,
|
||||
* sm4,sm4-cbc,sm4-cfb,sm4-ctr,sm4-ecb,sm4-ofb
|
||||
* 其中支持sm4相关的各种算法模式,缺省使用的是cbc算法
|
||||
* 加密串短可以使用ecb,计算速度快,串长的话ecb的扩散性差,安全性不足,就使用带向量的其他算法如cbc
|
||||
*/
|
||||
// echo implode(',',openssl_get_cipher_methods(true));
|
||||
|
||||
// $ivlen = openssl_cipher_iv_length("sm4");
|
||||
// $iv = openssl_random_pseudo_bytes($ivlen);
|
||||
// sm4的iv长度是16字符
|
||||
$key = "0123456789abcdef";
|
||||
$iv = "1234567887654321";
|
||||
|
||||
$data = '我爱你ILOVEYOU!';
|
||||
|
||||
// openssl_encrypt($plaintext, "sms4", $key, $options=0, $iv);
|
||||
// options = 0 base64, 1( OPENSSL_RAW_DATA ):原始二进制 , 这里为了与tsm4对比,就使用hex方式
|
||||
// sm4-ecb算法
|
||||
$ciphertext =openssl_encrypt($data, "sm4-ecb", $key, $options=OPENSSL_RAW_DATA);
|
||||
$enc = bin2hex($ciphertext);
|
||||
echo "encrypt: $enc\n";
|
||||
$original_plaintext = openssl_decrypt($ciphertext, "sm4-ecb", $key, $options=OPENSSL_RAW_DATA);
|
||||
echo "encrypt: $original_plaintext\n";
|
||||
|
||||
// 缺省的sm4算法,使用的是sm4-cbc模式
|
||||
$ciphertext =openssl_encrypt($data, "sm4", $key, $options=OPENSSL_RAW_DATA,$iv);
|
||||
// $ciphertext =openssl_encrypt($data, "sm4-cbc", $key, $options=OPENSSL_RAW_DATA,$iv); //这两个是一样的
|
||||
$enc = bin2hex($ciphertext);
|
||||
echo "encrypt: $enc\n";
|
||||
$original_plaintext = openssl_decrypt($ciphertext, "sm4", $key, $options=OPENSSL_RAW_DATA,$iv);
|
||||
echo "encrypt: $original_plaintext\n";
|
||||
|
||||
// sm4-cfb,sm4-ctr,sm4-ofb 的使用方法一样
|
||||
$ciphertext =openssl_encrypt($data, "sm4-cfb", $key, $options=OPENSSL_RAW_DATA,$iv);
|
||||
$enc = bin2hex($ciphertext);
|
||||
echo "encrypt: $enc\n";
|
||||
$original_plaintext = openssl_decrypt($ciphertext, "sm4-cfb", $key, $options=OPENSSL_RAW_DATA,$iv);
|
||||
echo "encrypt: $original_plaintext\n";
|
||||
24
pgserver/vendor/lpilp/guomi/test/tfsign.php
vendored
Normal file
24
pgserver/vendor/lpilp/guomi/test/tfsign.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
require_once '../vendor/autoload.php';
|
||||
use Rtgm\util\FormatSign;
|
||||
|
||||
$goodSign = 'MEUCIQDWveKrtx6VrosnYQHNBnRjolrlmi/mHwMWKU4bDxakQwIgfSX20s+Ci1SvFQBgx+kRMU3Z1xbHtT0kpZfAXVH8poc=';
|
||||
$badSign = 'MEYCIQDWveKrtx6VrosnYQHNBnRjolrlmi/mHwMWKU4bDxakQwIhAH0l9tLPgotUrxUAYMfpETFN2dcWx7U9JKWXwF1R/KaH';
|
||||
|
||||
$fs = new FormatSign();
|
||||
$newSign = $fs->run($badSign);
|
||||
|
||||
echo $newSign."\n";
|
||||
|
||||
if ($newSign == $goodSign) {
|
||||
echo "OK";
|
||||
} else {
|
||||
echo "Bad";
|
||||
}
|
||||
echo "\n=========\n";
|
||||
//good 补0,
|
||||
$goodSign2 = "MEMCHx7T5iZF+kfk0mNDxVOX2ZOytWjcFBDCRMyUZsvdk\/8CICOZz0A91TlSbZWAhs8J24nWT35l1Su8zegr+vomI9P+";
|
||||
echo (bin2hex(base64_decode($goodSign2)));
|
||||
echo "\n";
|
||||
$newSign2 = $fs->format_cmbc($goodSign2);
|
||||
echo (bin2hex(base64_decode($newSign2)));
|
||||
41
pgserver/vendor/lpilp/guomi/test/tsm2.php
vendored
Normal file
41
pgserver/vendor/lpilp/guomi/test/tsm2.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
require_once '../vendor/autoload.php';
|
||||
use Rtgm\sm\RtSm2;
|
||||
|
||||
$publicKey = '043d9d4cc71a285af936b36880fd4d6155c22957cd2c84ea313469065207fb951b9ef1db79d69af8886e91e833da1ebc6bfdde86e70f52923d6e042eaa147624c7'; // 公钥
|
||||
$privateKey = 'a7763cd4fe7db2a2146fc09bf2d5e5a30e10c51b7e4bed00b3a26ec79ba78ff3'; // 私钥
|
||||
$publicfile = "./data/sm2pub.pem";
|
||||
$privatefile = "./data/sm2.pem";
|
||||
$userId = '1234567812345678';
|
||||
$document = "我爱你ILOVEYOU!";
|
||||
|
||||
define('GK',1);
|
||||
define('SIGN',1);
|
||||
define('SIGNPEM',1);
|
||||
//返回的签名16进制还是base64, 目前可选hex,与base64两种
|
||||
// __construct($formatSign='hex', $randFixed = true)
|
||||
$sm2 = new RtSm2('base64',true);
|
||||
|
||||
|
||||
if(GK){
|
||||
echo "\n----------生成明文密钥对--------------------------\n";
|
||||
print_r($sm2->generatekey()); //生成明文密钥
|
||||
echo "\n----------生成pem密钥对--------------------------\n";
|
||||
print_r($sm2->generatePemkey()); //生成pem密钥,请放到相应的文件中
|
||||
}
|
||||
|
||||
if(SIGN){
|
||||
echo "\n---------明文密钥签名---------------------------\n";
|
||||
$sign = $sm2->doSign( $document, $privateKey, $userId);
|
||||
print_r($sign);
|
||||
echo "\n---------明文密钥验签---------------------------\n";
|
||||
var_dump($sm2->verifySign( $document, $sign, $publicKey, $userId ));
|
||||
}
|
||||
|
||||
if(SIGNPEM){
|
||||
echo "\n---------PEM密钥签名---------------------------\n";
|
||||
$sign = $sm2->doSignOutKey( $document, $privatefile, $userId);
|
||||
print_r($sign);
|
||||
echo "\n---------PEM密钥验签---------------------------\n";
|
||||
var_dump($sm2->verifySignOutKey( $document, $sign, $publicfile, $userId ));
|
||||
}
|
||||
39
pgserver/vendor/lpilp/guomi/test/tsm2_encrypt.php
vendored
Normal file
39
pgserver/vendor/lpilp/guomi/test/tsm2_encrypt.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
require_once '../vendor/autoload.php';
|
||||
use Rtgm\sm\RtSm2;
|
||||
$sm2 = new RtSm2();
|
||||
$publicKey = '043d9d4cc71a285af936b36880fd4d6155c22957cd2c84ea313469065207fb951b9ef1db79d69af8886e91e833da1ebc6bfdde86e70f52923d6e042eaa147624c7'; // 公钥
|
||||
$privateKey = 'a7763cd4fe7db2a2146fc09bf2d5e5a30e10c51b7e4bed00b3a26ec79ba78ff3'; // 私钥
|
||||
|
||||
$document = str_repeat('abcdef',10);
|
||||
// sm2的非对称加解密,不建议加密太长的字符串
|
||||
echo "原始: $document";
|
||||
$m2EncryptData = $sm2 ->doEncrypt($document, $publicKey);
|
||||
echo ("\n加密后: ".$m2EncryptData);
|
||||
$m2DecryptData = $sm2->doDecrypt($m2EncryptData,$privateKey);
|
||||
echo ("\n解密后:".$m2DecryptData);
|
||||
echo "\n------------------------------------------------------------------\n";
|
||||
$document = "我爱你ILOVEYOU!";
|
||||
echo "\n原始: $document";
|
||||
$m2EncryptData = $sm2 ->doEncrypt($document, $publicKey);
|
||||
echo ("\n加密后: ".$m2EncryptData);
|
||||
$m2DecryptData = $sm2->doDecrypt($m2EncryptData,$privateKey);
|
||||
|
||||
echo ("\n解密后: ".$m2DecryptData);
|
||||
echo "\n------------------以上是标准的 c1c3c2 串----------------------------\n";
|
||||
// define("C1C3C2",1);
|
||||
// define("C1C2C3",0);
|
||||
// doEncrypt($document, $publicKey, $model = C1C3C2),
|
||||
// trim是如果加密后前面带着04就去掉
|
||||
// doDecrypt($encryptData,$privateKey,$trim = true,$model = C1C3C2)
|
||||
echo "\n------------------以下是使用 c1c2c3 串可对比上面生成------------------\n";
|
||||
|
||||
|
||||
$document = "我爱你ILOVEYOU!";
|
||||
echo "\n原始: $document";
|
||||
$m2EncryptData = $sm2 ->doEncrypt($document, $publicKey,C1C2C3);
|
||||
echo ("\n加密后: ".$m2EncryptData);
|
||||
$m2DecryptData = $sm2->doDecrypt($m2EncryptData,$privateKey,1,C1C2C3);
|
||||
echo ("\n解密后: ".$m2DecryptData);
|
||||
|
||||
|
||||
6
pgserver/vendor/lpilp/guomi/test/tsm3.php
vendored
Normal file
6
pgserver/vendor/lpilp/guomi/test/tsm3.php
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
require_once '../vendor/autoload.php';
|
||||
use Rtgm\sm\RtSm3;
|
||||
$sm3 = new RtSm3();
|
||||
$data = '我爱你ILOVEYOU!';
|
||||
print_r($sm3->digest($data,1));
|
||||
35
pgserver/vendor/lpilp/guomi/test/tsm4.php
vendored
Normal file
35
pgserver/vendor/lpilp/guomi/test/tsm4.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
require_once '../vendor/autoload.php';
|
||||
use Rtgm\sm\RtSm4;
|
||||
|
||||
$key = "0123456789abcdef";
|
||||
$iv = '1234567887654321';
|
||||
|
||||
$sm4 = new RtSm4($key);
|
||||
|
||||
$data = '我1爱你ILOVEYOU!!!';
|
||||
$data = str_repeat('abc',7);
|
||||
//sm4 的ecb 与cbc加密有补齐(16*n)l
|
||||
// sm4->encrypt($data, $type = 'sm4', $iv = '', $format = 'hex')
|
||||
// openssl_encrypt ,和服务器openssl版本,PHP版本有关,有些服务器可能不支持sm4-* 相关的对称加密算法,
|
||||
|
||||
|
||||
echo "==== test sm4 sm4-cbc============";
|
||||
echo "\nphp sm4: ".$hex = $sm4->encrypt($data,'sm4',$iv); //default is cbc
|
||||
echo "\nphp decode: ".$sm4->decrypt($hex,'sm4',$iv,'hex');
|
||||
|
||||
echo "\n==== test sm4-ecb============";
|
||||
echo "\nphp sm4-ecb: ".$hex = $sm4->encrypt($data,'sm4-ecb');
|
||||
echo "\nphp decode: ".$sm4->decrypt($hex,'sm4-ecb','','hex');
|
||||
|
||||
echo "\n==== test sm4-ofb============";
|
||||
echo "\nphp sm4-ofb: ".$hex = $sm4->encrypt($data,'sm4-ofb',$iv);
|
||||
echo "\nphp decode: ".$sm4->decrypt($hex,'sm4-ofb',$iv,'hex');
|
||||
|
||||
echo "\n==== test sm4-cfb============";
|
||||
echo "\nphp sm4-cfb: ".$hex = $sm4->encrypt($data,'sm4-cfb',$iv);
|
||||
echo "\nphp decode: ".$sm4->decrypt($hex,'sm4-cfb',$iv,'hex');
|
||||
|
||||
echo "\n==== test sm4-ctr============";
|
||||
echo "\nphp sm4-ctr: ".$hex = $sm4->encrypt($data,'sm4-ctr',$iv);
|
||||
echo "\nphp decode: ".$sm4->decrypt($hex,'sm4-ctr',$iv,'hex');
|
||||
28
pgserver/vendor/lpilp/guomi/test/ttsm2.php
vendored
Normal file
28
pgserver/vendor/lpilp/guomi/test/ttsm2.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
require_once '../vendor/autoload.php';
|
||||
use Rtgm\sm\RtSm2;
|
||||
|
||||
$publicKey = '043d9d4cc71a285af936b36880fd4d6155c22957cd2c84ea313469065207fb951b9ef1db79d69af8886e91e833da1ebc6bfdde86e70f52923d6e042eaa147624c7'; // 公钥
|
||||
$privateKey = 'a7763cd4fe7db2a2146fc09bf2d5e5a30e10c51b7e4bed00b3a26ec79ba78ff3'; // 私钥
|
||||
$publicfile = "./data/sm2pub.pem";
|
||||
$privatefile = "./data/sm2.pem";
|
||||
$userId = '1234567812345678';
|
||||
$document = "我爱你ILOVEYOU!";
|
||||
|
||||
define('GK',1);
|
||||
define('SIGN',1);
|
||||
define('SIGNPEM',1);
|
||||
//返回的签名16进制还是base64, 目前可选hex,与base64两种
|
||||
// __construct($formatSign='hex', $randFixed = true)
|
||||
$sm2 = new RtSm2('base64',true);
|
||||
|
||||
|
||||
|
||||
if(SIGN){
|
||||
echo "\n---------明文密钥签名---------------------------\n";
|
||||
$sign = $sm2->doSign( $document, $privateKey, $userId);
|
||||
print_r($sign);
|
||||
echo "\n---------明文密钥验签---------------------------\n";
|
||||
var_dump($sm2->verifySign( $document, $sign, $publicKey, $userId ));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user