<?php namespace App\Utils; use App\Models\Game; /** * Rsa密钥处理类 * * Class Rsa * @package App\Utils */ class Rsa { private $_config = [ 'public_key' => '', 'private_key' => '', ]; // public function __construct($private_key_filepath, $public_key_filepath) // { // $this->_config['private_key'] = $this->_getContents($private_key_filepath); // $this->_config['public_key'] = $this->_getContents($public_key_filepath); // } public function __construct($appId) { [$this->_config['public_key'], $this->_config['private_key']] = $this->_getKeyData($appId); } /** * 获取密钥文件内容 * * @param $file_path * @return false|string|void */ private function _getKeyContents($file_path) { file_exists($file_path) or die ('密钥或公钥的文件路径错误'); return file_get_contents($file_path); } /** * 获取密钥数据 * * @param $appId * @return array */ private function _getKeyData($appId): array { $gameObj = Game::select('id', 'app_rsa_pub_key', 'app_rsa_pri_key') ->where('id', $appId) ->first(); if (!$gameObj) { throw new \RuntimeException('获取游戏信息失败!'); } return [$gameObj->app_rsa_pub_key, $gameObj->app_rsa_pri_key]; } /** * 获取私钥 * * @return resource */ private function _getPrivateKey() { $privateKey = $this->_config['private_key']; $resource = openssl_pkey_get_private($privateKey); if (!$resource) { throw new \RuntimeException('私钥不可用!'); } return $resource; } /** * 获取公钥 * * @return resource */ private function _getPublicKey() { $publicKey = $this->_config['public_key']; $resource = openssl_pkey_get_public($publicKey); if (!$resource) { throw new \RuntimeException('公钥不可用!'); } return $resource; } /** * 公钥加密 * * @param string $data * @return string */ public function publicEncrypt(string $data = ''): string { $splitArr = str_split($data, 117); $encrypted = ''; foreach ($splitArr as $item) { $bool = openssl_public_encrypt($item, $encryptedData, $this->_getPublicKey()); if (!$bool) { throw new \RuntimeException('公钥加密失败!'); } //每次加密后的字符长度为128 $encrypted .= $encryptedData; } return base64_encode($encrypted); } /** * 私钥加密 * * @param string $data * @return string */ public function privateEncrypt(string $data = ''): string { $splitArr = str_split($data, 117); $encryptedStr = ''; foreach ($splitArr as $item) { $bool = openssl_private_encrypt($item, $encryptedData, $this->_getPrivateKey()); if (!$bool) { throw new \RuntimeException('私钥加密失败!'); } //每次加密后的字符长度为128 $encryptedStr .= $encryptedData; } return base64_encode($encryptedStr); } /** * 公钥解密 * * @param string $data * @return string */ public function publicDecrypt(string $data = ''): string { //密钥每次加密后的长度是128,所以base64_decode后分割长度为128 $split = str_split(base64_decode($data), 128); $crypto = ''; foreach ($split as $chunk) { $bool = openssl_public_decrypt($chunk, $decryptData, $this->_getPublicKey()); if (!$bool) { throw new \RuntimeException('公钥解密失败!'); } $crypto .= $decryptData; } return $crypto; } /** * 私钥解密 * * @param string $data * @return string */ public function privateDecrypt(string $data = ''): string { //密钥每次加密后的长度是128,所以base64_decode后分割长度为128 $split = str_split(base64_decode($data), 128); $crypto = ''; foreach ($split as $chunk) { $bool = openssl_private_decrypt($chunk, $decryptData, $this->_getPrivateKey()); if (!$bool) { throw new \RuntimeException('私钥解密失败!'); } $crypto .= $decryptData; } return $crypto; } }