一、生成密钥

1. 生成私钥

openssl genrsa -out rsa_private_key.pem 1024

2. 生成公钥

openssl rsa -pubout -in rsa_private_key.pem -out rsa_public_key.pem

二、 用PHP实现RSA加密,解密,加签,验签

php内置了很丰富的openssl方法,需要安装php的openssl扩展,方法百度,至于查看,就phpinfo()后查看有没有openssl,操作类如下

<?php
declare(strict_types = 1);

/**
* RAS加解密类
*
* 用于实现RSA加密,解密,加签,验签
*
* @author alex.xu <xux851@gmail.com>
* @version 1.0.0
*
*/

class Rsa
{
/** 私钥 **/
private $_privateKey;

/** 公钥 **/
private $_publicKey;

/** 密钥的存储路径 **/
private $_keyPath;

public function __construct(string $path) {
if (empty($path) || !is_dir($path)) throw new \Exception('必须设置密钥的存储路径');
// 设置私钥
$this->_keyPath = $path;
$file = $this->_keyPath . DIRECTORY_SEPARATOR . 'rsa_private_key.pem';
$prk = file_get_contents($file);
$this->_privateKey = openssl_pkey_get_private($prk);
// 设置公钥
$file = $this->_keyPath . DIRECTORY_SEPARATOR . 'rsa_public_key.pem';
$puk = file_get_contents($file);
$this->_publicKey = openssl_pkey_get_public($puk);
}

/** 设置私钥 */
public function setPrivateKey() {
if (is_resource($this->_privateKey)) return true;
$file = $this->_keyPath . DIRECTORY_SEPARATOR . 'rsa_private_key.pem';
$prk = file_get_contents($file);
$this->_privateKey = openssl_pkey_get_private($prk);
return true;
}

/** 设置公钥 */
public function setPublicKey() {
if (is_resource($this->_publicKey)) return true;
$file = $this->_keyPath . DIRECTORY_SEPARATOR . 'rsa_public_key.pem';
$puk = file_get_contents($file);
$this->_publicKey = openssl_pkey_get_public($puk);
return true;
}

/**
* 加密
*
* @param string $data 要加密的字符串
* @param integer $type 类型 0. 私钥 1. 公钥
* @return string|null
*
*/
public function Encrypt(string $data = '', int $type = 0) {
if (empty($data)) return null;
$r = $type == 0 ? openssl_private_encrypt($data, $encrypted, $this->_privateKey) : openssl_public_encrypt($data, $encrypted, $this->_publicKey);
return $r ? base64_encode($encrypted) : null;
}

/**
* 解密
*
* @param string $data 要解密的字符串
* @param integer $type 类型 0. 私钥 1. 公钥
* @return string|null
*
*/
public function Decrypt(string $encrypted = '', int $type = 0) {
if (empty($encrypted)) return null;
$encrypted = base64_decode($encrypted);
$r = $type == 0 ? openssl_private_decrypt($encrypted, $decrypted, $this->_privateKey) : openssl_public_decrypt($encrypted, $decrypted, $this->_publicKey);
return $r ? $decrypted : null;
}

/**
* 私钥加签
*
* @param string $data 要加签的串
* @return string|null
*
*/
public function sign(string $data = '') {
if (empty($data)) return null;
openssl_sign($data, $sign, $this->_privateKey);
$sign = base64_encode($sign);
return $sign;
}

/**
* 公钥验签
*
* @param string $data 加密串
* @param string $sign 上一步的验名
* @return bool|null
*
*/
public function verify(string $data = '', string $sign = '') {
if (empty($data)) return null;
return !!openssl_verify($data, base64_decode($sign), $this->_publicKey);
}

/** 释放资源 */
public function __destruct() {
$this->_privateKey ?? openssl_free_key($this->_privateKey);
$this->_publicKey ?? openssl_free_key($this->_publicKey);
}
}

###三、使用方法
将生成的2个文件放在同目录中

$RSA = new Rsa(dirname(__FILE__));

// 公钥加密 --> 私钥加密

$string = 'del.pub';

$publicString = $RSA->Encrypt($string, 1);
echo '公钥加密后:' . $publicString . PHP_EOL;

$privateString = $RSA->Decrypt($publicString);
echo '私钥解密后:' . $privateString . PHP_EOL;

// 私钥加签 --> 公钥验签
$sign = $RSA->sign($string);
echo '私钥加签后:' . $sign . PHP_EOL;
$result = $RSA->verify($string, $sign);
echo '验证签名是否正确:' . (string)$result;

结果如下:

php Rsa.php
公钥加密后:aFDWf858bi30qnyxQvaVz4vTe4Q4+7OU4p+MkQNA8qtPKGxeh11MvRhdq5udzfQPRi72wyrMkfFnWTs5OTh6fXKA3JJPJyezs0yoEIRDfZDJz0sJKPSrZcU5TpCnnU0F3vjIZjxmQFJmSw3OCzGwlQAecAPdpxmUQgg2kl8yg4M=
私钥解密后:del.pub
私钥加签后:MHXPOJm2J6E/NW9n15q5p+uVZhIeUYZ2t8CauIEGR64bToQ+1m5LKKaN+hpaP0Odc7uG8z8JEVTiAsoWrOuxRF17OiKOYzyCmyU9nD4t8irMvmLmTUdX3Pin1iKXrn8SBj7y466EpENDiBkICcViYNTUf/JgrEs7Gn5YcBm+3HU=
验证签名是否正确:1