zhangzc/crypto

纯国密算法,通过trae辅助生成

Maintainers

Details

gitee.com/zhangzhichao/crypto.git

Installs: 3

Dependents: 0

Suggesters: 0

Security: 0

pkg:composer/zhangzc/crypto

v1.0.0 2025-12-08 09:36 UTC

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!

联系

如有问题,请通过以下方式联系: