快速获取RSA密钥对：http://www.metools.info/code/c80.html示例代码：<?php class App extends BaseController { private $syncUrl = 'https://www.xxx.com/api/event/sync'; private $privateKey; //私钥 private $publicKey; //其他系统公钥 private $keyLen = 2048; private $appId = 1; private $identity = 'hello'; public function __construct() { $this->privateKey = file_get_contents((app()->getRootPath() . 'private_key.pam')); $this->publicKey = file_get_contents((app()->getRootPath() . 'cert_public.pam')); } //新版接口 public function test($uid='', $token='') { //请求tokenIsValidSync判断请求是否合法 $data = [ 'app_id'=>$this->appId, 'app_identity'=>$this->identity, 'timestamp'=>time(), 'rnd_str'=>uniqid(), 'event'=>'tokenIsValidSync', 'uid'=>$uid, 'token'=>$token, 'profile'=>1 ]; $enData = $this->privateEncrypt($data); $postData = [ 'app_id'=>$this->appId, 'data'=>$enData ]; $ret = HttpService::postRequest($this->syncUrl, $postData); $info = json_decode($ret, true); $decryptData = $this->publicDecrypt($info['data']); $userInfo = json_decode($decryptData, true); } /** * 私钥加密 * * @param string|array $data 待加密数据 * @return string 已加密的内容 */ public function privateEncrypt($data) { //如果是数组，则转换为JSON字符串 if (is_array($data)) $data = json_encode($data); if (!is_string($data)) { return null; } $encrypted = ''; //采用默认的 OPENSSL_PKCS1_PADDING 填充格式，数据长度必须小于密钥长度 - 11 $part_len = $this->keyLen / 8 - 11; $parts = str_split($data, $part_len); foreach ($parts as $part) { $encrypted_temp = ''; openssl_private_encrypt($part, $encrypted_temp, $this->privateKey); $encrypted .= $encrypted_temp; } return base64_encode($encrypted); } /** * 公钥解密 * * @param string $encrypted 待解密内容 * @return string 已解密内容 */ public function publicDecrypt($encrypted = '') { if (!is_string($encrypted)) { return null; } $decrypted = ''; $part_len = $this->keyLen / 8; $base64_decoded = base64_decode($encrypted); $parts = str_split($base64_decoded, $part_len); foreach ($parts as $part) { $decrypted_temp = ''; openssl_public_decrypt($part, $decrypted_temp, $this->publicKey); $decrypted .= $decrypted_temp; } return $decrypted; } }
前端参考代码如下，后台PHP代码参考上篇文章。其中，key为后台动态生成的16位随机字符串并写入cache中，登录验证verify方法中需先判断此key的缓存是否存在。引入相关js: 登录操作:form.on('submit(login)', function(obj){ let data = obj.field; let key = CryptoJS.enc.Utf8.parse(data.key); let password = CryptoJS.enc.Utf8.parse(data.password); let encrypted = CryptoJS.AES.encrypt(password, key, {iv:key, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7}); var hexStr = encrypted.ciphertext.toString(); var oldHexStr = CryptoJS.enc.Hex.parse(hexStr); let base64 = CryptoJS.enc.Base64.stringify(oldHexStr); data.password = base64; $.ajax({ url: "{:url('verify')}" ,data: data ,method: "POST" ,dataType: "json" ,success: function(res){ if(res.code == 200){ layer.msg('登录成功', {time: 1000}, function(){ location.href = "{:url('index/index')}"; }); }else{ //重置验证码 $('#vercode').trigger('click'); $('#code').val(''); layer.msg(res.msg, {time: 2000}); } } }); });
<?php /** * Desc: AES加密解密 * User: SenSen Wechat:1050575278 * Date: 2021/4/27 * Time: 14:14 */ namespace sensen\services; class AesService { protected static $method = "AES-128-CBC"; const KEY = 'fei1zui2you3jie!'; const IV = 'hello202105world'; /** * 加密 * @param string|array $data 待加密 * @param string $key 秘钥 * @param string $iv 偏移量 * @return string|string[]|array */ public static function encrypt($data, $key=self::KEY, $iv=self::IV) { if(is_array($data)){ $res = []; foreach ($data as $v){ $text = openssl_encrypt($v, static::$method, $key, OPENSSL_RAW_DATA, $iv); $res[] = self::safetyBase64Encode($iv . $text); } }else{ $text = openssl_encrypt($data, static::$method, $key, OPENSSL_RAW_DATA, $iv); $res = self::safetyBase64Encode($iv . $text); } return $res; } /** * 解密 * @param string|array $text 待解密 * @param string $key 秘钥 * @param string $iv 偏移量 * @param false $login 是否为登录 * @return false|string|array */ public static function decrypt($text, $key=self::KEY, $iv=self::IV, $login=false) { if(is_array($text)){ $data = []; foreach ($text as $v){ $cipherText = self::safetyBase64Decode($v); $cipherText = substr($cipherText, strlen($iv)); $data[] = openssl_decrypt($cipherText, static::$method, $key, OPENSSL_RAW_DATA, $iv); } }else{ $cipherText = self::safetyBase64Decode($text); if($login){ //仅方便登录使用，登录时iv与key相同 $data = openssl_decrypt(base64_decode($text), static::$method, $key, OPENSSL_RAW_DATA, $iv); }else{ $cipherText = substr($cipherText, strlen($iv)); $data = openssl_decrypt($cipherText, static::$method, $key, OPENSSL_RAW_DATA, $iv); } } return $data; } /** * base64安全编码 * @param string $text * @return string|string[] */ public static function safetyBase64Encode($text) { $text = base64_encode($text); $text = str_replace(['+','/'],['-','_'],$text); return $text; } /** * base64安全解码 * @param string $text * @return false|string */ public static function safetyBase64Decode($text) { $text = str_replace(['-','_'],['+','/'],$text); $text = base64_decode($text); return $text; } }