技术饭
php的openssl加密扩展实现
php的openssl加密扩展实现对称和非对称加密,openssl这个扩展也是随 PHP 源码一起发布的,编译安装的时候加上 --with-openssl 就可以了。当然,它也是需要系统环境中安装 OpenSSL 软件的,在各类操作系统中基本都已经直接有了,如果没有的话就自己安装一下即可。最简单的,在操作系统命令行看看有没有 openssl 命令就可以看出当前系统有没有安装 OpenSSL 相关的软件。
lpilp/phpsm2sm3sm4加密仓库:https://gitcode.net/mirrors/lpilp/phpsm2sm3sm4
先安装php的openssl扩展
一、对称加密
<?php
$data = '加密数据';
$key = '加密key';
$algorithm = 'DES-EDE-CFB'; // 加密算法
//生成iv偏移量
$ivlen = openssl_cipher_iv_length($algorithm); // 算法长度
$iv = openssl_random_pseudo_bytes($ivlen); // 生成iv
//加密
$password = openssl_encrypt($data, $algorithm, $key, 0, $iv);
echo $password, PHP_EOL; // 值:4PvOc75QkIJ184/RULdOTeO8
//解密
echo openssl_decrypt($password, $algorithm, $key, 0, $iv), PHP_EOL;
$algorithm = 'aes-128-gcm';
$password = openssl_encrypt($data, $algorithm, $key, 0, $iv, $tags);
echo $password, PHP_EOL; // dPYsR+sdP56rQ99CNxciah+N
echo openssl_decrypt($password, $algorithm, $key, 0, $iv, $tags), PHP_EOL;
// 对称加密算法查询
print_r(openssl_get_cipher_methods());
?>
二、非对称加密
1)、生成私钥
<?php
$config = array(
"private_key_bits" => 4096, // 指定应该使用多少位来生成私钥
);
$res = openssl_pkey_new($config); // 根据配置信息生成私钥
openssl_pkey_export($res, $privateKey); // 将一个密钥的可输出表示转换为字符串
var_dump($privateKey);
-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDFMLW+9t3fNX4C// ……
-----END PRIVATE KEY-----
2)、抽取公钥:公钥是从私钥抽取出来的
<?php
$publicKey = openssl_pkey_get_details($res); // 抽取公钥信息
var_dump($publicKey);
array(4) {
["bits"]=> int(4096)
["key"]=> string(800) "-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtOIImDdS0W0vAr5Ra1+EhR2AJwQQwxntYKgTku8EmJRBX2vU+x8th8W8SnoGiVM/sOItG0HIe4Egf1UxoZHt -----END PUBLIC KEY-----"
}
$publicKey = $publicKey['key'];
3)、加密解密数据
<?php
$data = '测试加密数据';
// 公钥加密数据
openssl_public_encrypt($data, $encrypted, $publicKey);
var_dump($encrypted);
// 私钥解密数据
openssl_private_decrypt($encrypted, $decrypted, $privateKey);
var_dump($decrypted); // string(21) "测试非对称加密"
4)、签名及验证
<?php
// 利用私钥生成签名
openssl_sign($data, $signature, $privateKey, OPENSSL_ALGO_SHA256);
var_dump($signature);
// 公钥验证签名
$r = openssl_verify($data, $signature, $publicKey, OPENSSL_ALGO_SHA256);
var_dump($r); // int(1)
三、证书生成
1)、生成 CSR 证书签名请求,https证书
<?php
//证书生成配置
$privkey = openssl_pkey_new([
"private_key_bits" => 2048,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
]);
//证书信息
$dn = [
"countryName" => "CN", // 国家
"stateOrProvinceName" => "Hunan", // 省
"localityName" => "Changsha", // 市
"organizationName" => "zyblog", // 公司单位名称
"organizationalUnitName" => "zyblog", // 公司单位名称
"commonName" => "zyblog.xxx", // 公用名称,一般可以填域名
"emailAddress" => "zy@zyblog.xxx" // 邮箱地址
];
//生成导出证书
$csr = openssl_csr_new($dn, $privkey, ['digest_alg' => 'sha256']);
openssl_csr_export($csr, $csr_string);
var_dump($csr_string);
-----BEGIN CERTIFICATE REQUEST-----
MIIC9DCCAdwCAQAwga4xCzAJBgNVBAYTAkdCMREwDwYDVQQIDAhTb21lcnNldDEUMBIGA1UEBwwLR2xhc3RvbmJ1cnkxHzAdBgNVBAoMFlRoZSBCcmFpbiBSb29tIExp
-----END CERTIFICATE REQUEST-----"
//获取公钥
$public_key = openssl_csr_get_public_key($csr);
$info = openssl_pkey_get_details($public_key);
var_dump($info['key']);
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvDBrEHxkWucb/YQlzccObbgzlTficOAglSEDPBybnWXGfQRiqRij/QGyCPGVH9Ex7UTogsOp67+Jj0h8ikCDrCeomRfM7U95NBXrJJdELZFf6twXNBBNB4d8PL96LIatSGpjCDbBXemuIVi2T7Rli6towHxNjQuSILnUadmQIDAQAB
-----END PUBLIC KEY-----
//获取公钥证书信息
print_r(openssl_csr_get_subject($csr));
Array
(
[C] => CN
[ST] => Hunan
[L] => Changsha
[O] => zyblog
[OU] => zyblog
[CN] => zyblog.xxx
[emailAddress] => zy@zyblog.xxx
)
2)、证书签名及生成 x509 证书
<?php
$usercert = openssl_csr_sign($csr, NULL, $privkey, 365, array('digest_alg'=>'sha256'));
// 证书签名,返回 x509 证书资源
openssl_x509_export($usercert, $certout_string);
var_dump($certout_string);
-----BEGIN CERTIFICATE-----
MIID1zCCAr+gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBhTELMAkGA1UEBhMCQ04xDjAMBgNVBAgMBUh1bmFuMREwDwYDVQQHDAhDaGFuZ3NoYTEPMA0GA1UECgwGenli
-----END CERTIFICATE-----
var_dump(openssl_x509_check_private_key($certout_string, $privkey)); // bool(true)
var_dump(openssl_x509_verify($certout_string, $info['key'])); // bool(true)
3)、pkcs 证书操作
openssl_pkcs12_export ($usercert,$pkcs_string, $privkey, '123123' );
var_dump($pkcs_string);
openssl_pkcs12_read($pkcs_string, $certs, '123123');
var_dump($certs);
-----BEGIN CERTIFICATE-----
MIID1zCCAr+gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBhTELMAkGA1UEBhMCQ04xDjAMBgNVBAgMBUh1bmFuMREwDwYDVQQHDAhDaGFuZ3NoYTEPMA0GA1UECgwGenli
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCrbNHa2lFTBMwwzO0roPBLugmNa7Yij6zsIPYIdIm3x5oFCaZKsnMrynlZGZquEjs6ZXVVALB3tTKx
-----END PRIVATE KEY-----
//导出x509
openssl_x509_export($certs['cert'], $certout_string);
var_dump($certout_string);
-----BEGIN CERTIFICATE-----
MIID1zCCAr+gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBhTELMAkGA1UEBhMCQ04xDjAMBgNVBAgMBUh1bmFuMREwDwYDVQQHDAhDaGFuZ3NoYTEPMA0GA1UECgwGenli
-----END CERTIFICATE-----
//验证x509
var_dump(openssl_x509_check_private_key($certout_string, $privkey)); // bool(true)
参考:
PHP的OpenSSL加密扩展学习(一):https://www.bilibili.com/video/BV1ov41157GZ,查看文档
PHP的OpenSSL加密扩展学习(二):https://www.bilibili.com/video/BV1bf4y1Y7Be,查看文档
PHP的OpenSSL加密扩展学习(三):https://www.bilibili.com/video/BV1v44y1z7em,查看文档
文明上网理性发言!