千家信息网

openssl RSA非对称加密、解密、签名、验签

发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,需要先了解的openssl系列函数openssl_pkey_get_private 从证书中解析获取私钥,以供使用。成功,返回真实的密钥资源标识符(Resource ID),否则返回falseopen
千家信息网最后更新 2025年02月02日openssl RSA非对称加密、解密、签名、验签

需要先了解的openssl系列函数

  • openssl_pkey_get_private 从证书中解析获取私钥,以供使用。成功,返回真实的密钥资源标识符(Resource ID),否则返回false
  • openssl_pkey_get_public 从证书中解析获取公钥,以供使用。成功,返回真实的密钥资源标识符(Resource ID),否则返回false
  • openssl_private_encrypt($data, $encrypted, $privateKeyResourceID, OPENSSL_PKCS1_PADDING)
  • //使用私钥key加密数据data并且将结果保存至变量crypted中
  • openssl_public_decrypt(base64_decode($encrypted), $decrypted, $publicKeyResourceID, OPENSSL_PKCS1_PADDING)
  • //私钥加密的内容通过公钥可用解密出来
getMessage());}
加密、解密系列
  • 公钥加密 openssl_public_encrypt,私钥解密 openssl_private_decrypt
  • 私钥加密 openssl_private_encrypt,公钥解密 openssl_public_decrypt
封装
checkFilePath($publicKeyPath);        $this->checkFilePath($privatePath);        $this->publicKeyContent = file_get_contents($publicKeyPath);        $this->privateKeyContent = file_get_contents($privatePath);        if (empty($this->publicKeyContent)) throw new \Exception('Public key is empty');        if (empty($this->privateKeyContent)) throw new \Exception('Private key is empty');        $this->publicKeyResourceID = !empty($this->publicKeyContent) ? openssl_pkey_get_public($this->getPublicKey()) : false;        $this->privateKeyresourceID = !empty($this->privateKeyContent) ? openssl_pkey_get_private($this->getPrivatekey()) : false;        if ($this->publicKeyResourceID === false) throw new \Exception('解析公钥内容失败');        if ($this->privateKeyresourceID === false) throw new \Exception('解析私钥内容失败');    }    /**     * 校验文件路径     * @param string $filePath     * @throws Exception     */    public function checkFilePath(string $filePath)    {        if (!is_file($filePath)) throw new \Exception($filePath . ' is not a regular file');        if (!file_exists($filePath)) throw new \Exception($filePath . ' is not exists');    }    //获取私有key字符串,重新格式化,为保证任何key都可以识别    public function getPrivatekey(): string    {        $search = [            "-----BEGIN RSA PRIVATE KEY-----",            "-----END RSA PRIVATE KEY-----",            "\n",            "\r",            "\r\n"        ];        $privateKey = str_replace($search, "", $this->privateKeyContent);        //打断字符串为指定数量的字串        return $search[0] . PHP_EOL . wordwrap($privateKey, 64, "\n", true) . PHP_EOL . $search[1];    }    /**     *     * 获取公共key字符串,重新格式化,为保证任何key都可以识别     */    public function getPublicKey()    {        $search = [            "-----BEGIN PUBLIC KEY-----",            "-----END PUBLIC KEY-----",            "\n",            "\r",            "\r\n"        ];        $publicKey = str_replace($search, "", $this->publicKeyContent);        //打断字符串为指定数量的字串        return $search[0] . PHP_EOL . wordwrap($publicKey, 64, "\n", true) . PHP_EOL . $search[1];    }    public function createKey()    {        $result = openssl_pkey_new();// 生成一个新的私钥和公钥对,        if ($result === false) return false;        openssl_pkey_export($result, $privateKey);//将key当作PEM编码字符串导出并且将之保存到$privateKey(通过引用传递的)中。        $publicKey = openssl_pkey_get_details($result);//返回包含密钥详情的数组        return array('public_key' => $publicKey["key"], 'private_key' => $this->getPrivatekey());    }    //使用私钥加密    public function encryptByPrivateKey(string $data): string    {        openssl_private_encrypt($data, $output, $this->privateKeyresourceID);        return base64_encode($output);    }    //使用公钥解密    public function decryptByPublicKey(string $data): string    {        openssl_public_decrypt(base64_decode($data), $output, $this->publicKeyResourceID);        return $output;    }    //使用公钥加密    public function encryptByPublicKey(string $data): string    {        openssl_public_encrypt($data, $output, $this->publicKeyResourceID);        return base64_encode($output);    }    //使用私钥解密    public function decryptByPrivateKey(string $data): string    {        openssl_private_decrypt(base64_decode($data), $output, $this->privateKeyresourceID);        return $output;    }    //生成签名    public function generateSignature(string $data, int $signType = OPENSSL_ALGO_SHA1): string    {        openssl_sign($data, $outSignature, $this->privateKeyresourceID, $signType);//Generate signature        return base64_encode($outSignature);    }    //校验签名 OPENSSL_ALGO_SHA256为RSA2    public function checkSignature(string $originalData, string $signature, int $signType = OPENSSL_ALGO_SHA1): bool    {        //如果签名正确返回 1, 签名错误返回 0, 内部发生错误则返回-1        $result = openssl_verify($originalData, base64_decode($signature), $this->publicKeyResourceID, $signType);        return $result == 1;    }    public function __destruct()    {        openssl_free_key($this->publicKeyResourceID);        openssl_free_key($this->privateKeyresourceID);    }}$rsaObj = new RSA('/home/zrj/.ssh/rsa_public.key', '/home/zrj/.ssh/rsa_private.key');$str = 'Hello world';echo '原始数据:' . $str . PHP_EOL;echo '公钥加密私钥解密如下:' . PHP_EOL;$tmpstr = $rsaObj->encryptByPublicKey($str); //用公钥加密echo '加密后的数据:' . PHP_EOL;echo $tmpstr . PHP_EOL;$tmpstr = $rsaObj->decryptByPrivateKey($tmpstr); //用私钥解密echo '解密结果:' . $tmpstr . PHP_EOL;echo PHP_EOL;echo PHP_EOL;echo '私钥加密公钥解密如下:' . PHP_EOL;$tmpstr = $rsaObj->encryptByPrivateKey($str); //用私钥加密echo '私钥加密后的数据:' . PHP_EOL;echo $tmpstr . PHP_EOL;$tmpstr = $rsaObj->decryptByPublicKey($tmpstr); //用公钥解密echo '公钥解密结果:' . $tmpstr . PHP_EOL;echo PHP_EOL;echo PHP_EOL;$signature = $rsaObj->generateSignature($tmpstr);echo '签名结果为:' . $signature . PHP_EOL;var_dump($rsaObj->checkSignature($tmpstr, $signature));
0