php使用RSA加解密

2021-09-06

加解密类

/**
 * @description: RSA加解密
 */
class RSA
{
    /**
     * @description: 公钥加密
     * @var string
     */
    const PUBLIC_ENCRYPT  = 'openssl_public_encrypt';

    /**
     * @description: 公钥解密
     * @var string
     */
    const PUBLIC_DECRYPT  = 'openssl_public_decrypt';
    
    /**
     * @description: 私钥加密
     * @var string
     */
    const PRIVATE_ENCRYPT = 'openssl_private_encrypt';
    
    /**
     * @description: 私钥解密
     * @var string
     */
    const PRIVATE_DECRYPT = 'openssl_private_decrypt';

    /**
     * @description: 填充模式
     * @var array
     */
    private $_option = [
        OPENSSL_PKCS1_PADDING,     // 私钥加密、公钥解密/公钥加密、私钥解密可以指定,PKCS1填充模式
        OPENSSL_NO_PADDING,        // 私钥加密、公钥解密/公钥加密、私钥解密可以指定,不填充
        OPENSSL_SSLV23_PADDING,    // 公钥加密、私钥解密可以指定,SSLV23填充模式
        OPENSSL_PKCS1_OAEP_PADDING // 公钥加密、私钥解密可以指定,PKCS1_OAEP填充模式
    ];
    /**
     * @description: 加解密数据,公钥加密,私钥解密或私钥加密,公钥解密
     * @param string $data 要加解密的数据
     * @param mixed $key 加解密数据需要的key,私钥可以传私钥资源
     * @param string $mode 加解密方法  PUBLIC_ENCRYPT/PUBLIC_DECRYPT/PRIVATE_ENCRYPT/PRIVATE_DECRYPT   7.2.3私钥解密报错,暂未发现解决方法
     * @param int $padding 填充模式
     * @return string 加密数据使用base64加密后返回
     */
    public static function encryptDecrypt(string $data, $key, string $mode, int $padding = OPENSSL_PKCS1_PADDING): string
    {
        if (!in_array($mode, [static::PUBLIC_ENCRYPT, static::PUBLIC_DECRYPT, static::PRIVATE_ENCRYPT, static::PRIVATE_DECRYPT])) {
            throw new \Exception('加解密方法错误');
        }
        $func     = $mode;
        $isDecrpt = $mode == static::PUBLIC_DECRYPT || $mode == static::PRIVATE_DECRYPT;
        $data     = $isDecrpt ? base64_decode($data) : $data;
        $result   = '';
        if ($func($data, $result , $key, $padding) === false) {
            throw new \Exception('加解密失败,失败原因:' . implode(',', static::errors()));
        }
        // 解密数据去除空格是因为前端crypto-js加密后会有无效字符
        return $isDecrpt ? trim($result) : base64_encode($result);
    }

    /**
     * @description: 获取openSSL库的错误,错误消息已被队列化,可以查询到多条错误信息,最后一个是最近的一个错误。
     * @param {*}
     * @return {*}
     */
    public static function errors(): array
    {
        $result = [];
        while (($data = openssl_error_string()) !== false) {
            $result[] = $data;
        }
        return $result;
    }
}

生成公私钥:SecretKey类

$path = 'C:\Users\Administrator\Desktop\12\\';

$pr = SecretKey::genPrivateKey();
$pb = SecretKey::genPublicKey();

私钥加密公钥解密

$data = '123321abc0';
var_dump($data1 = RSA::encryptDecrypt($data, $pr, RSA::PRIVATE_ENCRYPT, OPENSSL_PKCS1_PADDING));
var_dump($data  = RSA::encryptDecrypt($data1, $pb, RSA::PUBLIC_DECRYPT, OPENSSL_PKCS1_PADDING));

公钥加密私钥解密

$data = '123321abc0';
var_dump($data1 = RSA::encryptDecrypt($data, $pb, RSA::PUBLIC_ENCRYPT, OPENSSL_PKCS1_PADDING));
var_dump($data  = RSA::encryptDecrypt($data1, $pr, RSA::PRIVATE_DECRYPT, OPENSSL_PKCS1_PADDING));

 

{/if}