zhangzc / crypto
纯国密算法,通过trae辅助生成
v1.0.0
2025-12-08 09:36 UTC
Requires
- php: >=7.2.0
- ext-gmp: *
This package is not auto-updated.
Last update: 2025-12-09 07:46:22 UTC
README
一个纯PHP实现的国密算法库,支持SM2、SM3、SM4算法,符合GM/T系列标准。
特性
- ✅ SM2 椭圆曲线加密算法 (GM/T 0003-2012)
- 支持压缩公钥(02/03前缀66位格式)和非压缩公钥(04前缀130位格式)
- 支持公钥点恢复
- 支持多种公钥格式输入
- ✅ SM3 哈希算法 (GM/T 0004-2012)
- ✅ SM4 对称加密算法 (GM/T 0002-2012)
- ✅ 支持PHP 7.2+
- ✅ 纯PHP实现,依赖少
- ✅ 支持PSR-4自动加载
- ✅ 完整的异常处理
依赖要求
- PHP >= 7.2
- gmp 扩展 (仅SM2算法需要)
安装
使用Composer安装:
composer require zhangzc/crypto
快速开始
SM3哈希算法
use Zhangzc\Crypto\SM3;
// 计算字符串的SM3哈希值
$hash = SM3::hash('abc');
echo $hash; // 输出: 66C7F0F462EEEDD9D1F2D46BDC10E4E24167C4875CF2F7A2297DA02B8F4BA8E0
// 计算HMAC-SM3值
$key = '1234567890abcdef';
$input = 'test message';
$hmac = SM3::hmac($input, $key);
SM4对称加密算法
use Zhangzc\Crypto\SM4;
// 密钥(16字节)
$key = 'abcdef0123456789';
$plaintext = '这是一个测试消息';
// ECB模式加密解密
$encrypted = SM4::encrypt($plaintext, $key, SM4::MODE_ECB, SM4::PADDING_PKCS7);
$decrypted = SM4::decrypt($encrypted, $key, SM4::MODE_ECB, SM4::PADDING_PKCS7);
// CBC模式加密解密
$iv = '0123456789abcdef'; // IV必须是16字节
$encrypted = SM4::encrypt($plaintext, $key, SM4::MODE_CBC, SM4::PADDING_PKCS7, $iv);
$decrypted = SM4::decrypt($encrypted, $key, SM4::MODE_CBC, SM4::PADDING_PKCS7, $iv);
SM2椭圆曲线加密算法
use Zhangzc\Crypto\SM2;
// 生成密钥对
// 默认生成非压缩公钥
$keyPair = SM2::generateKeyPair();
$privateKey = $keyPair['privateKey']; // 64字节十六进制字符串
$publicKey = $keyPair['publicKey']; // 128字节十六进制字符串(无前缀)
// 生成压缩公钥
$keyPair = SM2::generateKeyPair(true);
$compressedPublicKey = $keyPair['publicKey']; // 66字节十六进制字符串(02/03前缀)
// 加密解密(支持压缩和非压缩公钥)
$plaintext = '这是一个测试消息';
$encrypted = SM2::encrypt($plaintext, $compressedPublicKey);
$decrypted = SM2::decrypt($encrypted, $privateKey);
// 签名验证(支持压缩和非压缩公钥)
$signature = SM2::sign($plaintext, $privateKey);
$verified = SM2::verify($plaintext, $signature, $compressedPublicKey);
// 支持多种公钥格式
// 格式1: 压缩公钥(02/03前缀,66位)
$compressedPubKey = '02675bd47c879314daf7322d8996caa5f597ef35341f030e9d423e9f1b2b4d8faa';
// 格式2: 非压缩公钥(04前缀,130位)
$uncompressedPubKeyWithPrefix = '04675bd47c879314daf7322d8996caa5f597ef35341f030e9d423e9f1b2b4d8faa39b836745808d61679b0896238297081a49c02a53233e93041429140b8e7b5c5';
// 格式3: 非压缩公钥(无前缀,128位)
$uncompressedPubKeyWithoutPrefix = '675bd47c879314daf7322d8996caa5f597ef35341f030e9d423e9f1b2b4d8faa39b836745808d61679b0896238297081a49c02a53233e93041429140b8e7b5c5';
// 所有格式都可以直接用于加密和验证
$encrypted1 = SM2::encrypt($plaintext, $compressedPubKey);
$encrypted2 = SM2::encrypt($plaintext, $uncompressedPubKeyWithPrefix);
$encrypted3 = SM2::encrypt($plaintext, $uncompressedPubKeyWithoutPrefix);
API文档
SM3类
hash(string $data, bool $rawOutput = false): string
- 参数:
$data: 输入数据$rawOutput: 是否返回原始二进制数据,默认返回十六进制字符串
- 返回: 哈希结果
hmac(string $data, string $key, bool $rawOutput = false): string
- 参数:
$data: 输入数据$key: HMAC密钥$rawOutput: 是否返回原始二进制数据,默认返回十六进制字符串
- 返回: HMAC-SM3结果
SM4类
encrypt(string $data, string $key, string $mode = 'ecb', string $padding = 'pkcs7', string $iv = ''): string
- 参数:
$data: 明文数据$key: 密钥(必须16字节)$mode: 加密模式,支持'ecb'和'cbc'$padding: 填充方式,支持'pkcs7'和'zero'$iv: CBC模式下的初始向量(必须16字节)
- 返回: 密文(base64编码)
- 异常: 当参数不合法时抛出
CryptoException
decrypt(string $data, string $key, string $mode = 'ecb', string $padding = 'pkcs7', string $iv = ''): string
- 参数:
$data: 密文数据(base64编码)$key: 密钥(必须16字节)$mode: 加密模式,支持'ecb'和'cbc'$padding: 填充方式,支持'pkcs7'和'zero'$iv: CBC模式下的初始向量(必须16字节)
- 返回: 明文
- 异常: 当参数不合法或解密失败时抛出
CryptoException
SM2类
generateKeyPair(bool $compressed = false): array
- 参数:
$compressed: 是否生成压缩公钥,默认为false(生成非压缩公钥)
- 返回: 包含私钥和公钥的数组
['privateKey' => string, 'publicKey' => string]privateKey: 64字节十六进制字符串publicKey: 根据$compressed参数返回不同格式- false: 128字节十六进制字符串(无前缀非压缩公钥)
- true: 66字节十六进制字符串(02/03前缀压缩公钥)
- 异常: 当gmp扩展不可用时抛出
CryptoException
encrypt(string $data, string $publicKey): string
- 参数:
$data: 明文数据$publicKey: 公钥,支持以下格式:- 压缩公钥:66位十六进制字符串,以02或03开头
- 非压缩公钥:130位十六进制字符串,以04开头
- 非压缩公钥:128位十六进制字符串,无前缀
- 返回: 密文(base64编码)
- 异常: 当参数不合法时抛出
CryptoException
decrypt(string $data, string $privateKey): string
- 参数:
$data: 密文数据(base64编码)$privateKey: 私钥(必须64字节十六进制字符串)
- 返回: 明文
- 异常: 当参数不合法或解密失败时抛出
CryptoException
sign(string $data, string $privateKey, string $userId = '1234567812345678'): string
- 参数:
$data: 待签名数据$privateKey: 私钥(必须64字节十六进制字符串)$userId: 用户ID(可选,默认值为 '1234567812345678')
- 返回: 签名(base64编码)
- 异常: 当参数不合法时抛出
CryptoException
verify(string $data, string $signature, string $publicKey, string $userId = '1234567812345678'): bool
- 参数:
$data: 原始数据$signature: 签名(base64编码)$publicKey: 公钥,支持以下格式:- 压缩公钥:66位十六进制字符串,以02或03开头
- 非压缩公钥:130位十六进制字符串,以04开头
- 非压缩公钥:128位十六进制字符串,无前缀
$userId: 用户ID(可选,默认值为 '1234567812345678')
- 返回: 验证结果(true表示通过,false表示失败)
- 异常: 当参数不合法时抛出
CryptoException
运行测试
由于测试文件结构已更新,建议使用Composer的测试工具运行测试:
composer test
或者直接运行特定的测试文件(如果存在):
php test_sm2.php
php test_sm3.php
php test_sm4.php
异常处理
所有算法都可能抛出 Zhangzc\Crypto\Exception\CryptoException 异常,建议使用try-catch进行处理:
use Zhangzc\Crypto\SM4;
use Zhangzc\Crypto\Exception\CryptoException;
try {
$encrypted = SM4::encrypt($plaintext, $key);
$decrypted = SM4::decrypt($encrypted, $key);
} catch (CryptoException $e) {
echo "错误: " . $e->getMessage();
}
许可证
MIT License
标准参考
- SM2: GM/T 0003-2012 《SM2椭圆曲线公钥密码算法》
- SM3: GM/T 0004-2012 《SM3密码杂凑算法》
- SM4: GM/T 0002-2012 《SM4分组密码算法》
贡献
欢迎提交Issue和Pull Request!
联系
如有问题,请通过以下方式联系:
- GitHub: https://github.com/yourusername/crypto
- Email: your.email@example.com