This commit is contained in:
2025-10-20 10:02:41 +08:00
parent a4858d47fc
commit dc0a271adf
2805 changed files with 451240 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
# 如果对你有帮助 欢迎打赏
custom: ["https://www.vicsdf.com/img/z.jpg","https://www.vicsdf.com/img/w.jpg"]

View File

@@ -0,0 +1,33 @@
name: sm
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
run:
runs-on: ubuntu-latest
strategy:
matrix:
php-versions: [ '5.6','7.0','7.1', '7.2', '7.4', '8.0' ]
name: PHP ${{ matrix.php-versions }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
coverage: none
ini-values: opcache.jit_buffer_size=256M, opcache.jit=1205, pcre.jit=1, opcache.enable=1, opcache.enable_cli=1
- name: Check PHP Version
run: php -v && php -i | grep opcache
- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Execute tests sm3
run: php tests/sm3.php
- name: Execute tests sm4
run: php tests/sm4.php

7
vendor/lizhichao/one-sm/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
/vendor
.idea
.vscode
.svn
.DS_Store
composer.lock
cache/

65
vendor/lizhichao/one-sm/.php_cs.dist vendored Normal file
View File

@@ -0,0 +1,65 @@
<?php
/*
* This document has been generated with
* https://mlocati.github.io/php-cs-fixer-configurator/#version:2.15|configurator
* you can change this configuration by importing this file.
*/
return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setIndent(' ')
->setRules([
'@PSR2' => true,
'@PhpCsFixer' => true,
'@Symfony:risky' => true,
'concat_space' => ['spacing' => 'one'],
'array_syntax' => ['syntax' => 'short'],
'array_indentation' => true,
'combine_consecutive_unsets' => true,
'method_separation' => true,
'single_quote' => true,
'declare_equal_normalize' => true,
'function_typehint_space' => true,
'hash_to_slash_comment' => true,
'include' => true,
'lowercase_cast' => true,
'no_multiline_whitespace_before_semicolons' => true,
'no_leading_import_slash' => true,
'no_multiline_whitespace_around_double_arrow' => true,
'no_spaces_around_offset' => true,
'no_unneeded_control_parentheses' => true,
'no_unused_imports' => true,
'no_whitespace_before_comma_in_array' => true,
'no_whitespace_in_blank_line' => true,
'object_operator_without_whitespace' => true,
'single_blank_line_before_namespace' => true,
'single_class_element_per_statement' => true,
'space_after_semicolon' => true,
'standardize_not_equals' => true,
'ternary_operator_spaces' => true,
'trailing_comma_in_multiline_array' => true,
'trim_array_spaces' => true,
'unary_operator_spaces' => true,
'whitespace_after_comma_in_array' => true,
'no_extra_consecutive_blank_lines' => [
'curly_brace_block',
'extra',
'parenthesis_brace_block',
'square_brace_block',
'throw',
'use',
],
'binary_operator_spaces' => [
'align_double_arrow' => true,
'align_equals' => true,
],
'braces' => [
'allow_single_line_closure' => true,
],
])
->setFinder(
PhpCsFixer\Finder::create()
->exclude('vendor')
->exclude('tests')
->in(__DIR__)
);

100
vendor/lizhichao/one-sm/README.md vendored Normal file
View File

@@ -0,0 +1,100 @@
## php国密算法
- sm3
- 字符串签名
- 文件签名
- sm4
- ecb
- cbc
- cfb
- ofb
- ctr
## 安装
```shell
composer require lizhichao/one-sm
```
## SM3签名
```php
<?php
require __DIR__ . '/vendor/autoload.php';
$sm3 = new \OneSm\Sm3();
// 字符串签名
echo $sm3->sign('abc') . PHP_EOL;
echo $sm3->sign(str_repeat("adfas哈哈哈", 100)) . PHP_EOL;
// 文件签名
echo $sm3->signFile(__FILE__) . PHP_EOL;
```
### 性能测试
和 [openssl](https://github.com/openssl/openssl) , [SM3-PHP](https://github.com/DongyunLee/SM3-PHP) 性能测试
```shell
php bench.php
```
结果
```
openssl:4901d7181a1024b8c0f59b8d3c5c6d96b4b707ad10e8ebc8ece5dc49364a3067
one-sm3:4901d7181a1024b8c0f59b8d3c5c6d96b4b707ad10e8ebc8ece5dc49364a3067
SM3-PHP:4901d7181a1024b8c0f59b8d3c5c6d96b4b707ad10e8ebc8ece5dc49364a3067
openssl time:6.3741207122803ms
one-sm3 time:8.1770420074463ms
SM3-PHP time:1738.5928630829ms
```
[测试代码bench.php](https://github.com/lizhichao/sm/blob/master/bench.php)
## SM4加密
```php
<?php
use OneSm\Sm4;
require __DIR__ . '/vendor/autoload.php';
$data = str_repeat('阿斯顿发到付eeee', 160);
$str_len = strlen($data);
// md5 签名
$sign = md5($data);
// 加密key必须为16位
$key = hex2bin(md5(1));
$sm4 = new Sm4($key);
// ECB加密
$d = $sm4->enDataEcb($data);
// 加密后的长度和原数据长度一致
var_dump(strlen($d) === $str_len);
// ECB解密
$d = $sm4->deDataEcb($d);
// 解密后和原数据相等
var_dump(md5($d) === $sign);
// 初始化向量16位
$iv = hex2bin(md5(2));
// CBC加密
$d = $sm4->enDataCbc($data, $iv);
// 加密后的长度和原数据长度一致
var_dump(strlen($d)===$str_len);
// CBC解密
$d = $sm4->deDataCbc($d, $iv);
// 解密后和原数据相等
var_dump(md5($d)===$sign);
```
## 我的其他仓库
* [一个极简高性能php框架支持[swoole | php-fpm ]环境](https://github.com/lizhichao/one)
* [clickhouse tcp 客户端](https://github.com/lizhichao/one-ck)
* [中文分词](https://github.com/lizhichao/VicWord)
* [nsq客户端](https://github.com/lizhichao/one-nsq)

97
vendor/lizhichao/one-sm/bench.php vendored Normal file
View File

@@ -0,0 +1,97 @@
<?php
// 性能测试
// composer require ch4o5/sm3-php
// 下面是随便一段话
//SM3是中华人民共和国政府采用的一种密码散列函数标准由国家密码管理局于2010年12月17日发布。相关标准为“GM/T 0004-2012 《SM3密码杂凑算法》”。
//在商用密码体系中SM3主要用于数字签名及验证、消息认证码生成及验证、随机数生成等其算法公开。据国家密码管理局表示其安全性及效率与SHA-256相当。
//中文名SM3外文名SM3领 域密码学
//目录
//1 简介
//2 密码散列函数
//▪ 特性
//3 SHA-2
//简介编辑
//SM3是中华人民共和国政府采用的一种密码散列函数标准由国家密码管理局于2010年12月17日发布。相关标准为“GM/T 0004-2012 《SM3密码杂凑算法》”。
//在商用密码体系中SM3主要用于数字签名及验证、消息认证码生成及验证、随机数生成等其算法公开。据国家密码管理局表示其安全性及效率与SHA-256相当。 [1]
//密码散列函数编辑
//密码散列函数英语Cryptographic hash function又译为加密散列函数、密码散列函数、加密散列函数是散列函数的一种。它被认为是一种单向函数也就是说极其难以由散列函数输出的结果回推输入的数据是什么。这样的单向函数被称为“现代密码学的驮马”。这种散列函数的输入数据通常被称为消息message而它的输出结果经常被称为消息摘要message digest或摘要digest
//在信息安全中,有许多重要的应用,都使用了密码散列函数来实现,例如数字签名,消息认证码。
//特性
//一个理想的密码散列函数应该有四个主要的特性:
//对于任何一个给定的消息,它都很容易就能运算出散列数值。
//难以由一个已知的散列数值,去推算出原始的消息。
//在不更动散列数值的前提下,修改消息内容是不可行的。
//对于两个不同的消息,它不能给与相同的散列数值。 [1]
//SHA-2编辑
//SHA-2名称来自于安全散列算法2英语Secure Hash Algorithm 2的缩写一种密码散列函数算法标准由美国国家安全局研发由美国国家标准与技术研究院NIST在2001年发布。属于SHA算法之一是SHA-1的后继者。其下又可再分为六个不同的算法标准包括了SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。 [2]
//SM3是中华人民共和国政府采用的一种密码散列函数标准由国家密码管理局于2010年12月17日发布。相关标准为“GM/T 0004-2012 《SM3密码杂凑算法》”。
//在商用密码体系中SM3主要用于数字签名及验证、消息认证码生成及验证、随机数生成等其算法公开。据国家密码管理局表示其安全性及效率与SHA-256相当。
//中文名SM3外文名SM3领 域密码学
//目录
//1 简介
//2 密码散列函数
//▪ 特性
//3 SHA-2
//简介编辑
//SM3是中华人民共和国政府采用的一种密码散列函数标准由国家密码管理局于2010年12月17日发布。相关标准为“GM/T 0004-2012 《SM3密码杂凑算法》”。
//在商用密码体系中SM3主要用于数字签名及验证、消息认证码生成及验证、随机数生成等其算法公开。据国家密码管理局表示其安全性及效率与SHA-256相当。 [1]
//密码散列函数编辑
//密码散列函数英语Cryptographic hash function又译为加密散列函数、密码散列函数、加密散列函数是散列函数的一种。它被认为是一种单向函数也就是说极其难以由散列函数输出的结果回推输入的数据是什么。这样的单向函数被称为“现代密码学的驮马”。这种散列函数的输入数据通常被称为消息message而它的输出结果经常被称为消息摘要message digest或摘要digest
//在信息安全中,有许多重要的应用,都使用了密码散列函数来实现,例如数字签名,消息认证码。
//特性
//一个理想的密码散列函数应该有四个主要的特性:
//对于任何一个给定的消息,它都很容易就能运算出散列数值。
//难以由一个已知的散列数值,去推算出原始的消息。
//在不更动散列数值的前提下,修改消息内容是不可行的。
//对于两个不同的消息,它不能给与相同的散列数值。 [1]
//SHA-2编辑
//SHA-2名称来自于安全散列算法2英语Secure Hash Algorithm 2的缩写一种密码散列函数算法标准由美国国家安全局研发由美国国家标准与技术研究院NIST在2001年发布。属于SHA算法之一是SHA-1的后继者。其下又可再分为六个不同的算法标准包括了SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。 [2]
//SM3是中华人民共和国政府采用的一种密码散列函数标准由国家密码管理局于2010年12月17日发布。相关标准为“GM/T 0004-2012 《SM3密码杂凑算法》”。
//在商用密码体系中SM3主要用于数字签名及验证、消息认证码生成及验证、随机数生成等其算法公开。据国家密码管理局表示其安全性及效率与SHA-256相当。
//中文名SM3外文名SM3领 域密码学
//目录
//1 简介
//2 密码散列函数
//▪ 特性
//3 SHA-2
//简介编辑
//SM3是中华人民共和国政府采用的一种密码散列函数标准由国家密码管理局于2010年12月17日发布。相关标准为“GM/T 0004-2012 《SM3密码杂凑算法》”。
//在商用密码体系中SM3主要用于数字签名及验证、消息认证码生成及验证、随机数生成等其算法公开。据国家密码管理局表示其安全性及效率与SHA-256相当。 [1]
//密码散列函数编辑
//密码散列函数英语Cryptographic hash function又译为加密散列函数、密码散列函数、加密散列函数是散列函数的一种。它被认为是一种单向函数也就是说极其难以由散列函数输出的结果回推输入的数据是什么。这样的单向函数被称为“现代密码学的驮马”。这种散列函数的输入数据通常被称为消息message而它的输出结果经常被称为消息摘要message digest或摘要digest
//在信息安全中,有许多重要的应用,都使用了密码散列函数来实现,例如数字签名,消息认证码。
//特性
//一个理想的密码散列函数应该有四个主要的特性:
//对于任何一个给定的消息,它都很容易就能运算出散列数值。
//难以由一个已知的散列数值,去推算出原始的消息。
//在不更动散列数值的前提下,修改消息内容是不可行的。
//对于两个不同的消息,它不能给与相同的散列数值。 [1]
//SHA-2编辑
//SHA-2名称来自于安全散列算法2英语Secure Hash Algorithm 2的缩写一种密码散列函数算法标准由美国国家安全局研发由美国国家标准与技术研究院NIST在2001年发布。属于SHA算法之一是SHA-1的后继者。其下又可再分为六个不同的算法标准包括了SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。 [2]
//参考资料
require __DIR__ . '/vendor/autoload.php';
$str = file_get_contents(__FILE__);
$t = microtime(true);
// 字符串签名
echo 'openssl:' . trim(str_replace('(stdin)=', '', exec('cat ' . __FILE__ . ' | openssl dgst -SM3'))) . PHP_EOL;;
$t1 = microtime(true);
// 字符串签名
echo 'one-sm3:' . (new \OneSm\Sm3)->sign($str) . PHP_EOL;
$t2 = microtime(true);
echo 'SM3-PHP:' . sm3($str) . PHP_EOL;
$t3 = microtime(true);
echo 'openssl time:'.($t1 - $t) * 1000 . 'ms' . PHP_EOL;
echo 'one-sm3 time:'.($t2 - $t1) * 1000 . 'ms' . PHP_EOL;
echo 'SM3-PHP time:'.($t3 - $t2) * 1000 . 'ms' . PHP_EOL;
// 文件签名
//echo \OneSm\Sm3::signFile(__FILE__) . PHP_EOL;

24
vendor/lizhichao/one-sm/composer.json vendored Normal file
View File

@@ -0,0 +1,24 @@
{
"name": "lizhichao/one-sm",
"type": "library",
"description": "国密sm3",
"keywords": [
"php",
"sm3"
],
"license": "Apache-2.0",
"authors": [
{
"name": "tanszhe",
"email": "1018595261@qq.com"
}
],
"require": {
"php": ">=5.6"
},
"autoload": {
"psr-4": {
"OneSm\\": "src/"
}
}
}

142
vendor/lizhichao/one-sm/src/Sm3.php vendored Normal file
View File

@@ -0,0 +1,142 @@
<?php
namespace OneSm;
class Sm3
{
private $IV = '7380166f4914b2b9172442d7da8a0600a96f30bc163138aae38dee4db0fb0e4e';
private $LEN = 512;
private $STR_LEN = 64;
public function sign($str)
{
$l = strlen($str) * 8;
$k = $this->getK($l);
$bt = $this->getB($k);
$str = $str . $bt . pack('J', $l);
$count = strlen($str);
$l = $count / $this->STR_LEN;
$vr = hex2bin($this->IV);
for ($i = 0; $i < $l; $i++) {
$vr = $this->cf($vr, substr($str, $i * $this->STR_LEN, $this->STR_LEN));
}
return bin2hex($vr);
}
private function getK($l)
{
$v = $l % $this->LEN;
return $v + $this->STR_LEN < $this->LEN
? $this->LEN - $this->STR_LEN - $v - 1
: ($this->LEN * 2) - $this->STR_LEN - $v - 1;
}
private function getB($k)
{
$arg = [128];
$arg = array_merge($arg, array_fill(0, intval($k / 8), 0));
return pack('C*', ...$arg);
}
public function signFile($file)
{
$l = filesize($file) * 8;
$k = $this->getK($l);
$bt = $this->getB($k) . pack('J', $l);
$hd = fopen($file, 'r');
$vr = hex2bin($this->IV);
$str = fread($hd, $this->STR_LEN);
if ($l > $this->LEN - $this->STR_LEN - 1) {
do {
$vr = $this->cf($vr, $str);
$str = fread($hd, $this->STR_LEN);
} while (!feof($hd));
}
$str = $str . $bt;
$count = strlen($str) * 8;
$l = $count / $this->LEN;
for ($i = 0; $i < $l; $i++) {
$vr = $this->cf($vr, substr($str, $i * $this->STR_LEN, $this->STR_LEN));
}
return bin2hex($vr);
}
private function t($i)
{
return $i < 16 ? 0x79cc4519 : 0x7a879d8a;
}
private function cf($ai, $bi)
{
$wr = array_values(unpack('N*', $bi));
for ($i = 16; $i < 68; $i++) {
$wr[$i] = $this->p1($wr[$i - 16]
^
$wr[$i - 9]
^
$this->lm($wr[$i - 3], 15))
^
$this->lm($wr[$i - 13], 7)
^
$wr[$i - 6];
}
$wr1 = [];
for ($i = 0; $i < 64; $i++) {
$wr1[] = $wr[$i] ^ $wr[$i + 4];
}
list($a, $b, $c, $d, $e, $f, $g, $h) = array_values(unpack('N*', $ai));
for ($i = 0; $i < 64; $i++) {
$ss1 = $this->lm(
($this->lm($a, 12) + $e + $this->lm($this->t($i), $i % 32) & 0xffffffff),
7);
$ss2 = $ss1 ^ $this->lm($a, 12);
$tt1 = ($this->ff($i, $a, $b, $c) + $d + $ss2 + $wr1[$i]) & 0xffffffff;
$tt2 = ($this->gg($i, $e, $f, $g) + $h + $ss1 + $wr[$i]) & 0xffffffff;
$d = $c;
$c = $this->lm($b, 9);
$b = $a;
$a = $tt1;
$h = $g;
$g = $this->lm($f, 19);
$f = $e;
$e = $this->p0($tt2);
}
return pack('N*', $a, $b, $c, $d, $e, $f, $g, $h) ^ $ai;
}
private function ff($j, $x, $y, $z)
{
return $j < 16 ? $x ^ $y ^ $z : ($x & $y) | ($x & $z) | ($y & $z);
}
private function gg($j, $x, $y, $z)
{
return $j < 16 ? $x ^ $y ^ $z : ($x & $y) | (~$x & $z);
}
private function lm($a, $n)
{
return ($a >> (32 - $n) | (($a << $n) & 0xffffffff));
}
private function p0($x)
{
return $x ^ $this->lm($x, 9) ^ $this->lm($x, 17);
}
private function p1($x)
{
return $x ^ $this->lm($x, 15) ^ $this->lm($x, 23);
}
}

350
vendor/lizhichao/one-sm/src/Sm4.php vendored Normal file
View File

@@ -0,0 +1,350 @@
<?php
namespace OneSm;
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);
}
}

3
vendor/lizhichao/one-sm/test.php vendored Normal file
View File

@@ -0,0 +1,3 @@
<?php
require __DIR__ . '/vendor/autoload.php';

41
vendor/lizhichao/one-sm/tests/sm3.php vendored Normal file
View File

@@ -0,0 +1,41 @@
<?php
require __DIR__ . '/../vendor/autoload.php';
function eq($a, $b)
{
if ($a !== $b) {
print_r([$a, '!==', $b]);
throw new \Exception('error');
}
print_r([$a, $b, 'true']);
}
function hmac($data = null, $secret = null, $raw_output = false)
{
$sm3 = new \OneSm\Sm3();
$size = \strlen($sm3->sign('test'));
$pack = 'H' . (string)$size;
if (\strlen($secret) > $size) {
$secret = pack($pack, $sm3->sign($secret));
}
$key = str_pad($secret, $size, \chr(0x00));
$ipad = $key ^ str_repeat(\chr(0x36), $size);
$opad = $key ^ str_repeat(\chr(0x5C), $size);
$hmac = $sm3->sign($opad . pack($pack, $sm3->sign($ipad . $data)));
return $raw_output ? pack($pack, $hmac) : $hmac;
}
$sm3 = new \OneSm\Sm3();
eq('66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0', $sm3->sign('abc'));
eq('1294da78431a20991584c68a669f2c59618e08bf0d7989f35f6ae1d7d570e143', $sm3->sign(str_repeat("adfas哈哈哈", 100)));
eq('1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b', $sm3->sign(''));
eq(
'8e4bd77d8a10526fae772bb6014dfaed0335491e1cdfa92d3aca1481ae5d9a83',
hmac(str_repeat('abc', 1000), 'secret')
);
eq(
hex2bin('8e4bd77d8a10526fae772bb6014dfaed0335491e1cdfa92d3aca1481ae5d9a83'),
hmac(str_repeat('abc', 1000), 'secret', true)
);

79
vendor/lizhichao/one-sm/tests/sm4.php vendored Normal file
View File

@@ -0,0 +1,79 @@
<?php
require __DIR__ . '/../vendor/autoload.php';
function eq($a, $b)
{
if ($a !== $b) {
print_r([$a, '!==', $b]);
throw new \Exception('error');
}
print_r([$a, $b, 'true']);
}
$data = str_repeat('阿斯顿发到付eeee', 160);
$str_len = strlen($data);
// md5 签名
$sign = md5($data);
// 加密key必须为16位
$key = hex2bin(md5(1));
$iv = hex2bin(md5(2));
$sm4 = new \OneSm\Sm4($key);
echo "\n --- ecb --- \n";
// 加密ecb
$d = $sm4->enDataEcb($data);
// 加密后的长度和原数据长度一致
eq(strlen($d), $str_len);
// 解密ecb
$d = $sm4->deDataEcb($d);
// 解密后和原数据相等
eq(md5($d), $sign);
echo "\n --- cbc --- \n";
// 加密cbc
$d = $sm4->enDataCbc($data, $iv);
// 加密后的长度和原数据长度一致
eq(strlen($d), $str_len);
// 解密cbc
$d = $sm4->deDataCbc($d, $iv);
// 解密后和原数据相等
eq(md5($d), $sign);
echo "\n --- ofb --- \n";
// 加密ofb
$d = $sm4->enDataOfb($data, $iv);
// 加密后的长度和原数据长度一致
eq(strlen($d), $str_len);
// 解密ofb
$d = $sm4->deDataOfb($d, $iv);
// 解密后和原数据相等
eq(md5($d), $sign);
echo "\n --- cfb --- \n";
// 加密cfb
$d = $sm4->enDatacfb($data, $iv);
// 加密后的长度和原数据长度一致
eq(strlen($d), $str_len);
// 解密cfb
$d = $sm4->deDatacfb($d, $iv);
// 解密后和原数据相等
eq(md5($d), $sign);
echo "\n --- ctr --- \n";
// 加密ctr
$d = $sm4->enDataCtr($data, $iv);
// 加密后的长度和原数据长度一致
eq(strlen($d), $str_len);
// 解密ctr
$d = $sm4->deDataCtr($d, $iv);
// 解密后和原数据相等
eq(md5($d), $sign);
//ecb/cbc/cfb/ofb/ctr