PHP生成公钥私钥,加密解密,签名验签

发布时间 2023-08-14 10:01:58作者: 好记性还真不如烂笔头
<?php
/**
 * ras 生成钥对,加密/解密码,加密验证
 * @author 
 *
 */
class Ras
{
    // 公钥
    private $publicKey = __DIR__ . './ras/publicKey.pem';

    // 私钥
    private $privateKey = __DIR__ . './ras/privateKey.pem';

    //配置需要用到环境配置文件 openssl.cnf
    private $config_path = 'D:/phpstudy_pro/Extensions/Apache2.4.39/conf/openssl.cnf';

    /**
     * 测试生成签名对
     */
    public function testRas()
    {
        // 生成新的公私钥对
        $this->create_ras_key_pair();

        // 要加密的字符串
        $str = 'test123';

        echo "要加密的字符串:{$str} \n\n";

        // 加密生成字符串
        $encrypt_str = $this->public_encrypt($str);
        echo "加密生成的字符串:" . $encrypt_str;

        echo "\n\n ----- \n\n";

        // 解密由加密生成的字符串
        $decrypt_str = $this->private_decrypt($encrypt_str);
        echo "解密生成的字符串:" . $decrypt_str;

        echo "\n\n ----- \n\n";
        
        // 字符串生成签名
        $sign_str = $this->sign($decrypt_str);
        echo "生成签名:" . $sign_str;
        echo "\n\n ----- \n\n";

        // 验证签名生成的字符串
        $res = $this->verify($decrypt_str,$sign_str);
        echo "验证签名:";
        var_dump($res);
    }

    /**
     * 生成公钥和私钥对
     * @return false|void
     */
    public function create_ras_key_pair()
    {
        $config = array(
          'digest_alg' => 'sha512',
          'private_key_bits' => 4096,
          'private_key_type' => OPENSSL_KEYTYPE_RSA,
          'config' => realpath($this->config_path)
        );
    
        $new_key = openssl_pkey_new($config);
        if(!$new_key)
        {
            return false;
        }

        openssl_pkey_export($new_key,$private_key,null,$config);
        $public_key = openssl_pkey_get_details($new_key);
        // 公钥
        file_put_contents($this->publicKey,$public_key['key']);
        // 密钥
        file_put_contents($this->privateKey,$private_key);
//        echo "public_key:\n";
//        var_dump($public_key);
//        echo "\n\n\n\n private_key:\n";
//        var_dump($private_key);
        openssl_free_key($new_key);
    }

    /**
     * 公钥加密
     * @param $str  要加密的明文
     * @return string
     */
    public function public_encrypt($str){
        $public_key = file_get_contents($this->publicKey);
        openssl_public_encrypt($str, $encrypt_str, $public_key);
        return base64_encode($encrypt_str);
    }

    /**
     * 私钥解密
     * @param $encrypt_str  要解密的密文
     * @return mixed
     */
    public function private_decrypt($encrypt_str){
        $private_key_str = file_get_contents($this->privateKey);
        $private_key = openssl_get_privatekey($private_key_str);
        $encrypt_str_result = base64_decode($encrypt_str);
        openssl_private_decrypt($encrypt_str_result,$decrypt_str,$private_key);
        return $decrypt_str;
    }

    /**
     * 私钥签名
     * @param $plain 要签的明文
     * @return false|string|void
     */
    public function sign($plain)
    {
        try{
            $priv_key = file_get_contents($this->privateKey);
            $pkeyid = openssl_get_privatekey($priv_key);
            if(!is_resource($pkeyid)){
                return false;
            }
            openssl_sign($plain, $signature,$pkeyid,OPENSSL_ALGO_SHA256);
            openssl_free_key($pkeyid);
            return base64_encode($signature);
        }catch(Exception $e){
            print_r($e);
        }
    }

