原创PHP RSA实现公/私钥的加密、解密、签名

PHP 91 0 2024-07-23

PHP RSA实现公/私钥的加密、解密、签名

RSA加密解决封装(仅供参考),封装代码如下:

class Rsa
{
    //生成密钥对,返回值:数组,即privateKey为私钥,publicKey为公钥
    public static function pkey($config = [])
    {
        if (count($config) == 0) {
            $config = array(
                "digest_alg" => "SHA256",
                "private_key_bits" => 2048,
                "private_key_type" => OPENSSL_KEYTYPE_RSA
            );
        }
        $keys = openssl_pkey_new($config); // 生成私钥和公钥
        openssl_pkey_export($keys, $privKey); // 提取私钥
        $pubKey = openssl_pkey_get_details($keys)["key"]; // 提取公钥
        $res = [
            "privateKey" => $privKey,
            "publicKey" => $pubKey
        ];
        return $res;
    }

    //设置私钥,$type=1为完整key,2为长类型(无空格无换行),3为pem文件完整key,其它为原始值(不做任何改变)
    public static function setPrivKey($privateKey, $type = 0)
    {
        switch ($type) {
            case 1:
                $key = openssl_pkey_get_private($privateKey);
                break;
            case 2:
                $pem = chunk_split($privateKey, 64, "\n");
                $pem = "-----BEGIN PRIVATE KEY-----\n" . $pem . "-----END PRIVATE KEY-----\n";
                $key = openssl_pkey_get_private($pem);
                break;
            case 3:
                $privateKeyString = file_get_contents($privateKey);
                $key = openssl_pkey_get_private($privateKeyString);
                break;
            default:
                $key = $privateKey;
        }
        return $key;
    }

    //设置公钥,$type=1为完整key,2为长类型(无空格无换行),3为pem文件完整key,其它为原始值(不做任何改变)
    public static function setPubKey($publicKey, $type = 0)
    {
        switch ($type) {
            case 1:
                $key = openssl_pkey_get_public($publicKey);
                break;
            case 2:
                $pem = chunk_split($publicKey, 64, "\n");
                $pem = "-----BEGIN PUBLIC KEY-----\n" . $pem . "-----END PUBLIC KEY-----\n";
                $key = openssl_pkey_get_public($pem);
                break;
            case 3:
                $pubString = file_get_contents($publicKey);
                $key = openssl_pkey_get_public($pubString);
                break;
            default:
                $key = $publicKey;
        }
        return $key;
    }

    //签名
    public static function sign($data = '', $privateKey = '')
    {
        if ($data != '' && $privateKey != '') {
            openssl_sign($data, $signature, $privateKey, OPENSSL_ALGO_SHA256);
            return base64_encode($signature);
        } else {
            return '';
        }
    }

    //验证签名
    public static function verify($data = '', $signature = '', $publicKey = '')
    {
        $isVerified = 0;
        if ($data != '' && $signature != '' && $publicKey != '') {
            $isVerified = openssl_verify($data, base64_decode($signature), $publicKey, OPENSSL_ALGO_SHA256);
        }
        return $isVerified;
    }

    //公钥加密
    public static function pubEnc($data = '', $pubKey = '')
    {
        if ($data === '' || $pubKey === '') {
            return '';
        }
        openssl_public_encrypt($data, $encrypted, $pubKey);
        return base64_encode($encrypted);
    }

    //公钥解密
    public static function pubDec($encrypted = '', $pubKey = '')
    {
        if ($encrypted === '' || $pubKey === '') {
            return '';
        }
        openssl_public_decrypt(base64_decode($encrypted), $decrypted, $pubKey);
        return $decrypted;
    }

    //私钥加密
    public static function privEnc($data = '', $privKey = '')
    {
        if ($data === '' || $privKey === '') {
            return '';
        }
        openssl_private_encrypt($data, $encrypted, $privKey);
        return base64_encode($encrypted);
    }

    //私钥解密
    public static function privDec($encrypted = '', $privKey = '')
    {
        if ($encrypted === '' || $privKey === '') {
            return '';
        }
        openssl_private_decrypt(base64_decode($encrypted), $decrypted, $privKey);
        return $decrypted;
    }

    //释放资源, openssl_free_key函数PHP8.0后不再支持
    public static function free($privateKey, $publicKey)
    {
        is_resource($privateKey) && @openssl_free_key($privateKey);
        is_resource($publicKey) && @openssl_free_key($publicKey);
    }

    //数组转为字符串,$type=param|json
    public static function arrToStr($data = [], $type = 'param')
    {
        if ($type == 'json') {
            $str = json_encode($data, JSON_UNESCAPED_UNICODE);
        } else {
            $arrs = [];
            foreach ($data as $key => $val) {
                $arrs[] = $key . '=' . $val;
            }
            $str = join('&', $arrs);
        }
        return $str;
    }
}

调用方法:

    public function rsa()
    {
        $keys = Rsa::pkey(); //生成密钥对
        $privKey = Rsa::setPrivKey($keys['privateKey'], 1); //设置私钥
        $pubKey = Rsa::setPubKey($keys['publicKey'], 1); //设置公钥
        echo '<hr>私钥:' . $privKey;
        echo '<hr>公钥:' . $pubKey;

        //$data = '我是HILO8.COM'; // 待签名的数据
        $data2 = [
            'id' => 88,
            'name' => '哈喽吧',
            'url' => 'https://www.hilo8.com?page=23&limit=12'
        ];
        $data = Rsa::arrToStr($data2, 'json');
        echo '<hr>要签名/加密的数据:' . $data;

        $signature = Rsa::sign($data, $privKey); //签名
        echo "<hr>签名:" . $signature;
        $isVerified = Rsa::verify($data, $signature, $pubKey); // 验证签名
        echo "<hr>" . $isVerified;

        //公钥加密,私钥解密
        $encrypted = Rsa::pubEnc($data, $pubKey);
        echo "<hr>加密后:" . $encrypted;
        $decrypted = Rsa::privDec($encrypted, $privKey);
        echo "<hr>解密后: " . $decrypted . "\n";

        //私钥加密,公钥解密
        $encrypted = Rsa::privEnc($data, $privKey);
        echo "<hr>加密后:" . $encrypted;
        $decrypted = Rsa::pubDec($encrypted, $pubKey);
        echo "<hr>解密后: " . $decrypted . "\n";

        Rsa::free($privKey, $pubKey);
    }

上一篇:workerman开发中遇到的常见问题和解决方法

下一篇:PHPMailer实现发送邮件

讨论数量:0

请先登录再发表讨论。 2024-09-08

天涯网魂
3 杠 5 星
TA 的文章
TA 的随言
TA 的资源链