From ea2250d002140b51da7abba34ed58d157d07bb25 Mon Sep 17 00:00:00 2001 From: liaofei <136327134@qq.com> Date: Tue, 16 May 2023 19:00:10 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0rsa=E5=8A=A0=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crmeb/app/adminapi/controller/Login.php | 19 ++- crmeb/crmeb/utils/Rsa.php | 194 ++++++++++++++++++++++++ 2 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 crmeb/crmeb/utils/Rsa.php diff --git a/crmeb/app/adminapi/controller/Login.php b/crmeb/app/adminapi/controller/Login.php index b47a2f0ab..2239de764 100644 --- a/crmeb/app/adminapi/controller/Login.php +++ b/crmeb/app/adminapi/controller/Login.php @@ -11,9 +11,11 @@ namespace app\adminapi\controller; use crmeb\services\CacheService; +use crmeb\utils\Rsa; use think\facade\App; use crmeb\utils\Captcha; use app\services\system\admin\SystemAdminServices; +use think\facade\Cache; /** * 后台登陆 @@ -83,7 +85,7 @@ class Login extends AuthController * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ - public function login() + public function login(Rsa $rsa) { [$account, $password, $key, $captchaVerification, $captchaType] = $this->request->postMore([ 'account', @@ -102,9 +104,10 @@ class Login extends AuthController } $this->validate(['account' => $account, 'pwd' => $password], \app\adminapi\validate\setting\SystemAdminValidata::class, 'get'); + $password = $rsa->privateDecrypt($password); $result = $this->services->login($account, $password, 'admin', $key); if (!$result) { - $num = CacheService::get('login_captcha',1); + $num = CacheService::get('login_captcha', 1); if ($num > 1) { return app('json')->fail(400140, ['login_captcha' => 1]); } @@ -123,4 +126,16 @@ class Login extends AuthController { return app('json')->success($this->services->getLoginInfo()); } + + /** + * 获取 + * @return \think\Response + * @author 等风来 + * @email 136327134@qq.com + * @date 2023/5/16 + */ + public function key(Rsa $rsa) + { + return app('json')->success(['publicKey' => $rsa->getPublicKey()]); + } } diff --git a/crmeb/crmeb/utils/Rsa.php b/crmeb/crmeb/utils/Rsa.php new file mode 100644 index 000000000..a169bf26e --- /dev/null +++ b/crmeb/crmeb/utils/Rsa.php @@ -0,0 +1,194 @@ + + * +---------------------------------------------------------------------- + */ + +namespace crmeb\utils; + +/** + * Class Rsa + * @author 等风来 + * @email 136327134@qq.com + * @date 2023/5/16 + * @package crmeb\utils + */ +class Rsa +{ + /** + * @var string + */ + protected $publicKey; + + /** + * @var string + */ + protected $privateKey; + + /** + * @var string + */ + protected $basePath; + + /** + * 获取证书文件 + * @param $publicKey + * @param $privateKey + */ + public function __construct(string $publicKey = 'cert_public_password.key', string $privateKey = 'cert_private_password.key') + { + $this->basePath = runtime_path(); + if ($publicKey) { + $this->publicKey = $this->basePath . $publicKey; + } + if ($privateKey) { + $this->privateKey = $this->basePath . $publicKey; + } + if (!is_file($this->publicKey) || !is_file($this->privateKey)) { + $this->exportOpenSSLFile(); + } + } + + /** + * @return false|string + * @author 等风来 + * @email 136327134@qq.com + * @date 2023/5/16 + */ + public function getPublicKey() + { + if (!is_file($this->publicKey)) { + $this->exportOpenSSLFile(); + } + + return file_get_contents($this->publicKey); + } + + /** + * 生成证书 + * @return bool + */ + public function exportOpenSSLFile($passwork = null) + { + + $publicKey = $privateKey = ''; + $dir = runtime_path() . 'conf'; + $conf = 'openssl.cnf'; + if (!is_dir($dir)) { + mkdir($dir, 0700); + } + if (!file_exists($conf)) { + touch($dir . '/' . $conf); + } + + //参数设置 + $config = [ + "digest_alg" => "sha256", + //字节数 512 1024 2048 4096 等 + "private_key_bits" => 1024, + "config" => $dir . '/' . $conf, + //加密类型 + "private_key_type" => OPENSSL_KEYTYPE_RSA, + ]; + + //创建私钥和公钥 + $res = openssl_pkey_new($config); + if ($res == false) { + //创建失败,请检查openssl.cnf文件是否存在 + return false; + } + + //将密钥导出为PEM编码的字符串,并输出(通过引用传递)。 + openssl_pkey_export($res, $privateKey, $passwork, $config); + $publicKey = openssl_pkey_get_details($res); + $publicKey = $publicKey["key"]; + + //生成证书 + $createPublicFileRet = file_put_contents($this->publicKey, $publicKey); + $createPrivateFileRet = file_put_contents($this->privateKey, $privateKey); + if (!($createPublicFileRet || $createPrivateFileRet)) { + return false; + } + + openssl_free_key($res); + return true; + } + + /** + * 数据加密 + * @param string $data + * @param string|null $passwork + * @return false|string + * @author 等风来 + * @email 136327134@qq.com + * @date 2023/5/16 + */ + function privateEncrypt(string $data, string $passwork = null) + { + $encrypted = ''; + $pi_key = openssl_pkey_get_private(file_get_contents($this->privateKey), $passwork);//这个函数可用来判断私钥是否是可用的,可用返回资源id Resource id + //最大允许加密长度为117,得分段加密 + $plainData = str_split($data, 100);//生成密钥位数 1024 bit key + foreach ($plainData as $chunk) { + $partialEncrypted = ''; + $encryptionOk = openssl_private_encrypt($chunk, $partialEncrypted, $pi_key);//私钥加密 + if ($encryptionOk === false) { + return false; + } + $encrypted .= $partialEncrypted; + } + + $encrypted = base64_encode($encrypted);//加密后的内容通常含有特殊字符,需要编码转换下,在网络间通过url传输时要注意base64编码是否是url安全的 + return $encrypted; + } + + /** + * RSA公钥解密(私钥加密的内容通过公钥可以解密出来) + * @param string $public_key 公钥 + * @param string $data 私钥加密后的字符串 + * @return string $decrypted 返回解密后的字符串 + * @author mosishu + */ + function publicDecrypt(string $data) + { + $decrypted = ''; + $pu_key = openssl_pkey_get_public(file_get_contents($this->publicKey));//这个函数可用来判断公钥是否是可用的 + $plainData = str_split(base64_decode($data), 128);//生成密钥位数 1024 bit key + foreach ($plainData as $chunk) { + $str = ''; + $decryptionOk = openssl_public_decrypt($chunk, $str, $pu_key);//公钥解密 + if ($decryptionOk === false) { + return false; + } + $decrypted .= $str; + } + return $decrypted; + } + + /** + * 私钥解密 + * @param string $data + * @return mixed + * @author 等风来 + * @email 136327134@qq.com + * @date 2023/5/16 + */ + public function privateDecrypt(string $data) + { + if (!is_file($this->privateKey)) { + $this->exportOpenSSLFile(); + } + + openssl_private_decrypt(base64_decode($data), $decryptedData, file_get_contents($this->privateKey)); + + return $decryptedData; + } + +} From 234724abb65a5f1ea13ca8743b96d46493009136 Mon Sep 17 00:00:00 2001 From: liaofei <136327134@qq.com> Date: Wed, 17 May 2023 09:02:46 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E8=AF=81=E4=B9=A6=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crmeb/app/adminapi/controller/Login.php | 8 +++++++- crmeb/app/adminapi/route/route.php | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/crmeb/app/adminapi/controller/Login.php b/crmeb/app/adminapi/controller/Login.php index 2239de764..12325a2f3 100644 --- a/crmeb/app/adminapi/controller/Login.php +++ b/crmeb/app/adminapi/controller/Login.php @@ -104,7 +104,13 @@ class Login extends AuthController } $this->validate(['account' => $account, 'pwd' => $password], \app\adminapi\validate\setting\SystemAdminValidata::class, 'get'); - $password = $rsa->privateDecrypt($password); + + try { + $password = $rsa->privateDecrypt($password); + } catch (\Throwable $e) { + return app('json')->fail($e->getMessage()); + } + $result = $this->services->login($account, $password, 'admin', $key); if (!$result) { $num = CacheService::get('login_captcha', 1); diff --git a/crmeb/app/adminapi/route/route.php b/crmeb/app/adminapi/route/route.php index bcb82d491..b67a58968 100644 --- a/crmeb/app/adminapi/route/route.php +++ b/crmeb/app/adminapi/route/route.php @@ -24,6 +24,8 @@ Route::group(function () { Route::post('login', 'Login/login')->name('AdminLogin')->option(['real_name' => '下载表备份记录']); //后台登录页面数据 Route::get('login/info', 'Login/info')->option(['real_name' => '登录信息']); + //获取公钥证书信息 + Route::get('login/key', 'Login/key')->option(['real_name' => '获取公钥证书信息']); //下载文件 Route::get('download/:key', 'PublicController/download')->option(['real_name' => '下载文件']); //验证码 From 74ee389b1df54b3b5eb471d8dbb6159e116b422f Mon Sep 17 00:00:00 2001 From: liaofei <136327134@qq.com> Date: Wed, 17 May 2023 09:03:48 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=AF=81=E4=B9=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crmeb/app/adminapi/controller/Login.php | 14 +------------- crmeb/app/adminapi/route/route.php | 2 -- .../services/system/admin/SystemAdminServices.php | 4 +++- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/crmeb/app/adminapi/controller/Login.php b/crmeb/app/adminapi/controller/Login.php index 12325a2f3..facc90cd8 100644 --- a/crmeb/app/adminapi/controller/Login.php +++ b/crmeb/app/adminapi/controller/Login.php @@ -110,7 +110,7 @@ class Login extends AuthController } catch (\Throwable $e) { return app('json')->fail($e->getMessage()); } - + $result = $this->services->login($account, $password, 'admin', $key); if (!$result) { $num = CacheService::get('login_captcha', 1); @@ -132,16 +132,4 @@ class Login extends AuthController { return app('json')->success($this->services->getLoginInfo()); } - - /** - * 获取 - * @return \think\Response - * @author 等风来 - * @email 136327134@qq.com - * @date 2023/5/16 - */ - public function key(Rsa $rsa) - { - return app('json')->success(['publicKey' => $rsa->getPublicKey()]); - } } diff --git a/crmeb/app/adminapi/route/route.php b/crmeb/app/adminapi/route/route.php index b67a58968..bcb82d491 100644 --- a/crmeb/app/adminapi/route/route.php +++ b/crmeb/app/adminapi/route/route.php @@ -24,8 +24,6 @@ Route::group(function () { Route::post('login', 'Login/login')->name('AdminLogin')->option(['real_name' => '下载表备份记录']); //后台登录页面数据 Route::get('login/info', 'Login/info')->option(['real_name' => '登录信息']); - //获取公钥证书信息 - Route::get('login/key', 'Login/key')->option(['real_name' => '获取公钥证书信息']); //下载文件 Route::get('download/:key', 'PublicController/download')->option(['real_name' => '下载文件']); //验证码 diff --git a/crmeb/app/services/system/admin/SystemAdminServices.php b/crmeb/app/services/system/admin/SystemAdminServices.php index 0cacdc8bc..de07b3bcd 100644 --- a/crmeb/app/services/system/admin/SystemAdminServices.php +++ b/crmeb/app/services/system/admin/SystemAdminServices.php @@ -23,6 +23,7 @@ use app\services\system\SystemMenusServices; use crmeb\services\CacheService; use crmeb\services\FormBuilder; use crmeb\services\workerman\ChannelService; +use crmeb\utils\Rsa; use think\facade\Config; use think\facade\Event; use think\Model; @@ -167,7 +168,8 @@ class SystemAdminServices extends BaseServices 'copyright' => sys_config('nncnL_crmeb_copyright', ''), 'version' => get_crmeb_version(), 'key' => $key, - 'login_captcha' => 0 + 'login_captcha' => 0, + 'publicKey' => app()->make(Rsa::class)->getPublicKey() ]; if (CacheService::get('login_captcha', 1) > 1) { $data['login_captcha'] = 1;