PHP 国密算法实现,包含 SM2、SM3、SM4 三大算法。
该项目是lpilp/phpsm2sm3sm4 用AI洗了洗,然后去掉了PHPECC组件,只使用了PHP原生态的组件,因为PHP原生态的组件更安全,目前是按PHP7来弄的,在PHP8里测试通过,目前没做兼容性测试。可能会报一些warning。
本库提供纯 PHP 实现的中国国家密码标准(国密)算法:
- SM2:椭圆曲线公钥密码算法,支持密钥对生成、数字签名(含 ASN.1 DER 格式)、非对称加解密
- SM3:密码杂凑算法(GB/T 32905-2016),支持哈希计算与 HMAC
- SM4:分组密码算法,支持 ECB 和 CBC 模式加解密
- PHP >= 7.4
- PHP
ext-gmp扩展(SM2 大数运算必需)
composer require aiphpsm/aiphpsmuse Aiphpsm\SM3;
// 计算哈希
$hash = SM3::hash('hello world');
echo $hash; // 64字符十六进制字符串
// HMAC-SM3
$hmac = SM3::hmac('data', 'secret_key');
echo $hmac;use Aiphpsm\SM4;
$key = SM4::generateKey(); // 生成随机密钥(hex)
$iv = SM4::generateIV(); // 生成随机IV(hex)
// ECB 模式
$ciphertext = SM4::encryptECB('Hello, SM4!', $key);
$plaintext = SM4::decryptECB($ciphertext, $key);
// CBC 模式
$ciphertext = SM4::encryptCBC('Hello, SM4!', $key, $iv);
$plaintext = SM4::decryptCBC($ciphertext, $key, $iv);use Aiphpsm\SM2;
// 生成密钥对
$keyPair = SM2::generateKeyPair();
$privateKey = $keyPair['privateKey']; // 64字符hex
$publicKey = $keyPair['publicKey']; // 130字符hex(04||x||y)
// 加密 / 解密
$ciphertext = SM2::encrypt('Hello, SM2!', $publicKey);
$plaintext = SM2::decrypt($ciphertext, $privateKey);
// 签名 / 验签(原始格式 r||s)
$signature = SM2::sign('message', $privateKey, $publicKey);
$valid = SM2::verify('message', $signature, $publicKey);
// 签名 / 验签(ASN.1 DER 格式)
$asn1Sig = SM2::signAsn1('message', $privateKey, $publicKey);
$valid = SM2::verifyAsn1('message', $asn1Sig, $publicKey);
// 从私钥推导公钥
$pubKey = SM2::getPublicKeyFromPrivate($privateKey);
// 验证公钥合法性
$isValid = SM2::isValidPublicKey($publicKey);| 方法 | 说明 |
|---|---|
SM3::hash(string $data): string |
计算 SM3 哈希,返回 64 字符 hex |
SM3::hmac(string $data, string $key): string |
计算 HMAC-SM3,返回 64 字符 hex |
| 方法 | 说明 |
|---|---|
SM4::generateKey(): string |
生成随机 128 位密钥(32 字符 hex) |
SM4::generateIV(): string |
生成随机 128 位 IV(32 字符 hex) |
SM4::encryptECB(string $plaintext, string $key): string |
ECB 模式加密,返回 hex |
SM4::decryptECB(string $ciphertext, string $key): string |
ECB 模式解密 |
SM4::encryptCBC(string $plaintext, string $key, ?string $iv): string |
CBC 模式加密,返回 hex |
SM4::decryptCBC(string $ciphertext, string $key, ?string $iv): string |
CBC 模式解密 |
| 方法 | 说明 |
|---|---|
SM2::generateKeyPair(): array |
生成密钥对,返回 ['privateKey'=>hex, 'publicKey'=>hex] |
SM2::getPublicKeyFromPrivate(string $privateKey): string |
从私钥推导公钥 |
SM2::isValidPublicKey(string $pubKey): bool |
验证公钥是否在曲线上 |
SM2::encrypt(string $plaintext, string $pubKey): string |
加密,返回 hex(C1||C3||C2) |
SM2::decrypt(string $ciphertext, string $privateKey): string |
解密 |
SM2::sign(string $message, string $privateKey, string $pubKey, string $idHex = ''): string |
签名,返回 128 字符 hex(r||s) |
SM2::verify(string $message, string $signature, string $pubKey, string $idHex = ''): bool |
验签 |
SM2::signAsn1(string $message, string $privateKey, string $pubKey, string $idHex = ''): string |
ASN.1 DER 格式签名 |
SM2::verifyAsn1(string $message, string $signature, string $pubKey, string $idHex = ''): bool |
ASN.1 DER 格式验签 |
SM2::rawSignatureToAsn1(string $rawHex): string |
原始签名转 ASN.1 DER |
SM2::asn1SignatureToRaw(string $asn1Hex): string|false |
ASN.1 DER 转原始签名 |
php tests/SM_Test.phpMIT License