作者 shenhailong

优化代理人登录密码验证

@@ -543,8 +543,8 @@ @@ -543,8 +543,8 @@
543 <version>3.1</version> 543 <version>3.1</version>
544 <configuration> 544 <configuration>
545 <encoding>${project.build.sourceEncoding}</encoding> 545 <encoding>${project.build.sourceEncoding}</encoding>
546 - <source>${jdk.version}</source>  
547 - <target>${jdk.version}</target> 546 + <source>8</source>
  547 + <target>8</target>
548 </configuration> 548 </configuration>
549 </plugin> 549 </plugin>
550 550
  1 +package com.agent.controller.system.KIAM;
  2 +
  3 +import org.bouncycastle.crypto.digests.SM3Digest;
  4 +import org.bouncycastle.jce.provider.BouncyCastleProvider;
  5 +
  6 +import java.security.Security;
  7 +
  8 +/**
  9 + * sm3生成密码摘要
  10 + * 需要依赖 Bouncy Castle轻量级密码术包 1.60
  11 + */
  12 +public class SM3EncryptUtil {
  13 +
  14 + private static byte[] SECRET_KEY = {101, 87, 99, 10, 34, 45, 77, 76, 98, 13, 12, 18, 73, 84, 91, 93};
  15 +
  16 + public static byte[] hash(byte[] srcData) {
  17 + SM3Digest digest = new SM3Digest();
  18 + digest.update(srcData, 0, srcData.length);
  19 + byte[] hash = new byte[digest.getDigestSize()];
  20 + digest.doFinal(hash, 0);
  21 + return hash;
  22 + }
  23 +
  24 + public static String bytetoString(byte[] digest) {
  25 + String str = "";
  26 + String tempStr = "";
  27 + for (int i = 0; i < digest.length; i++) {
  28 + tempStr = (Integer.toHexString(digest[i] & 0xff));
  29 + if (tempStr.length() == 1) {
  30 + str = str + "0" + tempStr;
  31 + } else {
  32 + str = str + tempStr;
  33 + }
  34 + }
  35 + return str.toLowerCase();
  36 + }
  37 +
  38 + public static void main(String[] args) {
  39 + Security.addProvider(new BouncyCastleProvider());
  40 + try {
  41 + String pwdDigest = passwordSm3("N8HK@CGO.air2018");
  42 + System.out.println(pwdDigest);
  43 + } catch (Exception e) {
  44 + e.printStackTrace();
  45 + }
  46 + }
  47 +
  48 + /**
  49 + * 密码SM3加密
  50 + * @param password
  51 + * @return
  52 + */
  53 + public static String passwordSm3(String password){
  54 + Security.addProvider(new BouncyCastleProvider());
  55 + try {
  56 + byte[] pwdBytes = password.getBytes("UTF-8");
  57 + byte[] pwdDigest = hash(pwdBytes);
  58 + return bytetoString(pwdDigest);
  59 + } catch (Exception e) {
  60 + e.printStackTrace();
  61 + return null;
  62 + }
  63 + }
  64 +
  65 +}
  1 +package com.agent.controller.system.KIAM;
  2 +
  3 +
  4 +import org.bouncycastle.jce.provider.BouncyCastleProvider;
  5 +
  6 +import javax.crypto.BadPaddingException;
  7 +import javax.crypto.Cipher;
  8 +import javax.crypto.IllegalBlockSizeException;
  9 +import javax.crypto.NoSuchPaddingException;
  10 +import javax.crypto.spec.SecretKeySpec;
  11 +import java.security.*;
  12 +import java.util.Base64;
  13 +
  14 +/**
  15 + * sm4加密工具
  16 + * 需要依赖 Bouncy Castle轻量级密码术包 1.60
  17 + */
  18 +public class SM4EncryptUtil {
  19 +
  20 + /**
  21 + * 密钥, 禁止修改
  22 + */
  23 + private static byte[] SECRET_KEY = {101, 87, 99, 10, 34, 45, 77, 76, 98, 13, 12, 18, 73, 84, 91, 93};
  24 +
  25 + /**
  26 + * 解密方法
  27 + */
  28 + public static byte[] decryptSM4( byte[] cipherText)
  29 + throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
  30 + NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
  31 + return decryptSM4(SECRET_KEY, cipherText);
  32 + }
  33 +
  34 + public static byte[] decryptSM4(byte[] key, byte[] cipherText)
  35 + throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
  36 + NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
  37 + Cipher cipher = generateEcbCipher("SM4/ECB/PKCS5Padding", Cipher.DECRYPT_MODE, key);
  38 + return cipher.doFinal(cipherText);
  39 + }
  40 +
  41 + /**
  42 + * 解密方法
  43 + */
  44 + public static byte[] encryptSM4( byte[] cipherText)
  45 + throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
  46 + NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
  47 + return encryptSM4(SECRET_KEY, cipherText);
  48 + }
  49 +
  50 + public static byte[] encryptSM4(byte[] key, byte[] data)
  51 + throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
  52 + NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
  53 + Cipher cipher = generateEcbCipher("SM4/ECB/PKCS5Padding", Cipher.ENCRYPT_MODE, key);
  54 + return cipher.doFinal(data);
  55 + }
  56 +
  57 + private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key)
  58 + throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
  59 + InvalidKeyException {
  60 + Cipher cipher = Cipher.getInstance(algorithmName, "BC");
  61 + Key sm4Key = new SecretKeySpec(key, "SM4");
  62 + cipher.init(mode, sm4Key);
  63 + return cipher;
  64 + }
  65 +
  66 + public static void main(String[] args) {
  67 + Security.addProvider(new BouncyCastleProvider());
  68 + try {
  69 +// ResultPwd resultPwd = new ResultPwd();
  70 +// resultPwd.setResult("123456");
  71 +// String pwd = "vmvnv1v2VV.";
  72 + SM4EncryptUtil sm4EncryptUtil = new SM4EncryptUtil();
  73 + String pwd = sm4EncryptUtil.pwd("123456");
  74 + String encryptPwd = new String(Base64.getEncoder().encode(encryptSM4(pwd.getBytes("UTF-8"))));
  75 + System.out.println("加密密码: " +encryptPwd);
  76 + String originPwd = new String(decryptSM4(Base64.getDecoder().decode(encryptPwd)));
  77 + System.out.println("解密密码: "+ originPwd);
  78 + } catch (Exception e) {
  79 + e.printStackTrace();
  80 + }
  81 + }
  82 +
  83 + public String pwd(String pwd){
  84 + try {
  85 + String encryptPwd = new String(Base64.getEncoder().encode(encryptSM4(pwd.getBytes("UTF-8"))));
  86 + return encryptPwd;
  87 + } catch (Exception e) {
  88 + e.printStackTrace();
  89 + return "";
  90 + }
  91 + }
  92 +
  93 +}
  1 +package com.agent.controller.system.KIAM;
  2 +
  3 +import com.google.gson.Gson;
  4 +import org.apache.commons.lang3.RandomStringUtils;
  5 +import org.apache.commons.lang3.StringUtils;
  6 +import org.apache.http.HttpStatus;
  7 +import org.apache.http.client.ClientProtocolException;
  8 +import org.apache.http.client.config.RequestConfig;
  9 +import org.apache.http.client.methods.CloseableHttpResponse;
  10 +import org.apache.http.client.methods.HttpGet;
  11 +import org.apache.http.client.methods.HttpPut;
  12 +import org.apache.http.entity.StringEntity;
  13 +import org.apache.http.impl.client.CloseableHttpClient;
  14 +import org.apache.http.impl.client.HttpClients;
  15 +import org.apache.http.util.EntityUtils;
  16 +import org.slf4j.Logger;
  17 +import org.slf4j.LoggerFactory;
  18 +
  19 +import java.io.IOException;
  20 +import java.net.URI;
  21 +import java.net.URISyntaxException;
  22 +import java.util.Calendar;
  23 +import java.util.HashMap;
  24 +import java.util.Map;
  25 +
  26 +/**
  27 + * @author shenhailong
  28 + * <p>
  29 + * 2020/12/14/16:24
  30 + */
  31 +public class SignatureDemo {
  32 +
  33 +
  34 +
  35 + private static final Logger logger = LoggerFactory.getLogger(SignatureDemo.class);
  36 + // 接口服务地址

  37 + static String restSever = "http://10.5.14.103:28087/upm/service/V1/auth/userApp";
  38 + //应用标识

  39 + static String appKey = "8744334580944896";
  40 + // 身份系统签发给应用对接的密钥

  41 + static String appPwd = "c6dddfab2b59d87f98c703d924f3718bb4350f17";
  42 + public static void doMain() {
  43 + // 时间戳

  44 + Long ts = Calendar.getInstance().getTime().getTime();
  45 + // 随机数

  46 + String once = RandomStringUtils.randomAlphanumeric(32);
  47 + // 接口header中的公共参数

  48 + String commonParamUrl = String.format("appKey=%s" + "&" + "ts=%s" + "&" + "once=%s", appKey, ts, once);
  49 + // 创建HttpClient对象

  50 + CloseableHttpClient httpclient = HttpClients.createDefault();
  51 + /**
  52 + * GET查询接口演示代码
  53 + */
  54 + String getQueryParam = "startTime=2019-06-21T08:00:00.000Z";
  55 + String getFullUrl = restSever + "?" + getQueryParam;
  56 + HttpGet httpGet = new HttpGet(getFullUrl);
  57 + // get请求查询参数,用在URL上的,这里若是通过ID查询的,接口中ID是作为路径存在的,所以需要将ID组合成

  58 + String getAllParamUrl = commonParamUrl + "&" + getQueryParam;
  59 + // 对参数签名,并放入请求header中的signData参数中

  60 + try {
  61 + // 签名数据

  62 + String signData = TokenUtils.getSignature(appPwd, getAllParamUrl);
  63 + //添加header参数 appCode、timestamp、 signatureNonce、signature

  64 + httpGet.addHeader("appKey", appKey);
  65 + httpGet.addHeader("ts", ts.toString());
  66 + httpGet.addHeader("once", once);
  67 + System.out.println("once:" + once);
  68 + httpGet.addHeader("signData", signData);
  69 + System.out.println("headers:" + httpGet.getAllHeaders());
  70 + String urlStr = httpGet.getURI().toString();
  71 + // 公共参数URL

  72 + System.out.println("commonParamter:" + urlStr);
  73 + if (StringUtils.endsWith(urlStr, "/")) {
  74 + urlStr = StringUtils.removeEnd(urlStr, "/");
  75 + }
  76 + httpGet.setURI(new URI(urlStr));
  77 + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(3000).setConnectionRequestTimeout(3000).setSocketTimeout(3000).build();
  78 + httpGet.setConfig(requestConfig);
  79 + System.out.println("urlStr in request:" + httpGet.getURI().toString());
  80 + // 执行请求

  81 + CloseableHttpResponse response = httpclient.execute(httpGet);
  82 + // 取响应的结果

  83 + int statusCode = response.getStatusLine().getStatusCode();
  84 + // 打印响应结果

  85 + if (statusCode == HttpStatus.SC_OK) {
  86 + String resp = EntityUtils.toString(response.getEntity(), "utf-8");
  87 + System.out.println("status:" + statusCode);
  88 + System.out.println("result:" + resp);
  89 + }
  90 + } catch (URISyntaxException e) {
  91 + logger.error("签名失败:", e);
  92 + } catch (ClientProtocolException e) {
  93 + e.printStackTrace();
  94 + } catch (IOException e) {
  95 + e.printStackTrace();
  96 + }
  97 + /**
 * PUT修改接口的演示代码,POST与PUT类似
 */
  98 + String ID = "aa03a5c692cf480b87887e0ff8cfe566";
  99 + // 这里若是通过ID查询的,接口中ID是作为路径存在的,所以需要将ID组合成

  100 + String putQueryParam = "ID=" + ID;
  101 + String putFullUrl = restSever + "/" + ID;
  102 + // 访问用户接口

  103 + HttpPut httpPut = new HttpPut(putFullUrl);
  104 + // 模拟POST/PUT的body中数据,需转为JSON进行签名。GET则没有这部分内容。

  105 + Map<String, Object> dataMap = new HashMap<String, Object>();
  106 + dataMap.put("USER_NAME", "张三");
  107 + String bodyParam = new Gson().toJson(dataMap);
  108 + String postAllParamUrl = commonParamUrl + "&" + putQueryParam + "&bodyData=" + bodyParam;
  109 + StringEntity bodyData = new StringEntity(bodyParam.toString(), "UTF-8");
  110 + httpPut.setEntity(bodyData);
  111 + // 对参数签名,并放入请求header中的signData参数中

  112 + try {
  113 + // 签名数据

  114 + String signData = TokenUtils.getSignature(appPwd, postAllParamUrl);
  115 + // 添加header参数 appCode、timestamp、 signatureNonce、signature

  116 + httpPut.addHeader("appKey", appKey);
  117 + httpPut.addHeader("ts", ts.toString());
  118 + httpPut.addHeader("once", once);
  119 + System.out.println("once:" + once);
  120 + httpPut.addHeader("signData", signData);
  121 + System.out.println("headers:" + httpPut.getAllHeaders());
  122 + String urlStr = httpPut.getURI().toString();
  123 + // 公共参数URL

  124 + System.out.println("commonParamter:" + urlStr);
  125 + if (StringUtils.endsWith(urlStr, "/")) {
  126 + urlStr = StringUtils.removeEnd(urlStr, "/");
  127 + }
  128 + httpPut.setURI(new URI(urlStr));
  129 + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(3000).setConnectionRequestTimeout(3000).setSocketTimeout(3000).build();
  130 + httpPut.setConfig(requestConfig);
  131 + System.out.println("urlStr in request:" + httpPut.getURI().toString());
  132 + // 执行请求

  133 + CloseableHttpResponse response = httpclient.execute(httpPut);
  134 + // 取响应的结果

  135 + int statusCode = response.getStatusLine().getStatusCode();
  136 + // 打印响应结果

  137 + if (statusCode == HttpStatus.SC_OK) {
  138 + String resp = EntityUtils.toString(response.getEntity(), "utf-8");
  139 + System.out.println("status:" + statusCode);
  140 + System.out.println("result:" + resp);
  141 + }
  142 + } catch (URISyntaxException e) {
  143 + logger.error("签名失败:", e);
  144 + } catch (ClientProtocolException e) {
  145 + e.printStackTrace();
  146 + } catch (IOException e) {
  147 + e.printStackTrace();
  148 + }
  149 + }
  150 +}
  1 +package com.agent.controller.system.KIAM;
  2 +
  3 +
  4 +import org.apache.commons.lang3.ArrayUtils;
  5 +import org.apache.commons.lang3.StringUtils;
  6 +import org.slf4j.Logger;
  7 +import org.slf4j.LoggerFactory;
  8 +
  9 +import java.io.UnsupportedEncodingException;
  10 +import java.net.URLDecoder;
  11 +import java.security.MessageDigest;
  12 +import java.security.NoSuchAlgorithmException;
  13 +import java.util.Arrays;
  14 +
  15 +/**
  16 + * @author shenhailong
  17 + * <p>
  18 + * 2020/12/14/16:44
  19 + */
  20 +public class TokenUtils {
  21 +
  22 + private static final Logger logger = LoggerFactory.getLogger(TokenUtils.class);
  23 + private static String[] hexDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e","f" };
  24 + public static String getSignature(String appPwd, String paramUrl) {
  25 + if (StringUtils.isNotBlank(paramUrl)) {
  26 + try {
  27 + paramUrl = URLDecoder.decode(paramUrl, "UTF-8");
  28 + } catch (UnsupportedEncodingException e) {
  29 + logger.error("生成signData失败:", e);
  30 + throw new RuntimeException("生成signData失败:", e);
  31 + }
  32 + }
  33 + String[] paraArray = new String[] {};
  34 + if (StringUtils.isNotBlank(paramUrl)) {
  35 + String[] queryArray = paramUrl.split("&");
  36 + paraArray = (String[]) ArrayUtils.addAll(queryArray, paraArray);
  37 + } Arrays.sort(paraArray);
  38 + StringBuffer buffer = new StringBuffer();
  39 + buffer.append(appPwd);
  40 + buffer.append(":");
  41 + for (int i = 0; i < paraArray.length; i++) {
  42 + buffer.append(paraArray[i]);
  43 + buffer.append("&");
  44 + }
  45 + buffer.deleteCharAt(buffer.length() - 1);
  46 + buffer.append(":");
  47 + buffer.append(appPwd);
  48 + MessageDigest md = null;
  49 + try {
  50 + md = MessageDigest.getInstance("SM3");
  51 + md.update(buffer.toString().getBytes("UTF-8"));
  52 + } catch (NoSuchAlgorithmException e) {
  53 + logger.error("生成signData失败:", e);
  54 + throw new RuntimeException("生成signData失败.", e);
  55 + } catch (UnsupportedEncodingException e) {
  56 + logger.error("生成signData失败:", e);
  57 + throw new RuntimeException("生成signData失败.", e);
  58 + } String encode = byteArrayToHexString(md.digest());
  59 + return encode;
  60 + }
  61 + private static String byteArrayToHexString(byte[] byteArray) {
  62 + StringBuffer sb = new StringBuffer();
  63 + for (byte byt : byteArray) {
  64 + sb.append(byteToHexString(byt));
  65 + } return sb.toString();
  66 + }
  67 + private static String byteToHexString(byte byt) {
  68 + int n = byt;
  69 + if (n < 0) {
  70 + n = 256 + n;
  71 + }
  72 + return hexDigits[n / 16] + hexDigits[n % 16];
  73 + }
  74 +}
  75 +
