|
|
|
@ -1,19 +1,13 @@ |
|
|
|
|
package com.jianshui.common.utils.encrypt; |
|
|
|
|
|
|
|
|
|
import cn.hutool.core.util.HexUtil; |
|
|
|
|
import cn.hutool.crypto.SecureUtil; |
|
|
|
|
import sun.misc.BASE64Decoder; |
|
|
|
|
import sun.misc.BASE64Encoder; |
|
|
|
|
|
|
|
|
|
import java.io.UnsupportedEncodingException; |
|
|
|
|
import java.nio.charset.StandardCharsets; |
|
|
|
|
import java.security.MessageDigest; |
|
|
|
|
import java.util.Base64; |
|
|
|
|
import javax.crypto.Cipher; |
|
|
|
|
import javax.crypto.SecretKey; |
|
|
|
|
import javax.crypto.spec.GCMParameterSpec; |
|
|
|
|
import javax.crypto.spec.IvParameterSpec; |
|
|
|
|
import javax.crypto.spec.SecretKeySpec; |
|
|
|
|
import java.io.IOException; |
|
|
|
|
import java.io.UnsupportedEncodingException; |
|
|
|
|
import java.nio.charset.StandardCharsets; |
|
|
|
|
import java.security.MessageDigest; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 功能描述 |
|
|
|
@ -22,10 +16,10 @@ import java.security.MessageDigest; |
|
|
|
|
public class JianshuiInvoiceEncryptUtil { |
|
|
|
|
|
|
|
|
|
private static final String ALGORITHM = "AES/GCM/NoPadding"; |
|
|
|
|
private static final int IV_LENGTH = 12; // 初始化向量长度为12字节(96位)
|
|
|
|
|
private static final int TAG_LENGTH = 16; // GCM模式的认证标签长度为16字节
|
|
|
|
|
private static final int IV_LENGTH = 12; |
|
|
|
|
private static final int TAG_LENGTH = 16; |
|
|
|
|
|
|
|
|
|
/** 加密共有两种方法 一、DES 二、AES*/ |
|
|
|
|
/** 加密支持两种方法,建议用AES 一、DES 二、AES */ |
|
|
|
|
|
|
|
|
|
/** 一、DES加密方法*/ |
|
|
|
|
public static String encrypt(String xmlStr, String mkey) { |
|
|
|
@ -65,7 +59,7 @@ public class JianshuiInvoiceEncryptUtil { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 使用Base64加密后返回
|
|
|
|
|
return new BASE64Encoder().encode(temp); |
|
|
|
|
return Base64.getEncoder().encodeToString(temp); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -86,8 +80,9 @@ public class JianshuiInvoiceEncryptUtil { |
|
|
|
|
|
|
|
|
|
/** AES 加密接口*/ |
|
|
|
|
public static byte[] AES_Encrypt(byte[] sourceBuf, |
|
|
|
|
byte[] keys, IvParameterSpec ivParam) throws Exception { |
|
|
|
|
byte[] iv = keys; |
|
|
|
|
byte[] keys, IvParameterSpec ivParam) throws Exception { |
|
|
|
|
byte[] iv = new byte[IV_LENGTH]; |
|
|
|
|
System.arraycopy(keys, 0, iv, 0, Math.min(IV_LENGTH, keys.length)); |
|
|
|
|
|
|
|
|
|
Cipher cipher = Cipher.getInstance(ALGORITHM); |
|
|
|
|
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(TAG_LENGTH * 8, iv); |
|
|
|
@ -100,9 +95,10 @@ public class JianshuiInvoiceEncryptUtil { |
|
|
|
|
System.arraycopy(iv, 0, result, 0, IV_LENGTH); |
|
|
|
|
System.arraycopy(ciphertext, 0, result, IV_LENGTH, ciphertext.length); |
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** 转为十六进制字符串*/ |
|
|
|
|
private static String bytesToHex(byte[] bytes) { |
|
|
|
|
StringBuilder sb = new StringBuilder(); |
|
|
|
@ -131,19 +127,24 @@ public class JianshuiInvoiceEncryptUtil { |
|
|
|
|
// 组合消息体
|
|
|
|
|
byte[] totalByte = addMD5(md5Hasn, encrypt); |
|
|
|
|
|
|
|
|
|
// 取密钥和偏转向量
|
|
|
|
|
byte[] iv = new byte[16]; |
|
|
|
|
// 取密钥
|
|
|
|
|
byte[] keyBytes = mkey.getBytes(StandardCharsets.UTF_8); |
|
|
|
|
byte[] validKeyBytes = new byte[16]; // 默认使用128位密钥
|
|
|
|
|
System.arraycopy(keyBytes, 0, validKeyBytes, 0, Math.min(keyBytes.length, 16)); |
|
|
|
|
|
|
|
|
|
// 取偏转向量
|
|
|
|
|
byte[] iv = new byte[IV_LENGTH]; |
|
|
|
|
IvParameterSpec ivParam = new IvParameterSpec(iv); |
|
|
|
|
|
|
|
|
|
// 使用DES算法使用加密消息体
|
|
|
|
|
// 使用AES算法加密消息体
|
|
|
|
|
byte[] temp = null; |
|
|
|
|
try { |
|
|
|
|
temp = AES_Encrypt(totalByte, mkey.getBytes(), ivParam); |
|
|
|
|
temp = AES_Encrypt(totalByte, validKeyBytes, ivParam); |
|
|
|
|
} catch (Exception e) { |
|
|
|
|
e.printStackTrace(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 使用Base64加密后返回
|
|
|
|
|
// 使用十六进制编码后返回
|
|
|
|
|
return bytesToHex(temp); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -175,13 +176,7 @@ public class JianshuiInvoiceEncryptUtil { |
|
|
|
|
|
|
|
|
|
public static void getKeyIV(String encryptKey, byte[] key, byte[] iv) { |
|
|
|
|
// 密钥Base64解密
|
|
|
|
|
BASE64Decoder decoder = new BASE64Decoder(); |
|
|
|
|
byte[] buf = null; |
|
|
|
|
try { |
|
|
|
|
buf = decoder.decodeBuffer(encryptKey); |
|
|
|
|
} catch (IOException e) { |
|
|
|
|
e.printStackTrace(); |
|
|
|
|
} |
|
|
|
|
byte[] buf = Base64.getDecoder().decode(encryptKey); |
|
|
|
|
// 前8位为key
|
|
|
|
|
int i; |
|
|
|
|
for (i = 0; i < key.length; i++) { |
|
|
|
@ -195,30 +190,8 @@ public class JianshuiInvoiceEncryptUtil { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) throws Exception { |
|
|
|
|
|
|
|
|
|
// 生成一个随机的AES密钥
|
|
|
|
|
/* SecretKey secretKey = SecureUtil.generateKey("AES"); |
|
|
|
|
// 转换为16进制字符串
|
|
|
|
|
String keyHex = HexUtil.encodeHexStr(secretKey.getEncoded()); |
|
|
|
|
System.out.println("AES密钥:"); |
|
|
|
|
System.out.println(keyHex);*/ |
|
|
|
|
|
|
|
|
|
String str = "{\"taxNo\":\"91370100664851254J\",\"fpdm\":\"\",\"fphm\":\"25152000000011784979\",\"kprq\":\"20250311\",\"fpje\":\"267810\",\"fpzl\":\"21\",\"jym\":null}"; |
|
|
|
|
// String key = "S1jIlJRLXBNtIFihvQ0VPw==";
|
|
|
|
|
String key = "FIQKraT+UheC1GqQtgDM6g=="; |
|
|
|
|
System.out.println(encryptAES(str,key)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String key = "OvUtrlk1LUNMIs1oCdzTQ=="; |
|
|
|
|
System.out.println(encryptAES(str, key)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|