2024-04-12 18:03:00
围观(2703)
class RSA { // 公钥 private $publicKey = __DIR__ . './rsa/publicKey.pem'; // 私钥 private $privateKey = __DIR__ . './rsa/privateKey.pem'; // 需要用到环境配置文件 openssl.cnf // 更改为您的 openssl.cnf 文件路径 private $configPath = 'D:\\xxx\\openssl.cnf'; private $publicResource; private $privateResource; public function __construct() { if (empty($this->publicResource) || empty($this->privateResource)) { $this->setResource(); } } /** * 生成公钥和私钥对 * @return void */ private function createRsaKey(): void { $config = [ 'digest_alg' => 'sha512', 'private_key_bits' => 4096, 'private_key_type' => OPENSSL_KEYTYPE_RSA, 'config' => realpath($this->configPath), ]; @mkdir(dirname($this->publicKey), 0777, true); @mkdir(dirname($this->privateKey), 0777, true); $newKey = openssl_pkey_new($config); if (!$newKey) { return; } openssl_pkey_export($newKey, $privateKey, null, $config); $publicKey = openssl_pkey_get_details($newKey); // 公钥 file_put_contents($this->publicKey, $publicKey['key']); // 密钥 file_put_contents($this->privateKey, $privateKey); openssl_free_key($newKey); } private function setResource() { if (!file_exists($this->publicKey) || !file_exists($this->privateKey)) { $this->createRsaKey(); } $publicKey = file_get_contents($this->publicKey); $this->publicResource = openssl_pkey_get_public($publicKey); if (!$this->publicResource) { throw new Exception('公钥载入失败:' . openssl_error_string()); } $privateKey = file_get_contents($this->privateKey); $this->privateResource = openssl_pkey_get_private($privateKey); if (!$this->privateResource) { throw new Exception('私钥载入失败:' . openssl_error_string()); } } /** * 公钥加密 * @param $str * @return string * @throws Exception */ public function publicEncrypt($str): string { return $this->encrypt($str); } /** * 私钥加密 * @param $str * @return string * @throws Exception */ public function privateEncrypt($str): string { return $this->encrypt($str, 1); } /** * 加密 * @param $str * @param int $type * @return string * @throws Exception */ private function encrypt($str, int $type = 0): string { $resource = $this->publicResource; $encryptFunction = 'openssl_public_encrypt'; if ($type) { // 私钥加密 $resource = $this->privateResource; $encryptFunction = 'openssl_private_encrypt'; } $rows = str_split($str, 117); $result = []; foreach ($rows as $row) { $res = ''; $encryptRes = $encryptFunction($row, $res, $resource); if (!$encryptRes) { throw new Exception('加密失败:' . openssl_error_string()); } $result[] = base64_encode($res); } return base64_encode(json_encode($result)); } /** * 私钥解密 * @param $str * @return string * @throws Exception */ public function privateDecrypt($str): string { return $this->decrypt($str); } /** * 公钥解密 * @param $str * @return string * @throws Exception */ public function publicDecrypt($str): string { return $this->decrypt($str, 1); } /** * 解密 * @param $str * @param int $type * @return string * @throws Exception */ private function decrypt($str, int $type = 0): string { $resource = $this->privateResource; $decryptFunction = 'openssl_private_decrypt'; if ($type) { $resource = $this->publicResource; $decryptFunction = 'openssl_public_decrypt'; } $rows = json_decode(base64_decode($str), true); $result = ''; foreach ($rows as $row) { $res = ''; $decryptRes = $decryptFunction(base64_decode($row), $res, $resource); if (!$decryptRes) { throw new Exception('解密失败:' . openssl_error_string()); } $result .= $res; } return $result; } } $rsa = new RSA; // 要加密的字符串 $str = 'RSA算法是一种非对称加密算法,与对称加密算法不同的是,RSA算法有两个不同的密钥,一个是公钥,一个是私钥。 [10] RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制 [2]。 在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK [2]。 正是基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA对话密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要 [2]。 RSA是被研究得最广泛的公钥算法,从提出后经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。1983年麻省理工学院在美国为RSA算法申请了专利 [3]。 RSA允许选择公钥的大小。512位的密钥被视为不安全的;768位的密钥不用担心受到除了国家安全管理(NSA)外的其他事物的危害;RSA在一些主要产品内部都有嵌入'; // 公钥加密 $encryptStr = $rsa->publicEncrypt($str); echo "公钥加密生成的字符串:" . $encryptStr; echo "\\n\\n ----- \\n\\n"; // 私钥解密 $decryptStr = $rsa->privateDecrypt($encryptStr); echo "私钥解密结果:" . $decryptStr; echo "\\n\\n ----- \\n\\n"; // 私钥加密 $encryptStr = $rsa->privateEncrypt($str); echo "私钥加密生成的字符串:" . $encryptStr; echo "\\n\\n ----- \\n\\n"; // 公钥解密 $decryptStr = $rsa->publicDecrypt($encryptStr); echo "公钥解密结果:" . $decryptStr;