作者 shenhailong

优化代理人登录密码验证

... ... @@ -543,8 +543,8 @@
<version>3.1</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
... ...
package com.agent.controller.system.KIAM;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;
/**
* sm3生成密码摘要
* 需要依赖 Bouncy Castle轻量级密码术包 1.60
*/
public class SM3EncryptUtil {
private static byte[] SECRET_KEY = {101, 87, 99, 10, 34, 45, 77, 76, 98, 13, 12, 18, 73, 84, 91, 93};
public static byte[] hash(byte[] srcData) {
SM3Digest digest = new SM3Digest();
digest.update(srcData, 0, srcData.length);
byte[] hash = new byte[digest.getDigestSize()];
digest.doFinal(hash, 0);
return hash;
}
public static String bytetoString(byte[] digest) {
String str = "";
String tempStr = "";
for (int i = 0; i < digest.length; i++) {
tempStr = (Integer.toHexString(digest[i] & 0xff));
if (tempStr.length() == 1) {
str = str + "0" + tempStr;
} else {
str = str + tempStr;
}
}
return str.toLowerCase();
}
public static void main(String[] args) {
Security.addProvider(new BouncyCastleProvider());
try {
String pwdDigest = passwordSm3("N8HK@CGO.air2018");
System.out.println(pwdDigest);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 密码SM3加密
* @param password
* @return
*/
public static String passwordSm3(String password){
Security.addProvider(new BouncyCastleProvider());
try {
byte[] pwdBytes = password.getBytes("UTF-8");
byte[] pwdDigest = hash(pwdBytes);
return bytetoString(pwdDigest);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
... ...
package com.agent.controller.system.KIAM;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
import java.util.Base64;
/**
* sm4加密工具
* 需要依赖 Bouncy Castle轻量级密码术包 1.60
*/
public class SM4EncryptUtil {
/**
* 密钥, 禁止修改
*/
private static byte[] SECRET_KEY = {101, 87, 99, 10, 34, 45, 77, 76, 98, 13, 12, 18, 73, 84, 91, 93};
/**
* 解密方法
*/
public static byte[] decryptSM4( byte[] cipherText)
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
return decryptSM4(SECRET_KEY, cipherText);
}
public static byte[] decryptSM4(byte[] key, byte[] cipherText)
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
Cipher cipher = generateEcbCipher("SM4/ECB/PKCS5Padding", Cipher.DECRYPT_MODE, key);
return cipher.doFinal(cipherText);
}
/**
* 解密方法
*/
public static byte[] encryptSM4( byte[] cipherText)
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
return encryptSM4(SECRET_KEY, cipherText);
}
public static byte[] encryptSM4(byte[] key, byte[] data)
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = generateEcbCipher("SM4/ECB/PKCS5Padding", Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
}
private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key)
throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
InvalidKeyException {
Cipher cipher = Cipher.getInstance(algorithmName, "BC");
Key sm4Key = new SecretKeySpec(key, "SM4");
cipher.init(mode, sm4Key);
return cipher;
}
public static void main(String[] args) {
Security.addProvider(new BouncyCastleProvider());
try {
// ResultPwd resultPwd = new ResultPwd();
// resultPwd.setResult("123456");
// String pwd = "vmvnv1v2VV.";
SM4EncryptUtil sm4EncryptUtil = new SM4EncryptUtil();
String pwd = sm4EncryptUtil.pwd("123456");
String encryptPwd = new String(Base64.getEncoder().encode(encryptSM4(pwd.getBytes("UTF-8"))));
System.out.println("加密密码: " +encryptPwd);
String originPwd = new String(decryptSM4(Base64.getDecoder().decode(encryptPwd)));
System.out.println("解密密码: "+ originPwd);
} catch (Exception e) {
e.printStackTrace();
}
}
public String pwd(String pwd){
try {
String encryptPwd = new String(Base64.getEncoder().encode(encryptSM4(pwd.getBytes("UTF-8"))));
return encryptPwd;
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
}
... ...
package com.agent.controller.system.KIAM;
import com.google.gson.Gson;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
/**
* @author shenhailong
* <p>
* 2020/12/14/16:24
*/
public class SignatureDemo {
private static final Logger logger = LoggerFactory.getLogger(SignatureDemo.class);
// 接口服务地址

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

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

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

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

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

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

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

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

try {
// 签名数据

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

httpGet.addHeader("appKey", appKey);
httpGet.addHeader("ts", ts.toString());
httpGet.addHeader("once", once);
System.out.println("once:" + once);
httpGet.addHeader("signData", signData);
System.out.println("headers:" + httpGet.getAllHeaders());
String urlStr = httpGet.getURI().toString();
// 公共参数URL

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

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

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

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

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

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

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

try {
// 签名数据

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

httpPut.addHeader("appKey", appKey);
httpPut.addHeader("ts", ts.toString());
httpPut.addHeader("once", once);
System.out.println("once:" + once);
httpPut.addHeader("signData", signData);
System.out.println("headers:" + httpPut.getAllHeaders());
String urlStr = httpPut.getURI().toString();
// 公共参数URL

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

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

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

if (statusCode == HttpStatus.SC_OK) {
String resp = EntityUtils.toString(response.getEntity(), "utf-8");
System.out.println("status:" + statusCode);
System.out.println("result:" + resp);
}
} catch (URISyntaxException e) {
logger.error("签名失败:", e);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
... ...
package com.agent.controller.system.KIAM;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
/**
* @author shenhailong
* <p>
* 2020/12/14/16:44
*/
public class TokenUtils {
private static final Logger logger = LoggerFactory.getLogger(TokenUtils.class);
private static String[] hexDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e","f" };
public static String getSignature(String appPwd, String paramUrl) {
if (StringUtils.isNotBlank(paramUrl)) {
try {
paramUrl = URLDecoder.decode(paramUrl, "UTF-8");
} catch (UnsupportedEncodingException e) {
logger.error("生成signData失败:", e);
throw new RuntimeException("生成signData失败:", e);
}
}
String[] paraArray = new String[] {};
if (StringUtils.isNotBlank(paramUrl)) {
String[] queryArray = paramUrl.split("&");
paraArray = (String[]) ArrayUtils.addAll(queryArray, paraArray);
} Arrays.sort(paraArray);
StringBuffer buffer = new StringBuffer();
buffer.append(appPwd);
buffer.append(":");
for (int i = 0; i < paraArray.length; i++) {
buffer.append(paraArray[i]);
buffer.append("&");
}
buffer.deleteCharAt(buffer.length() - 1);
buffer.append(":");
buffer.append(appPwd);
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SM3");
md.update(buffer.toString().getBytes("UTF-8"));
} catch (NoSuchAlgorithmException e) {
logger.error("生成signData失败:", e);
throw new RuntimeException("生成signData失败.", e);
} catch (UnsupportedEncodingException e) {
logger.error("生成signData失败:", e);
throw new RuntimeException("生成signData失败.", e);
} String encode = byteArrayToHexString(md.digest());
return encode;
}
private static String byteArrayToHexString(byte[] byteArray) {
StringBuffer sb = new StringBuffer();
for (byte byt : byteArray) {
sb.append(byteToHexString(byt));
} return sb.toString();
}
private static String byteToHexString(byte byt) {
int n = byt;
if (n < 0) {
n = 256 + n;
}
return hexDigits[n / 16] + hexDigits[n % 16];
}
}
... ...
... ... @@ -12,6 +12,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import com.agent.controller.system.KIAM.SM3EncryptUtil;
import com.agent.entity.system.FunctionEntity;
import com.agent.vo.MenuVo;
import com.framework.util.PropertiesLoader;
... ... @@ -243,11 +244,11 @@ public class LoginController {
Subject subject = SecurityUtils.getSubject();
subject.getSession().setAttribute("user", user);
UsernamePasswordToken token = null;
if ("".equals(userEntity.getUamId())){
if (!StringUtils.isBlank(userEntity.getUamId())){
// 登录用户
token = new UsernamePasswordToken(loginAccount, MD5Tools.MD5(password));
token = new UsernamePasswordToken(loginAccount, SM3EncryptUtil.passwordSm3(password));
}else {
token = new UsernamePasswordToken(loginAccount, userEntity.getPassword());
token = new UsernamePasswordToken(loginAccount, MD5Tools.MD5(password));
}
// System.out.println(loginAccount+" " + password);
try {
... ...