| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- package com.happy.Unitil_elc;
- import javax.crypto.Cipher;
- import javax.crypto.spec.IvParameterSpec;
- import javax.crypto.spec.SecretKeySpec;
- import java.nio.charset.StandardCharsets;
- import java.security.MessageDigest;
- import java.security.NoSuchAlgorithmException;
- public class CodeUtil {
- /**
- * 解密
- * @param src 源数据
- * @param secret 秘钥
- * @param iv 初始化向量
- * @return String
- */
- public static String dataDecode(String src, String secret, String iv){
- try {
- // 判断Key是否正确
- if (secret == null) {
- System.out.print("Key为空null");
- return null;
- }
- // 判断Key是否为16位
- if (secret.length() != 16) {
- System.out.print("Key长度不是16位");
- return null;
- }
- byte[] raw = secret.getBytes(StandardCharsets.US_ASCII);
- SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
- Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
- cipher.init(Cipher.DECRYPT_MODE, skeySpec, ips);
- // byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);// 先用base64解密
- byte[] encrypted1 = Base64.decode(src);
- try {
- byte[] original = cipher.doFinal(encrypted1);
- return new String(original, StandardCharsets.UTF_8);
- } catch (Exception e) {
- System.out.println(e.toString());
- return null;
- }
- } catch (Exception ex) {
- System.out.println(ex.toString());
- return null;
- }
- }
- /**
- * 加密
- * @param src 源数据
- * @param secret 秘钥
- * @param iv 初始化向量
- * @return String
- */
- public static String dataEncode(String src, String secret, String iv) throws Exception {
- if (secret == null) {
- System.out.print("Key为空null");
- return null;
- }
- // 判断Key是否为16位
- if (secret.length() != 16) {
- System.out.print("Key长度不是16位");
- return null;
- }
- byte[] raw = secret.getBytes(StandardCharsets.UTF_8);
- SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
- Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// "算法/模式/补码方式"
- IvParameterSpec ips = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
- cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ips);
- byte[] encrypted = cipher.doFinal(src.getBytes(StandardCharsets.UTF_8));
- // return new BASE64Encoder().encode(encrypted);// 此处使用BASE64做转码功能,同时能起到2次加密的作用。
- return Base64.encode(encrypted);
- }
- /**
- * 获取签名
- * @param src 源数据
- * @param signKey 签名秘钥
- * @return String
- */
- public static String getSign(String src,String signKey){
- String result = "";
- try {
- byte[] keyByte = signKey.getBytes(StandardCharsets.UTF_8);
- byte[] dataByte = src.getBytes(StandardCharsets.UTF_8);
- byte[] hmacMd5Byte = getHmacMd5Bytes(keyByte, dataByte);
- StringBuilder md5Str = new StringBuilder();
- for (byte b : hmacMd5Byte) {
- if (Integer.toHexString(0xFF & b).length() == 1) md5Str.append("0").append(Integer.toHexString(0xFF & b));
- else md5Str.append(Integer.toHexString(0xFF & b));
- }
- result = md5Str.toString().toUpperCase();
- } catch (Exception ignored) {
- }
- return result;
- }
- /**
- * 将待加密数据data,通过密钥key,使用hmac-md5算法进行加密,然后返回加密结果。 参照rfc2104 HMAC算法介绍实现。
- *
- * @author sc
- * @param key 密钥
- * @param data 待加密数据
- * @return 加密结果
- */
- private static byte[] getHmacMd5Bytes(byte[] key, byte[] data) throws NoSuchAlgorithmException {
- /*
- * HmacMd5 calculation formula: H(K XOR opad, H(K XOR ipad, text)) HmacMd5 计算公式:H(K XOR opad, H(K XOR ipad,
- * text)) H代表hash算法,本类中使用MD5算法,K代表密钥,text代表要加密的数据 ipad为0x36,opad为0x5C。
- */
- int length = 64;
- byte[] ipad = new byte[length];
- byte[] opad = new byte[length];
- for (int i = 0; i < 64; i++) {
- ipad[i] = 0x36;
- opad[i] = 0x5C;
- }
- byte[] actualKey = key; // Actual key.
- byte[] keyArr = new byte[length]; // Key bytes of 64 bytes length
- /*
- * If key's length is longer than 64,then use hash to digest it and use the result as actual key.
- * 如果密钥长度,大于64字节,就使用哈希算法,计算其摘要,作为真正的密钥。
- */
- if (key.length > length) {
- actualKey = md5(key);
- }
- System.arraycopy(actualKey, 0, keyArr, 0, actualKey.length);
- /*
- * append zeros to K 如果密钥长度不足64字节,就使用0x00补齐到64字节。
- */
- if (actualKey.length < length) {
- for (int i = actualKey.length; i < keyArr.length; i++)
- keyArr[i] = 0x00;
- }
- /*
- * calc K XOR ipad 使用密钥和ipad进行异或运算。
- */
- byte[] kIpadXorResult = new byte[length];
- for (int i = 0; i < length; i++) {
- kIpadXorResult[i] = (byte) (keyArr[i] ^ ipad[i]);
- }
- /*
- * append "text" to the end of "K XOR ipad" 将待加密数据追加到K XOR ipad计算结果后面。
- */
- byte[] firstAppendResult = new byte[kIpadXorResult.length + data.length];
- System.arraycopy(kIpadXorResult, 0, firstAppendResult, 0, kIpadXorResult.length);
- System.arraycopy(data, 0, firstAppendResult, keyArr.length, data.length);
- /*
- * calc H(K XOR ipad, text) 使用哈希算法计算上面结果的摘要。
- */
- byte[] firstHashResult = md5(firstAppendResult);
- /*
- * calc K XOR opad 使用密钥和opad进行异或运算。
- */
- byte[] kOpadXorResult = new byte[length];
- for (int i = 0; i < length; i++) {
- kOpadXorResult[i] = (byte) (keyArr[i] ^ opad[i]);
- }
- /*
- * append "H(K XOR ipad, text)" to the end of "K XOR opad" 将H(K XOR ipad, text)结果追加到K XOR opad结果后面
- */
- byte[] secondAppendResult = new byte[kOpadXorResult.length + firstHashResult.length];
- System.arraycopy(kOpadXorResult, 0, secondAppendResult, 0, kOpadXorResult.length);
- System.arraycopy(firstHashResult, 0, secondAppendResult, keyArr.length, firstHashResult.length);
- /*
- * H(K XOR opad, H(K XOR ipad, text)) 对上面的数据进行哈希运算。
- */
- return md5(secondAppendResult);
- }
- /**
- * 计算参数的md5信息
- *
- * @param str 待处理的字节数组
- * @return md5摘要信息
- */
- private static byte[] md5(byte[] str) throws NoSuchAlgorithmException {
- MessageDigest md = MessageDigest.getInstance("MD5");
- md.update(str);
- return md.digest();
- }
- }
|