package com.hai.common.utils; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; import com.sun.jersey.api.client.WebResource.Builder; import com.sun.jersey.api.client.config.DefaultClientConfig; import com.sun.jersey.client.urlconnection.HTTPSProperties; import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import javax.net.ssl.*; import javax.ws.rs.core.MediaType; import java.security.*; import java.security.cert.CertificateException; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; public class UnionUtils { private static Client c = null; private static Client secureClient =null; private static Gson gson = new GsonBuilder().disableHtmlEscaping().create(); public static String DATE_FORMAT = "yyyy-MM-dd"; /** * 初始化设置 */ static{ initalizationJersyClient(); initalizationSecureJersyClient(); } /** * 设置调用参数 */ private static void initalizationJersyClient(){ try { c = Client.create(); c.setFollowRedirects(true); c.setConnectTimeout(10000); c.setReadTimeout(10000); } catch (Exception e) { e.printStackTrace(); } } private static void initalizationSecureJersyClient(){ try { SSLContext context = SSLContext.getInstance("SSL"); context.init(null, new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted( java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {} public void checkServerTrusted( java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {} } }, new SecureRandom()); HostnameVerifier hv = new HostnameVerifier(){ public boolean verify(String urlHostName, SSLSession session){ return true; } }; HTTPSProperties prop = new HTTPSProperties(hv, context); DefaultClientConfig dcc = new DefaultClientConfig(); dcc.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, prop); secureClient = Client.create(dcc); secureClient.setFollowRedirects(true); secureClient.setConnectTimeout(10000); secureClient.setReadTimeout(10000); } catch (Exception e) { e.printStackTrace(); } } /** * 调用接口 */ public static String sendPOSTRequest(String url, Object map, String contentTpye){ if(null==c){ initalizationJersyClient(); } Client client = null; if(url.indexOf("https://") == 0){ if(null==secureClient){ initalizationJersyClient(); } client = secureClient; }else{ if(null==c){ initalizationJersyClient(); } client = c; } WebResource resource = client.resource(url); String resultStr = null; try { Builder builder = resource.accept("*/*"); ClientResponse res = builder.type(contentTpye).entity(map).post(ClientResponse.class); if(res.getStatus() != 200){ throw new Exception("url:"+url+",response code:" + res.getStatus()); } resultStr = res.getEntity(String.class); return resultStr; } catch (Exception e) { e.printStackTrace(); return null; } } /** * 参数 转为json格式 * @param url 调用地址 * @param map 设置的参数 * @return */ public static String sendPostGson(String url, Map map){ String ps = gson.toJson(map); System.out.println("生成加密后的报文:"+ps); return sendPOSTRequest(url, ps, MediaType.APPLICATION_JSON); } /** * 使用公钥加密对称密钥 * @param publicKey 公钥 * @param symmetricKeyByte 对称密钥字节 * @return 加密后的对称密钥字节 * @throws Exception */ public static byte[] encrypt(String publicKey, byte[] symmetricKeyByte) throws Exception { byte[] encodedKey = Base64.decodeBase64(publicKey); KeySpec keySpec = new X509EncodedKeySpec(encodedKey); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey pk = keyFactory.generatePublic(keySpec); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, pk); byte[] result = cipher.doFinal(symmetricKeyByte); return result; } /** * 签名加密后的数据装载进map * @param key 对称秘钥 * @param params 待加密的字符串 * @param encryptKeys 加密字段 * @throws Exception */ public static void encryptedParamMap(String key, Map params, String ... encryptKeys) throws Exception{ if(encryptKeys != null && encryptKeys.length > 0){ for(String encryptKey : encryptKeys){ params.put(encryptKey, getEncryptedValue(params.get(encryptKey), key)); } } } /** * 3DES加密 * @param value 待加密的字符串 * @param key 加密密钥 * @return 加密后的字符串 * @throws Exception */ public static String getEncryptedValue(String value, String key) throws Exception { if (null == value || "".equals(value)) { return ""; } byte[] valueByte = value.getBytes(); byte[] sl = encrypt3DES(valueByte, hexToBytes(key)); String result = Base64.encodeBase64String(sl); // String result = BytesUtil.bytesToHex(sl); return result; } /** * 解密 * @param value 待解密的字符串 * @param key 解密秘钥 * @return 解密后字符串 * @throws Exception */ public static String getDecryptedValue(String value, String key) throws Exception { if (null == value || "".equals(value)) { return ""; } byte[] valueByte = Base64.decodeBase64(value); byte[] sl = decrypt3DES(valueByte, hexStr2Bytes(key)); String result = new String(sl); return result; } /** * 3DES解密 * @param input * @param key * @return * @throws Exception */ public static byte[] decrypt3DES(byte[] input, byte[] key) throws Exception { Cipher c = Cipher.getInstance("DESede/ECB/PKCS5Padding"); c.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "DESede")); return c.doFinal(input); } /** * bytes字符串转换为Byte值 * @param src String Byte字符串,每个Byte之间没有分隔符(字符范围:0-9 A-F) * @return byte[] */ public static byte[] hexStr2Bytes(String src){ /*对输入值进行规范化整理*/ src = src.trim().replace(" ", "").toUpperCase(Locale.US); //处理值初始化 int m=0,n=0; int iLen=src.length()/2; //计算长度 byte[] ret = new byte[iLen]; //分配存储空间 for (int i = 0; i < iLen; i++){ m=i*2+1; n=m+1; ret[i] = (byte)(Integer.decode("0x"+ src.substring(i*2, m) + src.substring(m,n)) & 0xFF); } return ret; } /** * 3DES加密 * @param input 待加密的字节 * @param key 密钥 * @return 加密后的字节 * @throws Exception */ private static byte[] encrypt3DES(byte[] input, byte[] key) throws Exception { Cipher c = Cipher.getInstance("DESede/ECB/PKCS5Padding"); c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "DESede")); return c.doFinal(input); } /** * 获取随机字符串 * @return 随机字符串 */ public static String createNonceStr(){ String sl = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; StringBuilder sb = new StringBuilder(); for(int i = 0 ; i < 16 ; i ++){ sb.append(sl.charAt(new Random().nextInt(sl.length()))); } return sb.toString(); } /** * h获取32位随机数字字符串 * @return */ public static String createNonceNumber(){ String sl = "0123456789"; StringBuilder sb = new StringBuilder(); for(int i = 0 ; i < 32 ; i ++){ sb.append(sl.charAt(new Random().nextInt(sl.length()))); } return sb.toString(); } /** * 获取当前日期时间 * * @return */ public static String getCurrentDateTime(String Dateformat) { String datestr = null; SimpleDateFormat df = new SimpleDateFormat(Dateformat); datestr = df.format(new Date()); return datestr; } /** * 在输入日期上增加(+)或减去(-)天数 * * @param date 输入日期 */ public static Date addDay(Date date, int iday) { Calendar cd = Calendar.getInstance(); cd.setTime(date); cd.add(Calendar.DAY_OF_MONTH, iday); return cd.getTime(); } /** * 将日期格式日期转换为字符串格式 自定義格式 * * @param date * @param dateformat * @return */ public static String dateToString(Date date, String dateformat) { String datestr = null; SimpleDateFormat df = new SimpleDateFormat(dateformat); datestr = df.format(date); return datestr; } /** * 将字符串日期转换为日期格式 * * @param datestr * @return */ public static Date stringToDate(String datestr) throws Exception{ if (datestr == null || datestr.equals("")) { return null; } Date date = new Date(); SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT); try { date = df.parse(datestr); } catch (ParseException e) { date = stringToDate(datestr, "yyyyMMdd"); } return date; } /** * 将字符串日期转换为日期格式 * 自定義格式 * * @param datestr * @return */ public static Date stringToDate(String datestr, String dateformat) throws Exception{ Date date = new Date(); SimpleDateFormat df = new SimpleDateFormat(dateformat); date = df.parse(datestr); return date; } /** * 签名 * @param param 待签名的参数 * @param signKey 签名密钥 * @return 签名结果字符串 * @throws Exception */ public static String sign(Map param, String signKey) throws Exception { String value = sortMap(param); byte[] keyBytes = Base64.decodeBase64(signKey); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyf = KeyFactory.getInstance("RSA"); PrivateKey priKey = keyf.generatePrivate(keySpec); Signature signature = Signature.getInstance("SHA256WithRSA"); signature.initSign(priKey); signature.update(value.getBytes()); byte[] signed = signature.sign(); String result = Base64.encodeBase64String(signed); return result; } /** * 排序 * @param param 待排序的参数 * @return 排序结果字符串 */ public static String sortMap(Map param){ StringBuilder result = new StringBuilder(); Collection keySet = param.keySet(); List list = new ArrayList(keySet); Collections.sort(list); for (int i = 0; i < list.size(); ++i) { String key = list.get(i); if("symmetricKey".equals(key)){ continue; } // 非空字段需要参与签名 // if(param.get(key) == null || "".equals(param.get(key).trim())){ // continue; // } result.append(key).append("=").append(param.get(key)).append("&"); } return result.substring(0, result.length() - 1); } public static String sha256(byte[] data) { try { MessageDigest md = MessageDigest.getInstance("SHA-256"); return bytesToHex(md.digest(data)); } catch (Exception ex) { return null; } } /** * 将byte数组转换成16进制字符串 * * @param bytes * @return 16进制字符串 */ public static String bytesToHex(byte[] bytes) { String hexArray = "0123456789abcdef"; StringBuilder sb = new StringBuilder(bytes.length * 2); for (byte b : bytes) { int bi = b & 0xff; sb.append(hexArray.charAt(bi >> 4)); sb.append(hexArray.charAt(bi & 0xf)); } return sb.toString(); } public static byte[] hexToBytes(String hex) { return hexToBytes(hex.toCharArray()); } public static byte[] hexToBytes(char[] hex) { int length = hex.length / 2; byte[] raw = new byte[length]; for (int i = 0; i < length; i++) { int high = Character.digit(hex[i * 2], 16); int low = Character.digit(hex[i * 2 + 1], 16); int value = (high << 4) | low; if (value > 127) { value -= 256; } raw[i] = (byte) value; } return raw; } public static String createSign(Map params){ StringBuilder sb = new StringBuilder(); // 将参数以参数名的字典升序排序 Map sortParams = new TreeMap(params); // 遍历排序的字典,并拼接"key=value"格式 for (Map.Entry entry : sortParams.entrySet()) { String key = entry.getKey(); String value = entry.getValue().trim(); if (null != value && !"".equals(value)) sb.append("&").append(key).append("=").append(value); } String stringA = sb.toString().replaceFirst("&",""); String stringSignTemp = stringA ; String signValue = sha256(stringSignTemp.getBytes()); return signValue; } /** * 签名 * @param param 待签名的参数 * @param sign 签名结果字符串 * @return 签名结果 * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws InvalidKeyException * @throws SignatureException */ public static boolean verify(Map param, String sign,String rescissionPublicKey) throws Exception { String value = sortMap(param); byte[] keyBytes = Base64.decodeBase64(rescissionPublicKey); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyf = KeyFactory.getInstance("RSA"); PublicKey pubkey = keyf.generatePublic(keySpec); Signature signature = Signature.getInstance("SHA256WithRSA"); signature.initVerify(pubkey); signature.update(value.getBytes()); boolean result = signature.verify(Base64.decodeBase64(sign.getBytes())); return result; } }