PHP生成RSA密钥对及RSA签名验证类库
一,PHP生成RSA密钥对 PKCS#1 或者PKCS#8
$rtype = "PKCS#8"; //PKCS#1;
$rlen = "1024"; //1024/2048/3072;
$config = array (
'private_key_bits' => $rlen,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
);
//生成密钥对
$res = openssl_pkey_new($config);
//根据类型导出私钥
if($rtype=='PKCS#8'){
openssl_pkey_export($res, $private_key_pem, null, [
'encrypt_key' => false,
'format' => OPENSSL_KEYFORMAT_PKCS8, // 指定 PKCS#8
'private_key_bits' => $rlen,
]);
}else{
openssl_pkey_export($res, $private_key_pem,null,[
'encrypt_key' => false,
'private_key_bits' => $rlen,
]);
}
//获取公钥
$details = openssl_pkey_get_details($res);
$publicKey = $details['key'];
echo "私钥:".$private_key_pem."\r\n";
echo "公钥:".$publicKey;
私钥:
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDcylWSrlltd/ou
Fv6OsThWYbN7GZlJgMLrgWDTNy0zCZ2ciuMhjpmPd1DJpvHsTe1/uUghkye828Ty
CvUIxmAlxqxL8cGbAemQ/Bi+4I0PBNY25bHju2PYWxiv1DvB7MZGD8HthyKyZwJM
SVT6JvjAlobvroZbzMBZvzHWlcV4R0ugLiqQMzPzK6ehAoeuxKHOxPy1yJj231PI
GA+Ph7I5Ffp0n9gssGeDJjWauOH+4tw+X9PWGWFvbqWAODyCiKVC/4RgDNgZsv8z
15THcb4IuSeQEA6zBxSTKQtlbYD2evVs4Cpav82+NZ1yz9itc7S+xdIUrxBpugS2
bY2l03Y5AgMBAAECggEBAJOcNl/Nbn5QUxOTTfbKJtchlKP9Nk0855QZuEkdv3s6
t4PcGwPpWWLgK0PV+DG628ijb8T6o/uQlngXuUB3l/pJfBF9/KkMO0IyOL0MVWIw
IqMrJ6YQNy2DodqTsqvxB5H5oPaTfS/2zEOCV2yyt2XSfT4q2SrwlbyqpcBH+3Bw
Q4Z1WCg9C7PXn+nyJa4fsWHBnxR8k2zsVq/FTTyQQqTKVWj8TDiinwWqdT4dc3qp
C7zpDDiPr6kaG615X4Py/x5DAtOBhyiy82Knjvoajp0ZGOU44RrPhYT8HRa0jXKN
ei5z/pv9Vn2M++GwlyUqdLRx7ZN0qqiOelFeqDwTeYECgYEA+7iDXBfkjVnpM79m
bD5UgJI7SWtxZSqreiWQdsmV08agunt+LyrrxHIV2+odltIxGExjD7B/UV1A4XEH
Cstx4qfAigrWvcVg7hlt3SYQxfrALfdokdrIbZCM73bcOpz8tuJ0ZhirgNunTFjz
W7G6FwAW42U2XEeYUhL3dAoo6hECgYEA4Is2W2HGwq93SMIra5gjJg9ZnZEBPQ41
ne7cAcSoD+fZwvK8QhHcJnNq+k28x+MsCkTSPe33u3+b5ClugJEpH6CXY8qbi+24
pb63mnEmTbeVWDBDYEmDsbeM13G7wav+QS6Z5Q808OK+94KedmrfvaoT/odakOrz
sVeiYPGY4akCgYBrcfjwKGqwQz6djgdkEL71GnYgArKmYi5LtxkQ+z7u5Ivazbew
3ntAoQnfkvEKXbIDEyf9nHLcAhgdoqdE3k5AVyaCRdofqs6TE1un2AW03DGH7WE/
UMnYqqjd1jhu9G+SiNrycXlTSW8B0b4e15/9DVa3vY4UmaLU9a+WYnfQYQKBgQCj
kwZwH5RpsuVUrY5v/Q5t5XTFIiMi1T0d5imDaD1+CMpMCAQ4pUYZBK+D1CmX+9fT
SztVPgvgHR/1YHFNW3H3xkdCvQ//KZf/tiWObqsWpow3CEGs3SEAz9PcBtBeT+sS
lN4rTZ6ldKjlKdRCM6z2P/X8z6GcPGx2Xn693IIgsQKBgCesH8Ef/v2W563rmteR
p97bgeSVMasdpsywlyjJpClSrV0HrdJXNZiaG07Q7UjrmmlwIzJSce3ChrvOEh1O
NjmfolFTTvOtZF95Q95yHuX2YqE/wBzzYEwg6r0sBXbVbqYhwKqCaTDMEmk501tM
/Dlw3HQ/35EbHVYhFvQat/rb
-----END PRIVATE KEY-----
公钥:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3MpVkq5ZbXf6Lhb+jrE4
VmGzexmZSYDC64Fg0zctMwmdnIrjIY6Zj3dQyabx7E3tf7lIIZMnvNvE8gr1CMZg
JcasS/HBmwHpkPwYvuCNDwTWNuWx47tj2FsYr9Q7wezGRg/B7YcismcCTElU+ib4
wJaG766GW8zAWb8x1pXFeEdLoC4qkDMz8yunoQKHrsShzsT8tciY9t9TyBgPj4ey
ORX6dJ/YLLBngyY1mrjh/uLcPl/T1hlhb26lgDg8goilQv+EYAzYGbL/M9eUx3G+
CLknkBAOswcUkykLZW2A9nr1bOAqWr/NvjWdcs/YrXO0vsXSFK8QaboEtm2NpdN2
OQIDAQAB
-----END PUBLIC KEY-----
二,常用封装类库默认sha1和支持各种其它算法的加密与验证,例如sha256
<?php
class Rsa
{
/**
* @var string
*/
public $publicKey = '';
/**
* @var string
*/
public $privateKey = '';
/**
* * public key
*/
public $_pubKey;
/**
* * public key
*/
public $_privKey;
/**
* @var int
*/
public $RSA_ENCRYPT_BLOCK_SIZE = 117;//加密切割长度
/**
* @var int
*/
public $RSA_DECRYPT_BLOCK_SIZE = 128;//解密切割长度
/**
* * the construtor,the param $path is the keys saving path
* @param string $publicKey 公钥
* @param string $privateKey 私钥
*/
public function __construct($publicKey = null, $privateKey = null)
{
$this->setKey($publicKey, $privateKey);
}
/**
* 设置公钥和私钥
* @param string $publicKey 公钥
* @param string $privateKey 私钥
*/
public function setKey($publicKey = null, $privateKey = null)
{
if (!is_null($publicKey)) {
$this->publicKey = $publicKey;
}
if (!is_null($privateKey)) {
$this->privateKey = $privateKey;
}
}
/**
* * 设置私钥
*/
private function setupPrivKey()
{
if (is_resource($this->privateKey)) {
return true;
}
$pem = chunk_split($this->privateKey, 64, "\n");
$pem = "-----BEGIN PRIVATE KEY-----\n" . $pem . "-----END PRIVATE KEY-----\n";
$this->_privKey = openssl_pkey_get_private($pem);
return true;
}
/**
* * 设置公钥
*/
private function setupPubKey()
{
if (is_resource($this->publicKey)) {
return true;
}
$pem = chunk_split($this->publicKey, 64, "\n");
$pem = "-----BEGIN PUBLIC KEY-----\n" . $pem . "-----END PUBLIC KEY-----\n";
$this->_pubKey = openssl_pkey_get_public($pem);
return true;
}
/**
* * 私钥加密
* @param $data
* @return string|null
*/
public function privEncrypt($data)
{
if (!is_string($data)) {
return null;
}
//设置私钥
$this->setupPrivKey();
$result='';
$data = str_split($data, $this->RSA_ENCRYPT_BLOCK_SIZE);
foreach ($data as $block) {
$isEncrypted=openssl_private_encrypt($block, $dataEncrypt,$this->_privKey);
if (!$isEncrypted)
{
continue ;
}
$result .= $dataEncrypt;
}
return $result ? base64_encode($result) : null;
}
/**
* * 私钥解密
* @param $encrypted
* @return string|null
*/
public function privDecrypt($encrypted)
{
if (!is_string($encrypted)) {
return null;
}
$this->setupPrivKey();
$encrypted = base64_decode($encrypted);
$data = str_split($encrypted, $this->RSA_DECRYPT_BLOCK_SIZE);
$decrypt = '';
foreach ($data as $key => $chunk)
{
$isEncrypted=openssl_private_decrypt($chunk, $encrypted, $this->_privKey);
if (!$isEncrypted)
{
continue ;
}
$decrypt .= $encrypted;
}
if ($decrypt) {
return $decrypt;
}
return null;
}
/**
* * 公钥加密
* @param $data
* @return string|null
*/
public function pubEncrypt($data)
{
if (!is_string($data)) {
return null;
}
//设置公钥
$this->setupPubKey();
//分割
$plainData = str_split($data, $this->RSA_ENCRYPT_BLOCK_SIZE);
$encrypt="";
foreach ($plainData as $key => $encrypt_item)
{
$isEncrypted=openssl_public_encrypt($encrypt_item, $encrypted, $this->_pubKey);
if (!$isEncrypted)
{
continue ;
}
$encrypt .= $encrypted;
}
if($encrypt){
return base64_encode($encrypt);
}
return null;
}
/**
* * 公钥解密
* @param $crypted
* @return string|null
*/
public function pubDecrypt($crypted)
{
if (!is_string($crypted)) {
return null;
}
$this->setupPubKey();
$decrypted = base64_decode($crypted);
$data = str_split($decrypted, $this->RSA_DECRYPT_BLOCK_SIZE);
$decrypt = '';
foreach ($data as $key => $chunk)
{
$isDecrypted=openssl_public_decrypt($chunk, $encrypted, $this->_pubKey);
if (!$isDecrypted)
{
continue;
}
$decrypt .= $encrypted;
}
if ($decrypt) {
return $decrypt;
}
return null;
}
/**
* 构造签名
* @param string $dataString 被签名数据
* @return string
*/
public function sign($dataString)
{
$this->setupPrivKey();
$signature = false;
openssl_sign($dataString, $signature, $this->_privKey);
return base64_encode($signature);
}
/**
* 验证签名
* @param string $dataString 被签名数据
* @param string $signString 已经签名的字符串
* @return number 1签名正确 0签名错误
*/
public function verify($dataString, $signString)
{
$this->setupPubKey();
$signature = base64_decode($signString);
return openssl_verify($dataString, $signature, $this->_pubKey);
}
/**
* 构造签名
* @param string $dataString 被签名数据 指定加密算法
* @param string $alg 签名算法
* @return string
*/
public function signWithRsa($dataString, $alg='sha256')
{
$this->setupPrivKey();
$signature = false;
openssl_sign($dataString, $signature, $this->_privKey, $alg);
return base64_encode($signature);
}
/**
* 验证签名 指定加密算法
* @param string $dataString 被签名数据
* @param string $signString 已经签名的字符串
* @param string $alg 签名算法
* @return number 1签名正确 0签名错误
*/
public function verifyWithRsa($dataString, $signString, $alg='sha256')
{
$this->setupPubKey();
$signature = base64_decode($signString);
return openssl_verify($dataString, $signature, $this->_pubKey, $alg);
}
public function __destruct()
{
is_resource($this->_privKey) && @openssl_free_key($this->_privKey);
is_resource($this->_pubKey) && @openssl_free_key($this->_pubKey);
}
}
三,基于ECC(椭圆曲线加密)比RSA更轻量,安全效率更高

<?php
// 指定使用的曲线(推荐 prime256v1,也称 secp256r1)
$config = [
"private_key_type" => OPENSSL_KEYTYPE_EC,
"curve_name" => "prime256v1",
];
// 生成 ECC 密钥对
$res = openssl_pkey_new($config);
// 导出私钥(PEM 格式)
openssl_pkey_export($res, $privKey);
// 提取公钥(PEM 格式)
$pubKeyDetails = openssl_pkey_get_details($res);
$pubKey = $pubKeyDetails['key'];
echo "私钥:\n$privKey\n";
echo "公钥:\n$pubKey\n";
?>


PHP中常见的问题点,知识点,及盲点。

浙公网安备 33010602011771号