# crypto **Repository Path**: zhangzhichao/crypto ## Basic Information - **Project Name**: crypto - **Description**: 通过traes生成的,纯血PHP国密工具 - **Primary Language**: PHP - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-08 - **Last Updated**: 2025-12-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Zhangzc\Crypto - 国密算法PHP库 一个纯PHP实现的国密算法库,支持SM2、SM3、SM4算法,符合GM/T系列标准。 ## 特性 - ✅ SM2 椭圆曲线加密算法 (GM/T 0003-2012) - 支持压缩公钥(02/03前缀66位格式)和非压缩公钥(04前缀130位格式) - 支持公钥点恢复 - 支持多种公钥格式输入 - ✅ SM3 哈希算法 (GM/T 0004-2012) - 支持标准哈希计算 - 支持HMAC-SM3计算 - 支持防止时序攻击的哈希验证 - 支持防止时序攻击的HMAC验证 - ✅ SM4 对称加密算法 (GM/T 0002-2012) - ✅ 支持PHP 7.2+ - ✅ 纯PHP实现,依赖少 - ✅ 支持PSR-4自动加载 - ✅ 完整的异常处理 ## 依赖要求 - PHP >= 7.2 - gmp 扩展 (仅SM2算法需要) ## 安装 使用Composer安装: ```bash composer require zhangzc/crypto ``` ## 快速开始 ### SM3哈希算法 ```php use Zhangzc\Crypto\SM3; // 计算字符串的SM3哈希值 $hash = SM3::hash('abc'); echo $hash; // 输出: 66C7F0F462EEEDD9D1F2D46BDC10E4E24167C4875CF2F7A2297DA02B8F4BA8E0 // 计算HMAC-SM3值 $key = '1234567890abcdef'; $input = 'test message'; $hmac = SM3::hmac($input, $key); echo PHP_EOL . "HMAC值: " . $hmac; // 1. 验证哈希值(防止时序攻击)示例 $hashToVerify = '66C7F0F462EEEDD9D1F2D46BDC10E4E24167C4875CF2F7A2297DA02B8F4BA8E0'; $isValid = SM3::hashVerify('abc', $hashToVerify); echo PHP_EOL . "哈希验证结果: " . ($isValid ? "有效" : "无效"); // 2. 验证HMAC值(防止时序攻击)示例 $hmacToVerify = $hmac; // 从上面计算的HMAC值 $isValidHmac = SM3::hmacVerify($input, $key, $hmacToVerify); echo PHP_EOL . "HMAC验证结果: " . ($isValidHmac ? "有效" : "无效"); // 3. 使用不同格式验证哈希值示例 $data = "测试数据"; $hexHash = SM3::hash($data); // 计算十六进制格式哈希 $base64Hash = base64_encode(hex2bin($hexHash)); // 转换为base64格式 // 验证base64格式的哈希值 $isValidBase64 = SM3::hashVerify($data, $base64Hash, 'text', 'base64'); echo PHP_EOL . "Base64格式哈希验证结果: " . ($isValidBase64 ? "有效" : "无效"); // 4. 使用不同格式验证HMAC值示例 $hexHmac = SM3::hmac($data, $key); // 计算十六进制格式HMAC $base64Hmac = base64_encode(hex2bin($hexHmac)); // 转换为base64格式 // 验证base64格式的HMAC值 $isValidBase64Hmac = SM3::hmacVerify($data, $key, $base64Hmac, 'text', 'text', 'base64'); echo PHP_EOL . "Base64格式HMAC验证结果: " . ($isValidBase64Hmac ? "有效" : "无效"); ``` ### SM4对称加密算法 ```php 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椭圆曲线加密算法 ```php 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结果 #### `hmacVerify(string $data, string $key, string $hmac, string $dataFormat = 'text', string $keyFormat = 'text', string $hmacFormat = 'hex'): bool` - **参数**: - `$data`: 输入数据,可以是任意长度的字符串 - `$key`: 密钥,可以是任意长度的字符串 - `$hmac`: 待验证的HMAC值 - `$dataFormat`: 数据输入格式,可选值:'text'、'base64'、'hex',默认值:'text' - `$keyFormat`: 密钥输入格式,可选值:'text'、'base64'、'hex',默认值:'text' - `$hmacFormat`: 待验证HMAC的格式,可选值:'text'、'base64'、'hex',默认值:'hex' - **返回**: 验证结果(true表示通过,false表示失败) - **说明**: 使用恒定时间比较防止时序攻击 #### `hashVerify(string $data, string $hash, string $dataFormat = 'text', string $hashFormat = 'hex'): bool` - **参数**: - `$data`: 输入数据,可以是任意长度的字符串 - `$hash`: 待验证的哈希值 - `$dataFormat`: 数据输入格式,可选值:'text'、'base64'、'hex',默认值:'text' - `$hashFormat`: 待验证哈希的格式,可选值:'text'、'base64'、'hex',默认值:'hex' - **返回**: 验证结果(true表示通过,false表示失败) - **说明**: 使用恒定时间比较防止时序攻击 ### 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的测试工具运行测试: ```bash composer test ``` 或者直接运行特定的测试文件(如果存在): ```bash php test_sm2.php php test_sm3.php php test_sm4.php ``` ## 异常处理 所有算法都可能抛出 `Zhangzc\Crypto\Exception\CryptoException` 异常,建议使用try-catch进行处理: ```php 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分组密码算法》