更新
This commit is contained in:
5
vendor/lizhichao/one-sm/.github/FUNDING.yml
vendored
Normal file
5
vendor/lizhichao/one-sm/.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# 如果对你有帮助 欢迎打赏
|
||||
|
||||
custom: ["https://www.vicsdf.com/img/z.jpg","https://www.vicsdf.com/img/w.jpg"]
|
||||
|
||||
|
||||
33
vendor/lizhichao/one-sm/.github/workflows/sm.yml
vendored
Normal file
33
vendor/lizhichao/one-sm/.github/workflows/sm.yml
vendored
Normal 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
7
vendor/lizhichao/one-sm/.gitignore
vendored
Normal 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
65
vendor/lizhichao/one-sm/.php_cs.dist
vendored
Normal 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
100
vendor/lizhichao/one-sm/README.md
vendored
Normal 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
97
vendor/lizhichao/one-sm/bench.php
vendored
Normal 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
24
vendor/lizhichao/one-sm/composer.json
vendored
Normal 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
142
vendor/lizhichao/one-sm/src/Sm3.php
vendored
Normal 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
350
vendor/lizhichao/one-sm/src/Sm4.php
vendored
Normal 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
3
vendor/lizhichao/one-sm/test.php
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
41
vendor/lizhichao/one-sm/tests/sm3.php
vendored
Normal file
41
vendor/lizhichao/one-sm/tests/sm3.php
vendored
Normal 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
79
vendor/lizhichao/one-sm/tests/sm4.php
vendored
Normal 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
|
||||
Reference in New Issue
Block a user