国密软硬分组加减密算法

 硬件分组加密内容不能超过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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BACKWASH2038

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值