硬件分组加密内容不能超过136个字节,软件没有限制,本问提供自己封装的工具类之外还有一个附带的jar资源
软件代码封装
package com.people.util;
import java.io.IOException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.Gson;
import com.people.dao.FishermanInfoDao;
import com.people.dao.KeyManagementDao;
import com.people.domain.DecryptTxtVo;
import com.people.domain.ResourcesGetVo;
import com.people.security.Utils.Util;
import com.people.security.sm2.SM2EncDecUtils;
import com.people.security.sm2.SM2SignVO;
import com.people.security.sm2.SM2SignVerUtils;
import com.people.security.sm4.EBCSM4;
import com.people.utils.Sm2GroupEncryUtils;
/**
* 国密算法软实现分组算法sm2
*
* @author zhaozhiqiang
*
*/
@Component
public class SoftGroupSMUtils {
static Gson gson = new Gson();
@Autowired
KeyManagementDao keyManagementDao;
@Autowired
FishermanInfoDao fishermanInfoDao;
@Autowired
private ResourcesGetVo resourcesGetVo;
/**
* 分组加密
*
* @param path
* @param custID
* @return
* @throws Exception
*/
public String encrypGroup(String path, String custID) throws Exception {
DecryptTxtVo vo = CSVUtils.readCSV(path);
String decrypt = gson.toJson(vo);
Slf4jLogUtil.info("csv加密之前的数据:"+ decrypt);
// 获取最新的客户编号
// String custID = keyManagementDao.getCustId();
String serviceKeySM4 = keyManagementDao.getServiceKey();
// 解密
String servicePublick = EBCSM4.SM4DecForECB(resourcesGetVo.getSm4key(),
serviceKeySM4);
if (servicePublick == null) {
return null;
}
// // 公钥加密
// String encrypt = SM2EncDecUtils.encrypt(
// Util.hexStringToBytes(servicePublick), decrypt.getBytes());
// // 删除04
// encrypt = encrypt.substring(2, encrypt.length());
// 使用客户端私钥签名
// // 获取客户端私钥密文
// String clientPriKeySm4 = keyManagementDao.getClientPriKey(custID);
// String priKey = EBCSM4.SM4DecForECB(resourcesGetVo.getSm4key(),
// clientPriKeySm4);
// SM2SignVO sign = SM2SignVerUtils.Sign2SM2(Util.hexToByte(priKey),
// Util.hexToByte(encrypt));
List<String> chineseSplitFunction = Sm2GroupEncryUtils
.chineseSplitFunction(decrypt, 1024 * 8);
String listData = "";
for (int i = 0; i < chineseSplitFunction.size(); i++) {
String bytes = chineseSplitFunction.get(i);
String cellData = "";
if (bytes.length() < 4) {
if (bytes.length() == 1) {
cellData = bytes + "001";
Slf4jLogUtil.info("加密内容缺失补充:" + 001);
}
if (bytes.length() == 2) {
cellData = bytes + "002";
Slf4jLogUtil.info("加密内容缺失补充:" + 002);
}
if (bytes.length() == 3) {
cellData = bytes + "003";
Slf4jLogUtil.info("加密内容缺失补充:" + 003);
}
} else {
cellData = bytes;
}
// 公钥加密
String resCode = SM2EncDecUtils.encrypt(
Util.hexStringToBytes(servicePublick),
cellData.getBytes("UTF-8"));
if (i < (chineseSplitFunction.size() - 1)) {
listData = listData + resCode + ",";
} else {
listData = listData + resCode;
}
}
return listData;
}
/**
* 分组加密
*
* @param json 待加密的json字符串
* @param custID
* @return
* @throws Exception
*/
public String encrypGroupJson(String json, String custID) throws Exception {
// 获取最新的客户编号
// String custID = keyManagementDao.getCustId();
String serviceKeySM4 = keyManagementDao.getServiceKey();
// 解密
String servicePublick = EBCSM4.SM4DecForECB(resourcesGetVo.getSm4key(),
serviceKeySM4);
if (servicePublick == null) {
return null;
}
List<String> chineseSplitFunction = Sm2GroupEncryUtils
.chineseSplitFunction(json, 1024 * 8);
String listData = "";
for (int i = 0; i < chineseSplitFunction.size(); i++) {
String bytes = chineseSplitFunction.get(i);
String cellData = "";
if (bytes.length() < 4) {
if (bytes.length() == 1) {
cellData = bytes + "001";
Slf4jLogUtil.info("加密内容缺失补充:" + 001);
}
if (bytes.length() == 2) {
cellData = bytes + "002";
Slf4jLogUtil.info("加密内容缺失补充:" + 002);
}
if (bytes.length() == 3) {
cellData = bytes + "003";
Slf4jLogUtil.info("加密内容缺失补充:" + 003);
}
} else {
cellData = bytes;
}
// 公钥加密
String resCode = SM2EncDecUtils.encrypt(
Util.hexStringToBytes(servicePublick),
cellData.getBytes("UTF-8"));
if (i < (chineseSplitFunction.size() - 1)) {
listData = listData + resCode + ",";
} else {
listData = listData + resCode;
}
}
return listData;
}
/**
* 分组解密
*
* @param listData
* @return
* @throws IOException
*/
public String descGroupData(String listData, String serPriKey,
String secretKey) throws IOException {
String str = "";
// 开始解密
String privateKey = EBCSM4.SM4DecForECB(secretKey, serPriKey);
String[] split = listData.split(",");
// 开始分组解密
for (int i = 0; i < split.length; i++) {
byte[] code = SM2EncDecUtils.decrypt(
Util.hexStringToBytes(privateKey),
Util.hexStringToBytes(split[i]));
String strGroup = new String(code);
str = str + strGroup;
}
// 如果解密出来的最后三位是001,002,003就去除
String subEndStr = str.substring((str.length()) - 3, str.length());
if (subEndStr.equals("001") || subEndStr.equals("002")
|| subEndStr.equals("003")) {
str = str.substring(0, str.length() - 3);
}
return str;
}
}
加密码代码封装
package com.people;
import java.security.KeyPair;
import java.security.PublicKey;
import java.util.List;
import com.people.entity.FishermanInfoEntity;
import com.people.util.ResponseUtils;
import com.people.utils.HexUtils;
import com.people.utils.KeyWiteAndReadUtils;
import com.people.utils.SM2Utils;
import com.people.utils.Sm2GroupEncryUtils;
/**
* 渔翁硬件加密卡分组算法代码封装
* sm2分组加密 如果被加密的内容超过136的话就需要分组加密了 渔翁加密卡支持: sm2加密最大数据长度是136位
* GBK编码,一个汉字占两个字节。UTF-8编码是变长编码,通常汉字占三个字节,扩展B区以后的汉字占四个字节。
* UTF-16编码,通常汉字占两个字节,扩展D区中的汉字占四个字节 中文字支持45分组 特殊字符支持136分组 sm2分组解密数据特性:
* 解密内容长度最大246
*
* @author zhaozhiqiang
*
*/
public class FishManUtils {
/**
* 国密算法硬件分组加密
*
* @param data
* @return
*/
public void encryData(String data) {
// 获取加密卡内部密钥对象
try {
SM2Utils innerSm2 = (SM2Utils) getInnerSm2();
SM2Utils innerSm22 = innerSm2;
if (null == innerSm22) {
}
// // 读取公钥文件的密钥16进制值
// PublicKey peoplePublickey = (PublicKey) KeyWiteAndReadUtils
// .readObject(commonPath() + uploadsm2publickeyName);
// String returnHexString = ComFun.returnHexString(peoplePublickey
// 查询服务端公钥地址
// 获取公钥对象
PublicKey publickKey = (PublicKey) KeyWiteAndReadUtils
.readObject("服务端密钥地址");
// 内容进行加密内容长度在136以内的话直接可以加密否则分组加密
List<String> strList = Sm2GroupEncryUtils.chineseSplitFunction(
data, 136);
// Slf4jLogUtil.info("加密内容分组长度:" + strList.size());
String listData = "";
for (int i = 0; i < strList.size(); i++) {
String cellData = "";
if (strList.get(i).getBytes().length < 4) {
if (strList.get(i).getBytes().length == 1) {
cellData = strList.get(i) + "001";
System.out.println("加密内容缺失补充:" + 001);
}
if (strList.get(i).getBytes().length == 2) {
cellData = strList.get(i) + "002";
System.out.println("加密内容缺失补充:" + 002);
}
if (strList.get(i).getBytes().length == 3) {
cellData = strList.get(i) + "003";
System.out.println("加密内容缺失补充:" + 003);
}
} else {
cellData = strList.get(i);
}
byte[] encrypData = innerSm22.ExternalSM2Enc(publickKey,
cellData.getBytes());
// 将二进制转化成16进制
String byteToHex2 = HexUtils.ByteToHex(encrypData);
if (i < (strList.size() - 1)) {
listData = listData + byteToHex2 + ",";
} else {
listData = listData + byteToHex2;
}
}
System.out.println(listData);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 国密算法sm2硬件分组解密
*
* @param data
* @return
*/
public void descryencryData(String data) {
// Slf4jLogUtil.info("16进制密文长度:" + data.length());
String str = "";
try {
SM2Utils sm2Utils = new SM2Utils();
String[] split = data.split(",");
// 获取加密卡内部密钥对象
SM2Utils innerSm2 = (SM2Utils) getInnerSm2();
if (null == innerSm2) {
}
// 开始分组解密
for (int i = 0; i < split.length; i++) {
// 将加密后的16进制数据转化成2进制字符串
byte[] hexToByte = HexUtils.HexToByte(split[i]);
byte[] descryptData = sm2Utils.descryptData(
Integer.parseInt("加密卡密钥存储位置"), hexToByte);
String strGroup = new String(descryptData);
str = str + strGroup;
}
// 如果解密出来的最后三位是001,002,003就去除
String subEndStr = str.substring((str.length()) - 3, str.length());
if (subEndStr.equals("001") || subEndStr.equals("002")
|| subEndStr.equals("003")) {
str = str.substring(0, str.length() - 3);
}
System.out.println(str);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取加密卡内部密钥对象
*
* @return
* @throws NumberFormatException
*/
public Object getInnerSm2() throws NumberFormatException {
// 将加密卡内部密钥拆分成公钥和私钥对象
SM2Utils sm2Utils = new SM2Utils();
// 获取加密卡内部密钥对象
KeyPair exportInternalSM2KeyPair = sm2Utils
.ExportInternalSM2KeyPair(Integer.parseInt("加密卡密钥存储位置"));
if (null == exportInternalSM2KeyPair) {
return null;
}
return sm2Utils;
}
}
完整资源链接地址
https://download.youkuaiyun.com/download/weixin_38501485/12619757