diff --git a/api/api-system/src/main/java/com/bonus/system/api/domain/SysOperLog.java b/api/api-system/src/main/java/com/bonus/system/api/domain/SysOperLog.java index bb24246..7b18c80 100644 --- a/api/api-system/src/main/java/com/bonus/system/api/domain/SysOperLog.java +++ b/api/api-system/src/main/java/com/bonus/system/api/domain/SysOperLog.java @@ -10,7 +10,7 @@ import java.util.Date; /** * 操作日志记录表 oper_log - * + * * @author zys */ @Data @@ -72,8 +72,8 @@ public class SysOperLog extends BaseEntity @Excel(name = "返回参数") private String jsonResult; - /** 操作状态(0正常 1异常) */ - @Excel(name = "状态", readConverterExp = "0=正常,1=异常") + /** 操作状态(0异常 1正常) */ + @Excel(name = "状态", readConverterExp = "0=异常,1=正常") private Integer status; /** 错误消息 */ @@ -96,5 +96,5 @@ public class SysOperLog extends BaseEntity private String operatoType; - + private String statusRes; } diff --git a/api/api-system/src/main/java/com/bonus/system/api/model/UserSession.java b/api/api-system/src/main/java/com/bonus/system/api/model/UserSession.java new file mode 100644 index 0000000..704c223 --- /dev/null +++ b/api/api-system/src/main/java/com/bonus/system/api/model/UserSession.java @@ -0,0 +1,23 @@ +package com.bonus.system.api.model; + +/** + * @author 马三炮 + * @date 2025/11/19 + */ + +import lombok.Data; + +import java.util.Date; + +/** + * 会话信息实体(存储用户登录状态与终端信息) + */ +@Data +public class UserSession { + private String sessionId; // 唯一会话ID(UUID生成) + private String userId; // 用户唯一标识 + private String terminal; // 终端标识(如PC/Android/iOS/WeChat) + private Date createTime; // 会话创建时间 + private Date lastActiveTime; // 最后活跃时间 + private boolean isValid; // 会话是否有效 +} diff --git a/auth/src/main/java/com/bonus/auth/controller/LocalSessionManager.java b/auth/src/main/java/com/bonus/auth/controller/LocalSessionManager.java new file mode 100644 index 0000000..2e46ada --- /dev/null +++ b/auth/src/main/java/com/bonus/auth/controller/LocalSessionManager.java @@ -0,0 +1,99 @@ +package com.bonus.auth.controller; + +import com.bonus.system.api.model.UserSession; +import org.springframework.stereotype.Component; + +import java.util.Date; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReentrantLock; + +@Component +public class LocalSessionManager { + // 内存缓存:用户ID -> 会话信息(ConcurrentHashMap保证并发安全) + private final Map userSessionMap = new ConcurrentHashMap<>(); + // 锁:防止同一用户并发登录导致会话状态混乱 + private final ReentrantLock lock = new ReentrantLock(); + // 会话有效期(2小时,单位:毫秒) + private static final long SESSION_EXPIRE_MS = 7200 * 1000; + + /** + * 用户登录创建会话(强制下线旧会话) + * @param userId 用户ID + * @param terminal 终端标识 + * @return 新会话ID + */ + public String createSession(String userId, String terminal) { + lock.lock(); + try { + // 1. 检查旧会话:存在则标记为无效(强制下线) + UserSession oldSession = userSessionMap.get(userId); + if (oldSession != null && oldSession.isValid()) { + oldSession.setValid(false); // 标记旧会话无效 + // 可选:记录下线日志(如用户XXX在Android终端登录,PC终端被强制下线) + } + + // 2. 生成新会话 + String newSessionId = UUID.randomUUID().toString().replace("-", ""); + UserSession newSession = new UserSession(); + newSession.setSessionId(newSessionId); + newSession.setUserId(userId); + newSession.setTerminal(terminal); + newSession.setCreateTime(new Date()); + newSession.setLastActiveTime(new Date()); + newSession.setValid(true); + + // 3. 缓存新会话 + userSessionMap.put(userId, newSession); + return newSessionId; + } finally { + lock.unlock(); + } + } + + /** + * 校验会话有效性(含过期检查) + * @param userId 用户ID + * @param sessionId 会话ID + * @return 有效返回true,无效返回false + */ + public boolean validateSession(String userId, String sessionId) { + UserSession session = userSessionMap.get(userId); + if (session == null) { + return false; // 无会话记录 + } + + // 校验会话ID、有效性、是否过期 + boolean isSessionValid = session.getSessionId().equals(sessionId) + && session.isValid() + && (System.currentTimeMillis() - session.getLastActiveTime().getTime() < SESSION_EXPIRE_MS); + + if (isSessionValid) { + session.setLastActiveTime(new Date()); // 刷新最后活跃时间 + return true; + } + + return false; + } + + /** + * 用户注销:销毁会话 + */ + public void destroySession(String userId) { + UserSession session = userSessionMap.get(userId); + if (session != null) { + session.setValid(false); + } + } + + /** + * 清理过期会话(可定时执行,如每30分钟) + */ + public void cleanExpiredSessions() { + long currentTime = System.currentTimeMillis(); + userSessionMap.values().removeIf(session -> + !session.isValid() || (currentTime - session.getLastActiveTime().getTime() >= SESSION_EXPIRE_MS) + ); + } +} diff --git a/auth/src/main/java/com/bonus/auth/controller/TokenController.java b/auth/src/main/java/com/bonus/auth/controller/TokenController.java index e852a98..422939a 100644 --- a/auth/src/main/java/com/bonus/auth/controller/TokenController.java +++ b/auth/src/main/java/com/bonus/auth/controller/TokenController.java @@ -19,7 +19,7 @@ import javax.servlet.http.HttpServletRequest; /** * token 控制 - * + * * @author zys */ //@CrossOrigin @@ -32,6 +32,10 @@ public class TokenController @Autowired private SysLoginService sysLoginService; + @Autowired + private LocalSessionManager sessionManager; + + @PostMapping("login") public R login(@RequestBody LoginBody form) { diff --git a/auth/src/main/java/com/bonus/auth/service/SysLoginService.java b/auth/src/main/java/com/bonus/auth/service/SysLoginService.java index 2364632..201b2ce 100644 --- a/auth/src/main/java/com/bonus/auth/service/SysLoginService.java +++ b/auth/src/main/java/com/bonus/auth/service/SysLoginService.java @@ -6,10 +6,7 @@ import com.bonus.common.core.constant.UserConstants; import com.bonus.common.core.domain.R; import com.bonus.common.core.enums.UserStatus; import com.bonus.common.core.exception.ServiceException; -import com.bonus.common.core.utils.AESCBCUtils; -import com.bonus.common.core.utils.JwtUtils; -import com.bonus.common.core.utils.ServletUtils; -import com.bonus.common.core.utils.StringUtils; +import com.bonus.common.core.utils.*; import com.bonus.common.core.utils.ip.IpUtils; import com.bonus.common.security.utils.SecurityUtils; import com.bonus.system.api.RemoteLogService; @@ -23,7 +20,7 @@ import org.springframework.stereotype.Component; /** * 登录校验方法 - * + * * @author zys */ @Component @@ -41,8 +38,10 @@ public class SysLoginService public LoginUser login(String username, String password, String type, String jwtToken) { - username = AESCBCUtils.decrypt(username); - password = AESCBCUtils.decrypt(password); + /* username = AESCBCUtils.decrypt(username); + password = AESCBCUtils.decrypt(password);*/ + username = RSAUtil.decrypt(username); + password = RSAUtil.decrypt(password); if(StringUtils.isNotEmpty(jwtToken)){ Claims claims = JwtUtils.parseToken(jwtToken); jwtToken = (String) claims.get(SecurityConstants.DETAILS_USERNAME); @@ -149,7 +148,7 @@ public class SysLoginService /** * 记录登录信息 - * + * * @param username 用户名 * @param status 状态 * @param message 消息内容 @@ -172,4 +171,4 @@ public class SysLoginService } remoteLogService.saveLogininfor(logininfor, SecurityConstants.INNER); } -} \ No newline at end of file +} diff --git a/common/common-core/src/main/java/com/bonus/common/core/constant/CacheConstants.java b/common/common-core/src/main/java/com/bonus/common/core/constant/CacheConstants.java index 8dc5cba..0c37660 100644 --- a/common/common-core/src/main/java/com/bonus/common/core/constant/CacheConstants.java +++ b/common/common-core/src/main/java/com/bonus/common/core/constant/CacheConstants.java @@ -2,20 +2,20 @@ package com.bonus.common.core.constant; /** * 缓存的key 常量 - * + * * @author zys */ public class CacheConstants { /** - * 缓存有效期,默认720(分钟) + * 缓存有效期,默认30(分钟) */ - public final static long EXPIRATION = 720; + public final static long EXPIRATION = 30; /** - * 缓存刷新时间,默认120(分钟) + * 缓存刷新时间,默认30(分钟) */ - public final static long REFRESH_TIME = 120; + public final static long REFRESH_TIME = 30; /** * 权限缓存前缀 diff --git a/common/common-core/src/main/java/com/bonus/common/core/utils/RSAUtil.java b/common/common-core/src/main/java/com/bonus/common/core/utils/RSAUtil.java new file mode 100644 index 0000000..9338274 --- /dev/null +++ b/common/common-core/src/main/java/com/bonus/common/core/utils/RSAUtil.java @@ -0,0 +1,89 @@ +package com.bonus.common.core.utils; + +/** + * @author 马三炮 + * @date 2025/11/19 + */ +import org.springframework.util.Base64Utils; +import javax.crypto.Cipher; +import java.security.*; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +public class RSAUtil { + // 私钥(从安全配置中获取,Base64编码) + private static final String PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC43RvfCkl42fK8YQUJCTLe7ScaH+OTBexWTwiU1GWyILYhNwGuhusmJ9Mgj7+wvxvB8p9ZT6HYCBfwdRlpkAmXbjzyGzZJx8l/npwpmwGOZN8LNRUSGDmOtOXET8sHeQG1j46BV9Tghn+2VL8ApT4dj+FitKro7/cNqHzbl4nqihEg/R3TKyx2Xo0yn/yDUmeFY9Qb4FWIFawjfwZ+09toQWpQ6L1mmkNYiN4doLMMohps67Uqvq/GIuaZNgV0HaZA0QyL2c6S8NKGbPfqUyS5kDvQ0EyUSM7oaf2GytaRsjJyGpOp96Lx2XXlQwN0p4lne7HjSvjvN+M8J/mLHZ51AgMBAAECggEAbh0eZeudugOwh68OrcQx7gG7Ad+u0bt8fCiVhvlBHipH8l7ufIPW+6JLKyEU4HXlVdBsRGmfkKu5frxxh6SJYg8C9H9rBeWgS4kxocK32ZaSGP3kcCPH3Q45soaI/AmDEB/TlY24uojC99tg7kR/TGKQsRfGmfud4B/VR4PrXa0egek75qtzZWA2E7bJjwbTQ7BGacz/JsbcbXWfWKYLIHsl0IGzyrqPRaX2iE6qBWDnWZO7Fot9f72fPzo1tiYwDG5tEF61gchNQvQswqVgKRW7u5/o1C11p+WUt5ImDiW/TScAYvQGZA1eHD9Ex3f+0Lb/eJPEvmOXHys+46dDfQKBgQDjGQ/QU5z5uJSmcroO7NZMoYF8pp737Clc90B74a7gDdvYC/TqEqaRji13m1v7VNwh6Q578KXfFYKoQviSXL93aoc09lPnfPZAZ9CORGAQBjYfXgx6KOiQ+GcQy7r/MF7j67OAPJ4jj/FzdSRw3+zeUZzDdf3VoaU8BjBdfSRl+wKBgQDQZApoZ+fKotn6czEG8sjRNYGthEAiElGo9GWlupmTbUt2Zo7l0ywqFjyaenGO68cew5mD/4L3orxOBIunF8nL5pufSTeQI2QS3LpHdpMTIwUxvvaaa86PSSUD31qkmb6BZtZrKlNKpLnjCpZ7tyIfok1xjErT0go04DAPN9uSTwKBgAFwJDB+hwzxxUc0jMcRat37W9WNPI53WV+0VR0ztabHj6/Ti4575cAgNVt/iVqTE/3G+wd/450BBt3H5skOe0vnScnlEWzy1qBbx+9OsYkIcQlL0Cpp3eclG4n4sEtzY/ZvhKh4Ocwh2jaP9FYepOJXg/Wc5qmWp3Q02dONulBHAoGBAJbY0+/fxxoX6FIzMDonZNaMNOK16PbA6/uxbiMZgDIH26hJdQdIZZ/RmOz51VnvsqPCU04Jl3RKiKSxBaZeweSned9D0MS12asNvIoeezhPEWOBKGF/yHZQLEsxUxvzbsOc/Xl1mfVeaHDBKU1Es57Sjdy0ATZzxI+h+SgK9xZhAoGAECzncIpn4I0IyJ16ArMNGqC/VlF73auGB2gPtI7G+v1aROtm6n8xKoJQmDMAM0tyRLUP//TSK8NgNw4ACUy3QhwI6R+cnVziv6v9ozVvyaPrBChDshtzCblRSFhKqq+f0tEYVns5VwlM5jp8uFhIKxxjo4ufCdd5v9Ot868ArIY="; // 后端存储的私钥Base64字符串 + + private static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuN0b3wpJeNnyvGEFCQky3u0nGh/jkwXsVk8IlNRlsiC2ITcBrobrJifTII+/sL8bwfKfWU+h2AgX8HUZaZAJl2488hs2ScfJf56cKZsBjmTfCzUVEhg5jrTlxE/LB3kBtY+OgVfU4IZ/tlS/AKU+HY/hYrSq6O/3Dah825eJ6ooRIP0d0yssdl6NMp/8g1JnhWPUG+BViBWsI38GftPbaEFqUOi9ZppDWIjeHaCzDKIabOu1Kr6vxiLmmTYFdB2mQNEMi9nOkvDShmz36lMkuZA70NBMlEjO6Gn9hsrWkbIychqTqfei8dl15UMDdKeJZ3ux40r47zfjPCf5ix2edQIDAQAB"; + + /** + * 解密RSA加密后的字符串 + */ + public static String decrypt(String encryptedData) { + + try { + // 1. 解码私钥 + byte[] privateKeyBytes = Base64Utils.decodeFromString(PRIVATE_KEY); + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes); + PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec); + + // 2. 初始化解密器 + Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // 填充方式需与前端一致 + cipher.init(Cipher.DECRYPT_MODE, privateKey); + + // 3. 分段解密(前端分段加密,后端需对应分段解密) + byte[] encryptedBytes = Base64Utils.decodeFromString(encryptedData); + int maxDecryptLength = 256; // 2048位RSA的最大解密长度 + StringBuilder decryptedResult = new StringBuilder(); + for (int i = 0; i < encryptedBytes.length; i += maxDecryptLength) { + int length = Math.min(i + maxDecryptLength, encryptedBytes.length); + byte[] chunk = cipher.doFinal(encryptedBytes, i, length); + decryptedResult.append(new String(chunk, "UTF-8")); + } + return decryptedResult.toString(); + }catch (Exception e){ + System.out.println("公钥+++++++"+e.getMessage()); + } + return ""; + } + + public static String encryptWithPublicKey(String data) { + try { + // 解码公钥 + byte[] publicKeyBytes = Base64Utils.decodeFromString(PUBLIC_KEY); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes); + PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(keySpec); + + Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + + byte[] dataBytes = data.getBytes("UTF-8"); + int maxLength = 245; + StringBuilder encryptedResult = new StringBuilder(); + for (int i = 0; i < dataBytes.length; i += maxLength) { + int end = Math.min(i + maxLength, dataBytes.length); + byte[] chunk = cipher.doFinal(dataBytes, i, end - i); + if (encryptedResult.length() > 0) { + encryptedResult.append(","); + } + encryptedResult.append(Base64Utils.encodeToString(chunk)); + } + return encryptedResult.toString(); + } catch (Exception e) { + System.out.println("加密异常: " + e.getMessage()); + } + return ""; + } + + public static void main(String[] args) throws NoSuchAlgorithmException { + // Java生成RSA密钥对(2048位) + KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); + keyPairGen.initialize(2048); // 密钥长度2048位 + KeyPair keyPair = keyPairGen.generateKeyPair(); + String publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()); // 公钥Base64编码(前端使用) + String privateKey = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()); // 私钥Base64编码(后端存储) + System.out.println("公钥+++++++"+publicKey); + System.out.println("私钥+++++++"+privateKey); + } +} diff --git a/common/common-security/src/main/java/com/bonus/common/security/service/TokenService.java b/common/common-security/src/main/java/com/bonus/common/security/service/TokenService.java index df056f5..fb593e6 100644 --- a/common/common-security/src/main/java/com/bonus/common/security/service/TokenService.java +++ b/common/common-security/src/main/java/com/bonus/common/security/service/TokenService.java @@ -4,6 +4,8 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import javax.servlet.http.HttpServletRequest; + +import com.bonus.common.core.utils.RSAUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.bonus.common.core.constant.CacheConstants; @@ -19,7 +21,7 @@ import com.bonus.system.api.model.LoginUser; /** * token验证处理 - * + * * @author zys */ @Component @@ -46,6 +48,8 @@ public class TokenService String token = IdUtils.fastUUID(); Long userId = loginUser.getSysUser().getUserId(); String userName = loginUser.getSysUser().getUserName(); + loginUser.getSysUser().setIdNumber(RSAUtil.encryptWithPublicKey(loginUser.getSysUser().getIdNumber())); + loginUser.getSysUser().setPhonenumber(RSAUtil.encryptWithPublicKey(loginUser.getSysUser().getPhonenumber())); loginUser.setToken(token); loginUser.setUserid(userId); loginUser.setUsername(userName); @@ -135,7 +139,7 @@ public class TokenService } /** - * 验证令牌有效期,相差不足120分钟,自动刷新缓存 + * 验证令牌有效期,相差不足30分钟,自动刷新缓存 * * @param loginUser */ @@ -167,4 +171,4 @@ public class TokenService { return ACCESS_TOKEN + token; } -} \ No newline at end of file +} diff --git a/modules/bmw/src/main/resources/static/js/Rsa.js b/modules/bmw/src/main/resources/static/js/Rsa.js new file mode 100644 index 0000000..1fb740e --- /dev/null +++ b/modules/bmw/src/main/resources/static/js/Rsa.js @@ -0,0 +1,72 @@ +/*! For license information please see jsencrypt.min.js.LICENSE.txt */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.JSEncrypt=e():t.JSEncrypt=e()}(window,(()=>(()=>{var t={155:t=>{var e,i,r=t.exports={};function n(){throw new Error("setTimeout has not been defined")}function s(){throw new Error("clearTimeout has not been defined")}function o(t){if(e===setTimeout)return setTimeout(t,0);if((e===n||!e)&&setTimeout)return e=setTimeout,setTimeout(t,0);try{return e(t,0)}catch(i){try{return e.call(null,t,0)}catch(i){return e.call(this,t,0)}}}!function(){try{e="function"==typeof setTimeout?setTimeout:n}catch(t){e=n}try{i="function"==typeof clearTimeout?clearTimeout:s}catch(t){i=s}}();var h,a=[],u=!1,c=-1;function f(){u&&h&&(u=!1,h.length?a=h.concat(a):c=-1,a.length&&l())}function l(){if(!u){var t=o(f);u=!0;for(var e=a.length;e;){for(h=a,a=[];++c1)for(var i=1;i{for(var r in e)i.o(e,r)&&!i.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);var r={};return(()=>{"use strict";i.d(r,{default:()=>ct});var t="0123456789abcdefghijklmnopqrstuvwxyz";function e(e){return t.charAt(e)}function n(t,e){return t&e}function s(t,e){return t|e}function o(t,e){return t^e}function h(t,e){return t&~e}function a(t){if(0==t)return-1;var e=0;return 0==(65535&t)&&(t>>=16,e+=16),0==(255&t)&&(t>>=8,e+=8),0==(15&t)&&(t>>=4,e+=4),0==(3&t)&&(t>>=2,e+=2),0==(1&t)&&++e,e}function u(t){for(var e=0;0!=t;)t&=t-1,++e;return e}var c,f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",l="=";function p(t){var e,i,r="";for(e=0;e+3<=t.length;e+=3)i=parseInt(t.substring(e,e+3),16),r+=f.charAt(i>>6)+f.charAt(63&i);for(e+1==t.length?(i=parseInt(t.substring(e,e+1),16),r+=f.charAt(i<<2)):e+2==t.length&&(i=parseInt(t.substring(e,e+2),16),r+=f.charAt(i>>2)+f.charAt((3&i)<<4));(3&r.length)>0;)r+=l;return r}function g(t){var i,r="",n=0,s=0;for(i=0;i>2),s=3&o,n=1):1==n?(r+=e(s<<2|o>>4),s=15&o,n=2):2==n?(r+=e(s),r+=e(o>>2),s=3&o,n=3):(r+=e(s<<2|o>>4),r+=e(15&o),n=0))}return 1==n&&(r+=e(s<<2)),r}var d,v={decode:function(t){var e;if(void 0===d){var i="= \f\n\r\t \u2028\u2029";for(d=Object.create(null),e=0;e<64;++e)d["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(e)]=e;for(d["-"]=62,d._=63,e=0;e=4?(r[r.length]=n>>16,r[r.length]=n>>8&255,r[r.length]=255&n,n=0,s=0):n<<=6}}switch(s){case 1:throw new Error("Base64 encoding incomplete: at least 2 bits missing");case 2:r[r.length]=n>>10;break;case 3:r[r.length]=n>>16,r[r.length]=n>>8&255}return r},re:/-----BEGIN [^-]+-----([A-Za-z0-9+\/=\s]+)-----END [^-]+-----|begin-base64[^\n]+\n([A-Za-z0-9+\/=\s]+)====/,unarmor:function(t){var e=v.re.exec(t);if(e)if(e[1])t=e[1];else{if(!e[2])throw new Error("RegExp out of sync");t=e[2]}return v.decode(t)}},m=1e13,y=function(){function t(t){this.buf=[+t||0]}return t.prototype.mulAdd=function(t,e){var i,r,n=this.buf,s=n.length;for(i=0;i0&&(n[i]=e)},t.prototype.sub=function(t){var e,i,r=this.buf,n=r.length;for(e=0;e=0;--r)i+=(m+e[r]).toString().substring(1);return i},t.prototype.valueOf=function(){for(var t=this.buf,e=0,i=t.length-1;i>=0;--i)e=e*m+t[i];return e},t.prototype.simplify=function(){var t=this.buf;return 1==t.length?t[0]:this},t}(),b="…",T=/^(\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/,S=/^(\d\d\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/;function E(t,e){return t.length>e&&(t=t.substring(0,e)+b),t}var w,D=function(){function t(e,i){this.hexDigits="0123456789ABCDEF",e instanceof t?(this.enc=e.enc,this.pos=e.pos):(this.enc=e,this.pos=i)}return t.prototype.get=function(t){if(void 0===t&&(t=this.pos++),t>=this.enc.length)throw new Error("Requesting byte offset ".concat(t," on a stream of length ").concat(this.enc.length));return"string"==typeof this.enc?this.enc.charCodeAt(t):this.enc[t]},t.prototype.hexByte=function(t){return this.hexDigits.charAt(t>>4&15)+this.hexDigits.charAt(15&t)},t.prototype.hexDump=function(t,e,i){for(var r="",n=t;n176)return!1}return!0},t.prototype.parseStringISO=function(t,e){for(var i="",r=t;r191&&n<224?String.fromCharCode((31&n)<<6|63&this.get(r++)):String.fromCharCode((15&n)<<12|(63&this.get(r++))<<6|63&this.get(r++))}return i},t.prototype.parseStringBMP=function(t,e){for(var i,r,n="",s=t;s127,s=n?255:0,o="";r==s&&++t4){for(o=r,i<<=3;0==(128&(+o^s));)o=+o<<1,--i;o="("+i+" bit)\n"}n&&(r-=256);for(var h=new y(r),a=t+1;a=a;--u)s+=h>>u&1?"1":"0";if(s.length>i)return n+E(s,i)}return n+s},t.prototype.parseOctetString=function(t,e,i){if(this.isASCII(t,e))return E(this.parseStringISO(t,e),i);var r=e-t,n="("+r+" byte)\n";r>(i/=2)&&(e=t+i);for(var s=t;si&&(n+=b),n},t.prototype.parseOID=function(t,e,i){for(var r="",n=new y,s=0,o=t;oi)return E(r,i);n=new y,s=0}}return s>0&&(r+=".incomplete"),r},t}(),x=function(){function t(t,e,i,r,n){if(!(r instanceof R))throw new Error("Invalid tag value.");this.stream=t,this.header=e,this.length=i,this.tag=r,this.sub=n}return t.prototype.typeName=function(){switch(this.tag.tagClass){case 0:switch(this.tag.tagNumber){case 0:return"EOC";case 1:return"BOOLEAN";case 2:return"INTEGER";case 3:return"BIT_STRING";case 4:return"OCTET_STRING";case 5:return"NULL";case 6:return"OBJECT_IDENTIFIER";case 7:return"ObjectDescriptor";case 8:return"EXTERNAL";case 9:return"REAL";case 10:return"ENUMERATED";case 11:return"EMBEDDED_PDV";case 12:return"UTF8String";case 16:return"SEQUENCE";case 17:return"SET";case 18:return"NumericString";case 19:return"PrintableString";case 20:return"TeletexString";case 21:return"VideotexString";case 22:return"IA5String";case 23:return"UTCTime";case 24:return"GeneralizedTime";case 25:return"GraphicString";case 26:return"VisibleString";case 27:return"GeneralString";case 28:return"UniversalString";case 30:return"BMPString"}return"Universal_"+this.tag.tagNumber.toString();case 1:return"Application_"+this.tag.tagNumber.toString();case 2:return"["+this.tag.tagNumber.toString()+"]";case 3:return"Private_"+this.tag.tagNumber.toString()}},t.prototype.content=function(t){if(void 0===this.tag)return null;void 0===t&&(t=1/0);var e=this.posContent(),i=Math.abs(this.length);if(!this.tag.isUniversal())return null!==this.sub?"("+this.sub.length+" elem)":this.stream.parseOctetString(e,e+i,t);switch(this.tag.tagNumber){case 1:return 0===this.stream.get(e)?"false":"true";case 2:return this.stream.parseInteger(e,e+i);case 3:return this.sub?"("+this.sub.length+" elem)":this.stream.parseBitString(e,e+i,t);case 4:return this.sub?"("+this.sub.length+" elem)":this.stream.parseOctetString(e,e+i,t);case 6:return this.stream.parseOID(e,e+i,t);case 16:case 17:return null!==this.sub?"("+this.sub.length+" elem)":"(no elem)";case 12:return E(this.stream.parseStringUTF(e,e+i),t);case 18:case 19:case 20:case 21:case 22:case 26:return E(this.stream.parseStringISO(e,e+i),t);case 30:return E(this.stream.parseStringBMP(e,e+i),t);case 23:case 24:return this.stream.parseTime(e,e+i,23==this.tag.tagNumber)}return null},t.prototype.toString=function(){return this.typeName()+"@"+this.stream.pos+"[header:"+this.header+",length:"+this.length+",sub:"+(null===this.sub?"null":this.sub.length)+"]"},t.prototype.toPrettyString=function(t){void 0===t&&(t="");var e=t+this.typeName()+" @"+this.stream.pos;if(this.length>=0&&(e+="+"),e+=this.length,this.tag.tagConstructed?e+=" (constructed)":!this.tag.isUniversal()||3!=this.tag.tagNumber&&4!=this.tag.tagNumber||null===this.sub||(e+=" (encapsulates)"),e+="\n",null!==this.sub){t+=" ";for(var i=0,r=this.sub.length;i6)throw new Error("Length over 48 bits not supported at position "+(t.pos-1));if(0===i)return null;e=0;for(var r=0;r>6,this.tagConstructed=0!=(32&e),this.tagNumber=31&e,31==this.tagNumber){var i=new y;do{e=t.get(),i.mulAdd(128,127&e)}while(128&e);this.tagNumber=i.simplify()}}return t.prototype.isUniversal=function(){return 0===this.tagClass},t.prototype.isEOC=function(){return 0===this.tagClass&&0===this.tagNumber},t}(),B=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997],O=(1<<26)/B[B.length-1],A=function(){function t(t,e,i){null!=t&&("number"==typeof t?this.fromNumber(t,e,i):null==e&&"string"!=typeof t?this.fromString(t,256):this.fromString(t,e))}return t.prototype.toString=function(t){if(this.s<0)return"-"+this.negate().toString(t);var i;if(16==t)i=4;else if(8==t)i=3;else if(2==t)i=1;else if(32==t)i=5;else{if(4!=t)return this.toRadix(t);i=2}var r,n=(1<0)for(a>a)>0&&(s=!0,o=e(r));h>=0;)a>(a+=this.DB-i)):(r=this[h]>>(a-=i)&n,a<=0&&(a+=this.DB,--h)),r>0&&(s=!0),s&&(o+=e(r));return s?o:"0"},t.prototype.negate=function(){var e=M();return t.ZERO.subTo(this,e),e},t.prototype.abs=function(){return this.s<0?this.negate():this},t.prototype.compareTo=function(t){var e=this.s-t.s;if(0!=e)return e;var i=this.t;if(0!=(e=i-t.t))return this.s<0?-e:e;for(;--i>=0;)if(0!=(e=this[i]-t[i]))return e;return 0},t.prototype.bitLength=function(){return this.t<=0?0:this.DB*(this.t-1)+K(this[this.t-1]^this.s&this.DM)},t.prototype.mod=function(e){var i=M();return this.abs().divRemTo(e,null,i),this.s<0&&i.compareTo(t.ZERO)>0&&e.subTo(i,i),i},t.prototype.modPowInt=function(t,e){var i;return i=t<256||e.isEven()?new I(e):new N(e),this.exp(t,i)},t.prototype.clone=function(){var t=M();return this.copyTo(t),t},t.prototype.intValue=function(){if(this.s<0){if(1==this.t)return this[0]-this.DV;if(0==this.t)return-1}else{if(1==this.t)return this[0];if(0==this.t)return 0}return(this[1]&(1<<32-this.DB)-1)<>24},t.prototype.shortValue=function(){return 0==this.t?this.s:this[0]<<16>>16},t.prototype.signum=function(){return this.s<0?-1:this.t<=0||1==this.t&&this[0]<=0?0:1},t.prototype.toByteArray=function(){var t=this.t,e=[];e[0]=this.s;var i,r=this.DB-t*this.DB%8,n=0;if(t-- >0)for(r>r)!=(this.s&this.DM)>>r&&(e[n++]=i|this.s<=0;)r<8?(i=(this[t]&(1<>(r+=this.DB-8)):(i=this[t]>>(r-=8)&255,r<=0&&(r+=this.DB,--t)),0!=(128&i)&&(i|=-256),0==n&&(128&this.s)!=(128&i)&&++n,(n>0||i!=this.s)&&(e[n++]=i);return e},t.prototype.equals=function(t){return 0==this.compareTo(t)},t.prototype.min=function(t){return this.compareTo(t)<0?this:t},t.prototype.max=function(t){return this.compareTo(t)>0?this:t},t.prototype.and=function(t){var e=M();return this.bitwiseTo(t,n,e),e},t.prototype.or=function(t){var e=M();return this.bitwiseTo(t,s,e),e},t.prototype.xor=function(t){var e=M();return this.bitwiseTo(t,o,e),e},t.prototype.andNot=function(t){var e=M();return this.bitwiseTo(t,h,e),e},t.prototype.not=function(){for(var t=M(),e=0;e=this.t?0!=this.s:0!=(this[e]&1<1){var c=M();for(r.sqrTo(o[1],c);h<=u;)o[h]=M(),r.mulTo(c,o[h-2],o[h]),h+=2}var f,l,p=t.t-1,g=!0,d=M();for(n=K(t[p])-1;p>=0;){for(n>=a?f=t[p]>>n-a&u:(f=(t[p]&(1<0&&(f|=t[p-1]>>this.DB+n-a)),h=i;0==(1&f);)f>>=1,--h;if((n-=h)<0&&(n+=this.DB,--p),g)o[f].copyTo(s),g=!1;else{for(;h>1;)r.sqrTo(s,d),r.sqrTo(d,s),h-=2;h>0?r.sqrTo(s,d):(l=s,s=d,d=l),r.mulTo(d,o[f],s)}for(;p>=0&&0==(t[p]&1<=0?(r.subTo(n,r),i&&s.subTo(h,s),o.subTo(a,o)):(n.subTo(r,n),i&&h.subTo(s,h),a.subTo(o,a))}return 0!=n.compareTo(t.ONE)?t.ZERO:a.compareTo(e)>=0?a.subtract(e):a.signum()<0?(a.addTo(e,a),a.signum()<0?a.add(e):a):a},t.prototype.pow=function(t){return this.exp(t,new V)},t.prototype.gcd=function(t){var e=this.s<0?this.negate():this.clone(),i=t.s<0?t.negate():t.clone();if(e.compareTo(i)<0){var r=e;e=i,i=r}var n=e.getLowestSetBit(),s=i.getLowestSetBit();if(s<0)return e;for(n0&&(e.rShiftTo(s,e),i.rShiftTo(s,i));e.signum()>0;)(n=e.getLowestSetBit())>0&&e.rShiftTo(n,e),(n=i.getLowestSetBit())>0&&i.rShiftTo(n,i),e.compareTo(i)>=0?(e.subTo(i,e),e.rShiftTo(1,e)):(i.subTo(e,i),i.rShiftTo(1,i));return s>0&&i.lShiftTo(s,i),i},t.prototype.isProbablePrime=function(t){var e,i=this.abs();if(1==i.t&&i[0]<=B[B.length-1]){for(e=0;e=0;--e)t[e]=this[e];t.t=this.t,t.s=this.s},t.prototype.fromInt=function(t){this.t=1,this.s=t<0?-1:0,t>0?this[0]=t:t<-1?this[0]=t+this.DV:this.t=0},t.prototype.fromString=function(e,i){var r;if(16==i)r=4;else if(8==i)r=3;else if(256==i)r=8;else if(2==i)r=1;else if(32==i)r=5;else{if(4!=i)return void this.fromRadix(e,i);r=2}this.t=0,this.s=0;for(var n=e.length,s=!1,o=0;--n>=0;){var h=8==r?255&+e[n]:F(e,n);h<0?"-"==e.charAt(n)&&(s=!0):(s=!1,0==o?this[this.t++]=h:o+r>this.DB?(this[this.t-1]|=(h&(1<>this.DB-o):this[this.t-1]|=h<=this.DB&&(o-=this.DB))}8==r&&0!=(128&+e[0])&&(this.s=-1,o>0&&(this[this.t-1]|=(1<0&&this[this.t-1]==t;)--this.t},t.prototype.dlShiftTo=function(t,e){var i;for(i=this.t-1;i>=0;--i)e[i+t]=this[i];for(i=t-1;i>=0;--i)e[i]=0;e.t=this.t+t,e.s=this.s},t.prototype.drShiftTo=function(t,e){for(var i=t;i=0;--h)e[h+s+1]=this[h]>>r|o,o=(this[h]&n)<=0;--h)e[h]=0;e[s]=o,e.t=this.t+s+1,e.s=this.s,e.clamp()},t.prototype.rShiftTo=function(t,e){e.s=this.s;var i=Math.floor(t/this.DB);if(i>=this.t)e.t=0;else{var r=t%this.DB,n=this.DB-r,s=(1<>r;for(var o=i+1;o>r;r>0&&(e[this.t-i-1]|=(this.s&s)<>=this.DB;if(t.t>=this.DB;r+=this.s}else{for(r+=this.s;i>=this.DB;r-=t.s}e.s=r<0?-1:0,r<-1?e[i++]=this.DV+r:r>0&&(e[i++]=r),e.t=i,e.clamp()},t.prototype.multiplyTo=function(e,i){var r=this.abs(),n=e.abs(),s=r.t;for(i.t=s+n.t;--s>=0;)i[s]=0;for(s=0;s=0;)t[i]=0;for(i=0;i=e.DV&&(t[i+e.t]-=e.DV,t[i+e.t+1]=1)}t.t>0&&(t[t.t-1]+=e.am(i,e[i],t,2*i,0,1)),t.s=0,t.clamp()},t.prototype.divRemTo=function(e,i,r){var n=e.abs();if(!(n.t<=0)){var s=this.abs();if(s.t0?(n.lShiftTo(u,o),s.lShiftTo(u,r)):(n.copyTo(o),s.copyTo(r));var c=o.t,f=o[c-1];if(0!=f){var l=f*(1<1?o[c-2]>>this.F2:0),p=this.FV/l,g=(1<=0&&(r[r.t++]=1,r.subTo(y,r)),t.ONE.dlShiftTo(c,y),y.subTo(o,o);o.t=0;){var b=r[--v]==f?this.DM:Math.floor(r[v]*p+(r[v-1]+d)*g);if((r[v]+=o.am(0,b,r,m,0,c))0&&r.rShiftTo(u,r),h<0&&t.ZERO.subTo(r,r)}}},t.prototype.invDigit=function(){if(this.t<1)return 0;var t=this[0];if(0==(1&t))return 0;var e=3&t;return(e=(e=(e=(e=e*(2-(15&t)*e)&15)*(2-(255&t)*e)&255)*(2-((65535&t)*e&65535))&65535)*(2-t*e%this.DV)%this.DV)>0?this.DV-e:-e},t.prototype.isEven=function(){return 0==(this.t>0?1&this[0]:this.s)},t.prototype.exp=function(e,i){if(e>4294967295||e<1)return t.ONE;var r=M(),n=M(),s=i.convert(this),o=K(e)-1;for(s.copyTo(r);--o>=0;)if(i.sqrTo(r,n),(e&1<0)i.mulTo(n,s,r);else{var h=r;r=n,n=h}return i.revert(r)},t.prototype.chunkSize=function(t){return Math.floor(Math.LN2*this.DB/Math.log(t))},t.prototype.toRadix=function(t){if(null==t&&(t=10),0==this.signum()||t<2||t>36)return"0";var e=this.chunkSize(t),i=Math.pow(t,e),r=U(i),n=M(),s=M(),o="";for(this.divRemTo(r,n,s);n.signum()>0;)o=(i+s.intValue()).toString(t).substr(1)+o,n.divRemTo(r,n,s);return s.intValue().toString(t)+o},t.prototype.fromRadix=function(e,i){this.fromInt(0),null==i&&(i=10);for(var r=this.chunkSize(i),n=Math.pow(i,r),s=!1,o=0,h=0,a=0;a=r&&(this.dMultiply(n),this.dAddOffset(h,0),o=0,h=0))}o>0&&(this.dMultiply(Math.pow(i,o)),this.dAddOffset(h,0)),s&&t.ZERO.subTo(this,this)},t.prototype.fromNumber=function(e,i,r){if("number"==typeof i)if(e<2)this.fromInt(1);else for(this.fromNumber(e,r),this.testBit(e-1)||this.bitwiseTo(t.ONE.shiftLeft(e-1),s,this),this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(i);)this.dAddOffset(2,0),this.bitLength()>e&&this.subTo(t.ONE.shiftLeft(e-1),this);else{var n=[],o=7&e;n.length=1+(e>>3),i.nextBytes(n),o>0?n[0]&=(1<>=this.DB;if(t.t>=this.DB;r+=this.s}else{for(r+=this.s;i>=this.DB;r+=t.s}e.s=r<0?-1:0,r>0?e[i++]=r:r<-1&&(e[i++]=this.DV+r),e.t=i,e.clamp()},t.prototype.dMultiply=function(t){this[this.t]=this.am(0,t-1,this,0,0,this.t),++this.t,this.clamp()},t.prototype.dAddOffset=function(t,e){if(0!=t){for(;this.t<=e;)this[this.t++]=0;for(this[e]+=t;this[e]>=this.DV;)this[e]-=this.DV,++e>=this.t&&(this[this.t++]=0),++this[e]}},t.prototype.multiplyLowerTo=function(t,e,i){var r=Math.min(this.t+t.t,e);for(i.s=0,i.t=r;r>0;)i[--r]=0;for(var n=i.t-this.t;r=0;)i[r]=0;for(r=Math.max(e-this.t,0);r0)if(0==e)i=this[0]%t;else for(var r=this.t-1;r>=0;--r)i=(e*i+this[r])%t;return i},t.prototype.millerRabin=function(e){var i=this.subtract(t.ONE),r=i.getLowestSetBit();if(r<=0)return!1;var n=i.shiftRight(r);(e=e+1>>1)>B.length&&(e=B.length);for(var s=M(),o=0;o0&&(i.rShiftTo(o,i),r.rShiftTo(o,r));var h=function(){(s=i.getLowestSetBit())>0&&i.rShiftTo(s,i),(s=r.getLowestSetBit())>0&&r.rShiftTo(s,r),i.compareTo(r)>=0?(i.subTo(r,i),i.rShiftTo(1,i)):(r.subTo(i,r),r.rShiftTo(1,r)),i.signum()>0?setTimeout(h,0):(o>0&&r.lShiftTo(o,r),setTimeout((function(){e(r)}),0))};setTimeout(h,10)}},t.prototype.fromNumberAsync=function(e,i,r,n){if("number"==typeof i)if(e<2)this.fromInt(1);else{this.fromNumber(e,r),this.testBit(e-1)||this.bitwiseTo(t.ONE.shiftLeft(e-1),s,this),this.isEven()&&this.dAddOffset(1,0);var o=this,h=function(){o.dAddOffset(2,0),o.bitLength()>e&&o.subTo(t.ONE.shiftLeft(e-1),o),o.isProbablePrime(i)?setTimeout((function(){n()}),0):setTimeout(h,0)};setTimeout(h,0)}else{var a=[],u=7&e;a.length=1+(e>>3),i.nextBytes(a),u>0?a[0]&=(1<=0?t.mod(this.m):t},t.prototype.revert=function(t){return t},t.prototype.reduce=function(t){t.divRemTo(this.m,null,t)},t.prototype.mulTo=function(t,e,i){t.multiplyTo(e,i),this.reduce(i)},t.prototype.sqrTo=function(t,e){t.squareTo(e),this.reduce(e)},t}(),N=function(){function t(t){this.m=t,this.mp=t.invDigit(),this.mpl=32767&this.mp,this.mph=this.mp>>15,this.um=(1<0&&this.m.subTo(e,e),e},t.prototype.revert=function(t){var e=M();return t.copyTo(e),this.reduce(e),e},t.prototype.reduce=function(t){for(;t.t<=this.mt2;)t[t.t++]=0;for(var e=0;e>15)*this.mpl&this.um)<<15)&t.DM;for(t[i=e+this.m.t]+=this.m.am(0,r,t,e,0,this.m.t);t[i]>=t.DV;)t[i]-=t.DV,t[++i]++}t.clamp(),t.drShiftTo(this.m.t,t),t.compareTo(this.m)>=0&&t.subTo(this.m,t)},t.prototype.mulTo=function(t,e,i){t.multiplyTo(e,i),this.reduce(i)},t.prototype.sqrTo=function(t,e){t.squareTo(e),this.reduce(e)},t}(),P=function(){function t(t){this.m=t,this.r2=M(),this.q3=M(),A.ONE.dlShiftTo(2*t.t,this.r2),this.mu=this.r2.divide(t)}return t.prototype.convert=function(t){if(t.s<0||t.t>2*this.m.t)return t.mod(this.m);if(t.compareTo(this.m)<0)return t;var e=M();return t.copyTo(e),this.reduce(e),e},t.prototype.revert=function(t){return t},t.prototype.reduce=function(t){for(t.drShiftTo(this.m.t-1,this.r2),t.t>this.m.t+1&&(t.t=this.m.t+1,t.clamp()),this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3),this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);t.compareTo(this.r2)<0;)t.dAddOffset(1,this.m.t+1);for(t.subTo(this.r2,t);t.compareTo(this.m)>=0;)t.subTo(this.m,t)},t.prototype.mulTo=function(t,e,i){t.multiplyTo(e,i),this.reduce(i)},t.prototype.sqrTo=function(t,e){t.squareTo(e),this.reduce(e)},t}();function M(){return new A(null)}function L(t,e){return new A(t,e)}var j="undefined"!=typeof navigator;j&&"Microsoft Internet Explorer"==navigator.appName?(A.prototype.am=function(t,e,i,r,n,s){for(var o=32767&e,h=e>>15;--s>=0;){var a=32767&this[t],u=this[t++]>>15,c=h*a+u*o;n=((a=o*a+((32767&c)<<15)+i[r]+(1073741823&n))>>>30)+(c>>>15)+h*u+(n>>>30),i[r++]=1073741823&a}return n},w=30):j&&"Netscape"!=navigator.appName?(A.prototype.am=function(t,e,i,r,n,s){for(;--s>=0;){var o=e*this[t++]+i[r]+n;n=Math.floor(o/67108864),i[r++]=67108863&o}return n},w=26):(A.prototype.am=function(t,e,i,r,n,s){for(var o=16383&e,h=e>>14;--s>=0;){var a=16383&this[t],u=this[t++]>>14,c=h*a+u*o;n=((a=o*a+((16383&c)<<14)+i[r]+n)>>28)+(c>>14)+h*u,i[r++]=268435455&a}return n},w=28),A.prototype.DB=w,A.prototype.DM=(1<>>16)&&(t=e,i+=16),0!=(e=t>>8)&&(t=e,i+=8),0!=(e=t>>4)&&(t=e,i+=4),0!=(e=t>>2)&&(t=e,i+=2),0!=(e=t>>1)&&(t=e,i+=1),i}A.ZERO=U(0),A.ONE=U(1);var k,_,z=function(){function t(){this.i=0,this.j=0,this.S=[]}return t.prototype.init=function(t){var e,i,r;for(e=0;e<256;++e)this.S[e]=e;for(i=0,e=0;e<256;++e)i=i+this.S[e]+t[e%t.length]&255,r=this.S[e],this.S[e]=this.S[i],this.S[i]=r;this.i=0,this.j=0},t.prototype.next=function(){var t;return this.i=this.i+1&255,this.j=this.j+this.S[this.i]&255,t=this.S[this.i],this.S[this.i]=this.S[this.j],this.S[this.j]=t,this.S[t+this.S[this.i]&255]},t}(),Z=256,G=null;if(null==G){G=[],_=0;var $=void 0;if("undefined"!=typeof window&&window.crypto&&window.crypto.getRandomValues){var Y=new Uint32Array(256);for(window.crypto.getRandomValues(Y),$=0;$=256||_>=Z)window.removeEventListener?window.removeEventListener("mousemove",X,!1):window.detachEvent&&window.detachEvent("onmousemove",X);else try{var e=t.x+t.y;G[_++]=255&e,J+=1}catch(t){}};"undefined"!=typeof window&&(window.addEventListener?window.addEventListener("mousemove",X,!1):window.attachEvent&&window.attachEvent("onmousemove",X))}function Q(){if(null==k){for(k=new z;_0&&e.length>0?(this.n=L(t,16),this.e=parseInt(e,16)):console.error("Invalid RSA public key")},t.prototype.encrypt=function(t){var e=this.n.bitLength()+7>>3,i=function(t,e){if(e=0&&e>0;){var n=t.charCodeAt(r--);n<128?i[--e]=n:n>127&&n<2048?(i[--e]=63&n|128,i[--e]=n>>6|192):(i[--e]=63&n|128,i[--e]=n>>6&63|128,i[--e]=n>>12|224)}i[--e]=0;for(var s=new W,o=[];e>2;){for(o[0]=0;0==o[0];)s.nextBytes(o);i[--e]=o[0]}return i[--e]=2,i[--e]=0,new A(i)}(t,e);if(null==i)return null;var r=this.doPublic(i);if(null==r)return null;for(var n=r.toString(16),s=n.length,o=0;o<2*e-s;o++)n="0"+n;return n},t.prototype.setPrivate=function(t,e,i){null!=t&&null!=e&&t.length>0&&e.length>0?(this.n=L(t,16),this.e=parseInt(e,16),this.d=L(i,16)):console.error("Invalid RSA private key")},t.prototype.setPrivateEx=function(t,e,i,r,n,s,o,h){null!=t&&null!=e&&t.length>0&&e.length>0?(this.n=L(t,16),this.e=parseInt(e,16),this.d=L(i,16),this.p=L(r,16),this.q=L(n,16),this.dmp1=L(s,16),this.dmq1=L(o,16),this.coeff=L(h,16)):console.error("Invalid RSA private key")},t.prototype.generate=function(t,e){var i=new W,r=t>>1;this.e=parseInt(e,16);for(var n=new A(e,16);;){for(;this.p=new A(t-r,1,i),0!=this.p.subtract(A.ONE).gcd(n).compareTo(A.ONE)||!this.p.isProbablePrime(10););for(;this.q=new A(r,1,i),0!=this.q.subtract(A.ONE).gcd(n).compareTo(A.ONE)||!this.q.isProbablePrime(10););if(this.p.compareTo(this.q)<=0){var s=this.p;this.p=this.q,this.q=s}var o=this.p.subtract(A.ONE),h=this.q.subtract(A.ONE),a=o.multiply(h);if(0==a.gcd(n).compareTo(A.ONE)){this.n=this.p.multiply(this.q),this.d=n.modInverse(a),this.dmp1=this.d.mod(o),this.dmq1=this.d.mod(h),this.coeff=this.q.modInverse(this.p);break}}},t.prototype.decrypt=function(t){var e=L(t,16),i=this.doPrivate(e);return null==i?null:function(t,e){for(var i=t.toByteArray(),r=0;r=i.length)return null;for(var n="";++r191&&s<224?(n+=String.fromCharCode((31&s)<<6|63&i[r+1]),++r):(n+=String.fromCharCode((15&s)<<12|(63&i[r+1])<<6|63&i[r+2]),r+=2)}return n}(i,this.n.bitLength()+7>>3)},t.prototype.generateAsync=function(t,e,i){var r=new W,n=t>>1;this.e=parseInt(e,16);var s=new A(e,16),o=this,h=function(){var e=function(){if(o.p.compareTo(o.q)<=0){var t=o.p;o.p=o.q,o.q=t}var e=o.p.subtract(A.ONE),r=o.q.subtract(A.ONE),n=e.multiply(r);0==n.gcd(s).compareTo(A.ONE)?(o.n=o.p.multiply(o.q),o.d=s.modInverse(n),o.dmp1=o.d.mod(e),o.dmq1=o.d.mod(r),o.coeff=o.q.modInverse(o.p),setTimeout((function(){i()}),0)):setTimeout(h,0)},a=function(){o.q=M(),o.q.fromNumberAsync(n,1,r,(function(){o.q.subtract(A.ONE).gcda(s,(function(t){0==t.compareTo(A.ONE)&&o.q.isProbablePrime(10)?setTimeout(e,0):setTimeout(a,0)}))}))},u=function(){o.p=M(),o.p.fromNumberAsync(t-n,1,r,(function(){o.p.subtract(A.ONE).gcda(s,(function(t){0==t.compareTo(A.ONE)&&o.p.isProbablePrime(10)?setTimeout(a,0):setTimeout(u,0)}))}))};setTimeout(u,0)};setTimeout(h,0)},t.prototype.sign=function(t,e,i){var r=function(t,e){if(e15)throw"ASN.1 length too long to represent by 8x: n = "+t.toString(16);return(128+i).toString(16)+e},this.getEncodedHex=function(){return(null==this.hTLV||this.isModified)&&(this.hV=this.getFreshValueHex(),this.hL=this.getLengthHexFromValue(),this.hTLV=this.hT+this.hL+this.hV,this.isModified=!1),this.hTLV},this.getValueHex=function(){return this.getEncodedHex(),this.hV},this.getFreshValueHex=function(){return""}},rt.asn1.DERAbstractString=function(t){rt.asn1.DERAbstractString.superclass.constructor.call(this),this.getString=function(){return this.s},this.setString=function(t){this.hTLV=null,this.isModified=!0,this.s=t,this.hV=stohex(this.s)},this.setStringHex=function(t){this.hTLV=null,this.isModified=!0,this.s=null,this.hV=t},this.getFreshValueHex=function(){return this.hV},void 0!==t&&("string"==typeof t?this.setString(t):void 0!==t.str?this.setString(t.str):void 0!==t.hex&&this.setStringHex(t.hex))},it.lang.extend(rt.asn1.DERAbstractString,rt.asn1.ASN1Object),rt.asn1.DERAbstractTime=function(t){rt.asn1.DERAbstractTime.superclass.constructor.call(this),this.localDateToUTC=function(t){return utc=t.getTime()+6e4*t.getTimezoneOffset(),new Date(utc)},this.formatDate=function(t,e,i){var r=this.zeroPadding,n=this.localDateToUTC(t),s=String(n.getFullYear());"utc"==e&&(s=s.substr(2,2));var o=s+r(String(n.getMonth()+1),2)+r(String(n.getDate()),2)+r(String(n.getHours()),2)+r(String(n.getMinutes()),2)+r(String(n.getSeconds()),2);if(!0===i){var h=n.getMilliseconds();if(0!=h){var a=r(String(h),3);o=o+"."+(a=a.replace(/[0]+$/,""))}}return o+"Z"},this.zeroPadding=function(t,e){return t.length>=e?t:new Array(e-t.length+1).join("0")+t},this.getString=function(){return this.s},this.setString=function(t){this.hTLV=null,this.isModified=!0,this.s=t,this.hV=stohex(t)},this.setByDateValue=function(t,e,i,r,n,s){var o=new Date(Date.UTC(t,e-1,i,r,n,s,0));this.setByDate(o)},this.getFreshValueHex=function(){return this.hV}},it.lang.extend(rt.asn1.DERAbstractTime,rt.asn1.ASN1Object),rt.asn1.DERAbstractStructured=function(t){rt.asn1.DERAbstractString.superclass.constructor.call(this),this.setByASN1ObjectArray=function(t){this.hTLV=null,this.isModified=!0,this.asn1Array=t},this.appendASN1Object=function(t){this.hTLV=null,this.isModified=!0,this.asn1Array.push(t)},this.asn1Array=new Array,void 0!==t&&void 0!==t.array&&(this.asn1Array=t.array)},it.lang.extend(rt.asn1.DERAbstractStructured,rt.asn1.ASN1Object),rt.asn1.DERBoolean=function(){rt.asn1.DERBoolean.superclass.constructor.call(this),this.hT="01",this.hTLV="0101ff"},it.lang.extend(rt.asn1.DERBoolean,rt.asn1.ASN1Object),rt.asn1.DERInteger=function(t){rt.asn1.DERInteger.superclass.constructor.call(this),this.hT="02",this.setByBigInteger=function(t){this.hTLV=null,this.isModified=!0,this.hV=rt.asn1.ASN1Util.bigIntToMinTwosComplementsHex(t)},this.setByInteger=function(t){var e=new A(String(t),10);this.setByBigInteger(e)},this.setValueHex=function(t){this.hV=t},this.getFreshValueHex=function(){return this.hV},void 0!==t&&(void 0!==t.bigint?this.setByBigInteger(t.bigint):void 0!==t.int?this.setByInteger(t.int):"number"==typeof t?this.setByInteger(t):void 0!==t.hex&&this.setValueHex(t.hex))},it.lang.extend(rt.asn1.DERInteger,rt.asn1.ASN1Object),rt.asn1.DERBitString=function(t){if(void 0!==t&&void 0!==t.obj){var e=rt.asn1.ASN1Util.newObject(t.obj);t.hex="00"+e.getEncodedHex()}rt.asn1.DERBitString.superclass.constructor.call(this),this.hT="03",this.setHexValueIncludingUnusedBits=function(t){this.hTLV=null,this.isModified=!0,this.hV=t},this.setUnusedBitsAndHexValue=function(t,e){if(t<0||7=2?(n[n.length]=s,s=0,o=0):s<<=4}}if(o)throw new Error("Hex encoding incomplete: 4 bits missing");return n}(t):v.unarmor(t),n=x.decode(r);if(3===n.sub.length&&(n=n.sub[2].sub[0]),9===n.sub.length){e=n.sub[1].getHexStringValue(),this.n=L(e,16),i=n.sub[2].getHexStringValue(),this.e=parseInt(i,16);var s=n.sub[3].getHexStringValue();this.d=L(s,16);var o=n.sub[4].getHexStringValue();this.p=L(o,16);var h=n.sub[5].getHexStringValue();this.q=L(h,16);var a=n.sub[6].getHexStringValue();this.dmp1=L(a,16);var u=n.sub[7].getHexStringValue();this.dmq1=L(u,16);var f=n.sub[8].getHexStringValue();this.coeff=L(f,16)}else{if(2!==n.sub.length)return!1;if(n.sub[0].sub){var l=n.sub[1].sub[0];e=l.sub[0].getHexStringValue(),this.n=L(e,16),i=l.sub[1].getHexStringValue(),this.e=parseInt(i,16)}else e=n.sub[0].getHexStringValue(),this.n=L(e,16),i=n.sub[1].getHexStringValue(),this.e=parseInt(i,16)}return!0}catch(t){return!1}},e.prototype.getPrivateBaseKey=function(){var t={array:[new rt.asn1.DERInteger({int:0}),new rt.asn1.DERInteger({bigint:this.n}),new rt.asn1.DERInteger({int:this.e}),new rt.asn1.DERInteger({bigint:this.d}),new rt.asn1.DERInteger({bigint:this.p}),new rt.asn1.DERInteger({bigint:this.q}),new rt.asn1.DERInteger({bigint:this.dmp1}),new rt.asn1.DERInteger({bigint:this.dmq1}),new rt.asn1.DERInteger({bigint:this.coeff})]};return new rt.asn1.DERSequence(t).getEncodedHex()},e.prototype.getPrivateBaseKeyB64=function(){return p(this.getPrivateBaseKey())},e.prototype.getPublicBaseKey=function(){var t=new rt.asn1.DERSequence({array:[new rt.asn1.DERObjectIdentifier({oid:"1.2.840.113549.1.1.1"}),new rt.asn1.DERNull]}),e=new rt.asn1.DERSequence({array:[new rt.asn1.DERInteger({bigint:this.n}),new rt.asn1.DERInteger({int:this.e})]}),i=new rt.asn1.DERBitString({hex:"00"+e.getEncodedHex()});return new rt.asn1.DERSequence({array:[t,i]}).getEncodedHex()},e.prototype.getPublicBaseKeyB64=function(){return p(this.getPublicBaseKey())},e.wordwrap=function(t,e){if(!t)return t;var i="(.{1,"+(e=e||64)+"})( +|$\n?)|(.{1,"+e+"})";return t.match(RegExp(i,"g")).join("\n")},e.prototype.getPrivateKey=function(){var t="-----BEGIN RSA PRIVATE KEY-----\n";return(t+=e.wordwrap(this.getPrivateBaseKeyB64())+"\n")+"-----END RSA PRIVATE KEY-----"},e.prototype.getPublicKey=function(){var t="-----BEGIN PUBLIC KEY-----\n";return(t+=e.wordwrap(this.getPublicBaseKeyB64())+"\n")+"-----END PUBLIC KEY-----"},e.hasPublicKeyProperty=function(t){return(t=t||{}).hasOwnProperty("n")&&t.hasOwnProperty("e")},e.hasPrivateKeyProperty=function(t){return(t=t||{}).hasOwnProperty("n")&&t.hasOwnProperty("e")&&t.hasOwnProperty("d")&&t.hasOwnProperty("p")&&t.hasOwnProperty("q")&&t.hasOwnProperty("dmp1")&&t.hasOwnProperty("dmq1")&&t.hasOwnProperty("coeff")},e.prototype.parsePropertiesFrom=function(t){this.n=t.n,this.e=t.e,t.hasOwnProperty("d")&&(this.d=t.d,this.p=t.p,this.q=t.q,this.dmp1=t.dmp1,this.dmq1=t.dmq1,this.coeff=t.coeff)},e}(tt),at=i(155),ut=void 0!==at?null===(st=at.env)||void 0===st?void 0:"3.3.2":void 0;const ct=function(){function t(t){void 0===t&&(t={}),t=t||{},this.default_key_size=t.default_key_size?parseInt(t.default_key_size,10):1024,this.default_public_exponent=t.default_public_exponent||"010001",this.log=t.log||!1,this.key=null}return t.prototype.setKey=function(t){this.log&&this.key&&console.warn("A key was already set, overriding existing."),this.key=new ht(t)},t.prototype.setPrivateKey=function(t){this.setKey(t)},t.prototype.setPublicKey=function(t){this.setKey(t)},t.prototype.decrypt=function(t){try{return this.getKey().decrypt(g(t))}catch(t){return!1}},t.prototype.encrypt=function(t){try{return p(this.getKey().encrypt(t))}catch(t){return!1}},t.prototype.sign=function(t,e,i){try{return p(this.getKey().sign(t,e,i))}catch(t){return!1}},t.prototype.verify=function(t,e,i){try{return this.getKey().verify(t,g(e),i)}catch(t){return!1}},t.prototype.getKey=function(t){if(!this.key){if(this.key=new ht,t&&"[object Function]"==={}.toString.call(t))return void this.key.generateAsync(this.default_key_size,this.default_public_exponent,t);this.key.generate(this.default_key_size,this.default_public_exponent)}return this.key},t.prototype.getPrivateKey=function(){return this.getKey().getPrivateKey()},t.prototype.getPrivateKeyB64=function(){return this.getKey().getPrivateBaseKeyB64()},t.prototype.getPublicKey=function(){return this.getKey().getPublicKey()},t.prototype.getPublicKeyB64=function(){return this.getKey().getPublicBaseKeyB64()},t.version=ut,t}()})(),r.default})())); + + +var PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuN0b3wpJeNnyvGEFCQky3u0nGh/jkwXsVk8IlNRlsiC2ITcBrobrJifTII+/sL8bwfKfWU+h2AgX8HUZaZAJl2488hs2ScfJf56cKZsBjmTfCzUVEhg5jrTlxE/LB3kBtY+OgVfU4IZ/tlS/AKU+HY/hYrSq6O/3Dah825eJ6ooRIP0d0yssdl6NMp/8g1JnhWPUG+BViBWsI38GftPbaEFqUOi9ZppDWIjeHaCzDKIabOu1Kr6vxiLmmTYFdB2mQNEMi9nOkvDShmz36lMkuZA70NBMlEjO6Gn9hsrWkbIychqTqfei8dl15UMDdKeJZ3ux40r47zfjPCf5ix2edQIDAQAB"; +var PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC43RvfCkl42fK8YQUJCTLe7ScaH+OTBexWTwiU1GWyILYhNwGuhusmJ9Mgj7+wvxvB8p9ZT6HYCBfwdRlpkAmXbjzyGzZJx8l/npwpmwGOZN8LNRUSGDmOtOXET8sHeQG1j46BV9Tghn+2VL8ApT4dj+FitKro7/cNqHzbl4nqihEg/R3TKyx2Xo0yn/yDUmeFY9Qb4FWIFawjfwZ+09toQWpQ6L1mmkNYiN4doLMMohps67Uqvq/GIuaZNgV0HaZA0QyL2c6S8NKGbPfqUyS5kDvQ0EyUSM7oaf2GytaRsjJyGpOp96Lx2XXlQwN0p4lne7HjSvjvN+M8J/mLHZ51AgMBAAECggEAbh0eZeudugOwh68OrcQx7gG7Ad+u0bt8fCiVhvlBHipH8l7ufIPW+6JLKyEU4HXlVdBsRGmfkKu5frxxh6SJYg8C9H9rBeWgS4kxocK32ZaSGP3kcCPH3Q45soaI/AmDEB/TlY24uojC99tg7kR/TGKQsRfGmfud4B/VR4PrXa0egek75qtzZWA2E7bJjwbTQ7BGacz/JsbcbXWfWKYLIHsl0IGzyrqPRaX2iE6qBWDnWZO7Fot9f72fPzo1tiYwDG5tEF61gchNQvQswqVgKRW7u5/o1C11p+WUt5ImDiW/TScAYvQGZA1eHD9Ex3f+0Lb/eJPEvmOXHys+46dDfQKBgQDjGQ/QU5z5uJSmcroO7NZMoYF8pp737Clc90B74a7gDdvYC/TqEqaRji13m1v7VNwh6Q578KXfFYKoQviSXL93aoc09lPnfPZAZ9CORGAQBjYfXgx6KOiQ+GcQy7r/MF7j67OAPJ4jj/FzdSRw3+zeUZzDdf3VoaU8BjBdfSRl+wKBgQDQZApoZ+fKotn6czEG8sjRNYGthEAiElGo9GWlupmTbUt2Zo7l0ywqFjyaenGO68cew5mD/4L3orxOBIunF8nL5pufSTeQI2QS3LpHdpMTIwUxvvaaa86PSSUD31qkmb6BZtZrKlNKpLnjCpZ7tyIfok1xjErT0go04DAPN9uSTwKBgAFwJDB+hwzxxUc0jMcRat37W9WNPI53WV+0VR0ztabHj6/Ti4575cAgNVt/iVqTE/3G+wd/450BBt3H5skOe0vnScnlEWzy1qBbx+9OsYkIcQlL0Cpp3eclG4n4sEtzY/ZvhKh4Ocwh2jaP9FYepOJXg/Wc5qmWp3Q02dONulBHAoGBAJbY0+/fxxoX6FIzMDonZNaMNOK16PbA6/uxbiMZgDIH26hJdQdIZZ/RmOz51VnvsqPCU04Jl3RKiKSxBaZeweSned9D0MS12asNvIoeezhPEWOBKGF/yHZQLEsxUxvzbsOc/Xl1mfVeaHDBKU1Es57Sjdy0ATZzxI+h+SgK9xZhAoGAECzncIpn4I0IyJ16ArMNGqC/VlF73auGB2gPtI7G+v1aROtm6n8xKoJQmDMAM0tyRLUP//TSK8NgNw4ACUy3QhwI6R+cnVziv6v9ozVvyaPrBChDshtzCblRSFhKqq+f0tEYVns5VwlM5jp8uFhIKxxjo4ufCdd5v9Ot868ArIY="; // 后端存储的私钥Base64字符串 + +var encryptInstance = null; // 加密实例缓存 +var decryptInstance = null; // 加密实例缓存 +function encryptRsa(word){ + var encrypt = initEncrypt(PUBLIC_KEY); + var maxLength = 245; // RSA 2048位 最大明文长度(需与后端一致) + var result = ''; + for (var i = 0; i < word.length; i += maxLength) { + var chunk = word.slice(i, i + maxLength); + var encryptedChunk = encrypt.encrypt(chunk); + if (!encryptedChunk) { + throw new Error('RSA 加密失败'); + } + result += encryptedChunk; + } + return result; +} + + +function decryptRsa(word) { + if (!word) return ""; + + const rawWord = decodeURIComponent(word).replace(/ /g, '+'); + const chunks = rawWord.split(','); + + + var decrypt = initDecrypt(PRIVATE_KEY); + let decryptedResult = ''; + + for (let i = 0; i < chunks.length; i++) { + const chunk = chunks[i].trim(); + if (!chunk) continue; + + const decryptedChunk = decrypt.decrypt(chunk); + if (!decryptedChunk) { + throw new Error(`第${i+1}段解密失败`); + } + decryptedResult += decryptedChunk; + } + return decryptedResult; +}; + +// 初始化 RSA 加密实例(加载公钥) +function initEncrypt(publicKey) { + if (!encryptInstance) { + encryptInstance = new JSEncrypt(); + encryptInstance.setPublicKey(publicKey); // 设置后端提供的公钥(Base64 编码) + } + return encryptInstance; +} + +// 初始化 RSA 加密实例(加载公钥) +function initDecrypt(privateKey) { + if (!decryptInstance) { + decryptInstance = new JSEncrypt(); + // 设置私钥 + const pemPrivateKey = `-----BEGIN PRIVATE KEY----- +${privateKey} +-----END PRIVATE KEY-----`; + decryptInstance.setPrivateKey(pemPrivateKey); + } + return decryptInstance; + +} + + diff --git a/modules/bmw/src/main/resources/static/js/main.js b/modules/bmw/src/main/resources/static/js/main.js index 029b503..7930696 100644 --- a/modules/bmw/src/main/resources/static/js/main.js +++ b/modules/bmw/src/main/resources/static/js/main.js @@ -137,7 +137,7 @@ function logout() { //清除系统首页缓存 localStorage.removeItem('subComIds'); localStorage.removeItem('subComNamePlan'); - + localStorage.clear(); $.ajax({ type: 'delete', url: DATA_URL + '/auth/logout', @@ -292,4 +292,4 @@ function onclickIndex(lay_id){ layui.use(['layer'], function () { layer = layui.layer; -}); \ No newline at end of file +}); diff --git a/modules/bmw/src/main/resources/static/login.html b/modules/bmw/src/main/resources/static/login.html index b06ce90..3ae7548 100644 --- a/modules/bmw/src/main/resources/static/login.html +++ b/modules/bmw/src/main/resources/static/login.html @@ -40,7 +40,7 @@ - + - \ No newline at end of file + diff --git a/modules/system/src/main/resources/mapper/logs/SysOperLogMapper.xml b/modules/system/src/main/resources/mapper/logs/SysOperLogMapper.xml index 375b3d2..c85e995 100644 --- a/modules/system/src/main/resources/mapper/logs/SysOperLogMapper.xml +++ b/modules/system/src/main/resources/mapper/logs/SysOperLogMapper.xml @@ -111,6 +111,8 @@ "oper_id" AS operId, "title", "json_result" as jsonResult, + "oper_ip" as operIp, + "status" as status, CASE "business_type" WHEN 1 THEN '查询' @@ -131,6 +133,12 @@ WHEN 2 THEN 'APP' ELSE '其他' END AS operatoType , + CASE + "status" + WHEN 0 THEN '请求异常' + WHEN 1 THEN '请求成功' + ELSE '其他' + END AS statusRes , "create_time" AS opersTime FROM "ynrealname"."sys_oper_log" @@ -157,4 +165,4 @@ truncate table "ynrealname"."sys_oper_log" - \ No newline at end of file +