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更轻量,安全效率更高

image

 

<?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";
?>

 

image

 

image

 

posted @ 2025-11-13 11:55  sblack  阅读(7)  评论(0)    收藏  举报