    /**
     * @param $plain 要签的明文
     * @param $signature 生成的签名
     */
    public function verify($plain,$signature){
        $signature = base64_decode($signature);
        $cert = file_get_contents($this->publicKey);
        $pubkeyid = openssl_get_publickey($cert);
        if(!is_resource($pubkeyid)){
            return false;
        }
        $ok = openssl_verify($plain, $signature,$pubkeyid,OPENSSL_ALGO_SHA256);
        @openssl_free_key($pubkeyid);
        if($ok == 1){
            return true;
        }
        return false;
    }


}
(new Ras())->testRas();

/*
 
要加密的字符串:test123 

加密生成的字符串:KSd7kRWCiWiCapmFeWfrO3Zuy4iG+wg6zmAWPDp5x2117BZO/++ECRTFKU+JNtXLaODJwo3a/nUACVgp/aKGDNyWNOi60K/GQYDeOIBJbv9CwUfHUL/3U9+qmyGA25+Br/AfnUyTLXw2xAGpO0wsx71uJdg19rWiPLoSxM7PO+WS1q3ekqK3dktOIzeS8EwtIhuC8G9WG6HoMeNZl8CzVUtEr/s34qtA7npgDjje8DziCrXCmJk0nMGuKZaYJc9MGQ6F1/ULpPilm2HQxj5ZhTmJc5Z5fQtfEVrIbg7Z+wQOlSjXSR4wU4SHdVOyjyIzC/CV6+lB2isNMCWCnE9kj+TJ+hM7e3bZr+v1KLcyXi0NirGO/SOd8Mh49Vf22eahME2pwKm/B0hFcuMTsDTNLcjA93c9akfjo4w2PFGY+rpvFqB6WTQhgZVfKmFosiHqyGmBg3H/rVS2NRZ7VCvBwt+RN2DDH/2Wpcrod7x3JylYVbZBK+BTRUpVPoVN+l3e62a0iqLKlM4fdHB/vHn/OD3OBw1OTCZzZdzbIra0ykDgrkW+IqQI/HDALUcPRfp6klAi7IEjsW3Z4VTgKAhNzPUarWkjaKm5oaVXSaT5NTcoPOpSC2hK6Vcd+wChKuXC8iScxjTjKJoG8tnMtNC6SfBQkXneDjTuBpZ2w1rns8g=

 ----- 

解密生成的字符串:test123

 ----- 

生成签名:TuELg67wti693pURJjZ4V9NeqoZQscUVL72uuNyu4QGI0ed0JrJQEPMeNWA6T7kAtHra5rSKIgVb9vhOpPSy4fycqXp4TJyDsKvY2DIqAdzYDx62HCBMZSjwOjLDHGn+4B/j2B//x2igdgpxUOSmD5iXvutuLASlvSkTQI8KoKOfc13IYy8kIrgrd464wC8nePfFy+oKFw4Efl0ZWwRZ3UzRW+ip8BFJSnMMjkuB6JdcdlphqdCniN8I7WenJnuOy0OGEj7uQHbUjDeaJDr7sKvyASuh8eWieNzbUMMLXLwC2vcJX2IGu+ozYvAmIEBUXZmBkTiD0GWHEWTCg0/V93AoJYAINP87TCQuzuM4O7cjlmicVtfXlQwT9ShxOgJvki/hrLrE9noElpiaFXJ81RO7qMlFz4nMNofDNAVDD8DibiBlVONgf2JpAGiidDAoo6ct6VdsGvAs9nV+WddoXyhtv/lBlo9JN4pUaiKfzkCL2WfbAxTWiU58jkwe7EjfbH0HiIJDtEDLgbtdNIauhXOXbced61VScaFHh9jk4grXgVtqBL+K0aOweq/Q9Gqx2PYuVE2kYuFDYhjYLoGVssgB9PGDgeHeIPzDvudkcsydexaM3BtSIMPyvu3TR3GnRv9kdEWNwaJPFkpf6dRvo0RSK+ZPidxqI01Qg6I5i+k=

 ----- 

验证签名:bool(true)
*/