@@ -12,6 +12,7 @@ import javax.servlet.http.HttpServletRequest; @@ -12,6 +12,7 @@ import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpSession; 12 import javax.servlet.http.HttpSession;
13 13
14 14
  15 +import com.agent.controller.system.KIAM.SM3EncryptUtil;
15 import com.agent.entity.system.FunctionEntity; 16 import com.agent.entity.system.FunctionEntity;
16 import com.agent.vo.MenuVo; 17 import com.agent.vo.MenuVo;
17 import com.framework.util.PropertiesLoader; 18 import com.framework.util.PropertiesLoader;
@@ -243,11 +244,11 @@ public class LoginController { @@ -243,11 +244,11 @@ public class LoginController {
243 Subject subject = SecurityUtils.getSubject(); 244 Subject subject = SecurityUtils.getSubject();
244 subject.getSession().setAttribute("user", user); 245 subject.getSession().setAttribute("user", user);
245 UsernamePasswordToken token = null; 246 UsernamePasswordToken token = null;
246 - if ("".equals(userEntity.getUamId())){ 247 + if (!StringUtils.isBlank(userEntity.getUamId())){
247 // 登录用户 248 // 登录用户
248 - token = new UsernamePasswordToken(loginAccount, MD5Tools.MD5(password)); 249 + token = new UsernamePasswordToken(loginAccount, SM3EncryptUtil.passwordSm3(password));
249 }else { 250 }else {
250 - token = new UsernamePasswordToken(loginAccount, userEntity.getPassword()); 251 + token = new UsernamePasswordToken(loginAccount, MD5Tools.MD5(password));
251 } 252 }
252 // System.out.println(loginAccount+" " + password); 253 // System.out.println(loginAccount+" " + password);
253 try { 254 try {