RSA算法实现数据加密签名传输与数据解密代码实(2)

RSA算法实现数据加密签名传输与数据解密代码实

package com.sxy.rsademo.rsa; import com.sxy.rsademo.utils.Base64; import com.sxy.rsademo.utils.CastUtils; import lombok.extern.slf4j.Slf4j; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import java.io.*; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; /** * @Description: RSA 工具类 * @Author: SuXingYong * @Date 2020/7/11 23:35 **/ @Slf4j public class RsaUtils extends KeyConstant { /************************************************* 密钥初始化、持久化、获取start *************************************************/ /** * @Description 初始化密钥对 * 返回甲方密钥的Map * @Author SuXingYong * @Date 2020/7/11 23:35 * @Param [] * @Return java.util.Map<java.lang.String,java.lang.Object> **/ public static Map<String,Object> initKey(){ // 将密钥存储在map中 Map<String,Object> keyMap = new HashMap<String,Object>(); try { // 实例化密钥生成器 采用RSA算法 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM); // 初始化密钥生成器 1024 keyPairGenerator.initialize(KEY_SIZE); // 生成密钥对 KeyPair keyPair = keyPairGenerator.generateKeyPair(); // 甲方公钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); log.info("系数:"+publicKey.getModulus()+" 加密指数:"+publicKey.getPublicExponent()); // 甲方私钥 RSAPrivateKey privateKey=(RSAPrivateKey) keyPair.getPrivate(); log.info("系数:"+privateKey.getModulus()+" 解密指数:"+privateKey.getPrivateExponent()); // 公钥 keyMap.put(PUBLIC_KEY, Base64.encode(publicKey.getEncoded())); // 私钥 keyMap.put(PRIVATE_KEY, Base64.encode(privateKey.getEncoded())); // 公钥持久性文件存储地址 String publicKeyFileSavePath = PUBLIC_KEY_FILE_ULR; if (publicKeyFileSavePath != null && !publicKeyFileSavePath.equals("")){ keyMap.put(PUBLIC_KEY_FILE_SAVE_PATH,publicKeyFileSavePath); } // 私钥持久性文件存储地址 String privateKeyFileSavePath = PRIVATE_KEY_FILE_ULR; if (privateKeyFileSavePath != null && !privateKeyFileSavePath.equals("")){ keyMap.put(PRIVATE_KEY_FILE_SAVE_PATH,privateKeyFileSavePath); } // 密钥对持久化存储 RsaUtils.saveKeyPairToFile(keyMap); }catch (Exception e){ e.printStackTrace(); log.error(e.getMessage()); } return keyMap; } /** * @Description 保存密钥对 到文件中 * @Author SuXingYong * @Date 2020/7/11 23:35 * @Param [keyMap] * @Return void **/ public static void saveKeyPairToFile(Map<String,Object> keyMap){ try { // 公钥原始字符串 String publicKeyOriginalString = CastUtils.castString(keyMap.get(PUBLIC_KEY)); log.info("公钥:"+publicKeyOriginalString); // 私钥原始字符串 String privateKeyOriginalString = CastUtils.castString(keyMap.get(PRIVATE_KEY)); log.info("私钥:"+privateKeyOriginalString); // 需要存储的公钥字符串键值对 StringBuilder publicKeyOutString = new StringBuilder(""); publicKeyOutString.append(PUBLIC_KEY).append(KEY_AND_VALUE_SEPARATOR).append(publicKeyOriginalString); // 需要存储的私钥字符串键值对 StringBuilder privateKeyOutString = new StringBuilder(""); privateKeyOutString.append(PUBLIC_KEY).append(KEY_AND_VALUE_SEPARATOR).append(privateKeyOriginalString); // 公钥存储地址 String publicKeyPath = CastUtils.castString(keyMap.get(PUBLIC_KEY_FILE_SAVE_PATH)); File publicKeyFile = new File(publicKeyPath); if (!publicKeyFile.exists()){ publicKeyFile.getParentFile().mkdirs(); } log.info("公钥存储地址:"+publicKeyPath); // 私钥存储地址 String privateKeyPath = CastUtils.castString(keyMap.get(PRIVATE_KEY_FILE_SAVE_PATH)); File privateKeyFile = new File(privateKeyPath); if (!privateKeyFile.exists()){ privateKeyFile.getParentFile().mkdirs(); } log.info("私钥存储地址:"+privateKeyPath); // 将密钥对写入到文件 FileWriter publicFileWriter = new FileWriter(publicKeyPath); FileWriter privateFileWriter = new FileWriter(privateKeyPath); BufferedWriter publicBufferedWriter = new BufferedWriter(publicFileWriter); BufferedWriter privateBufferedWriter = new BufferedWriter(privateFileWriter); publicBufferedWriter.write(publicKeyOutString.toString()); privateBufferedWriter.write(privateKeyOutString.toString()); publicBufferedWriter.flush(); publicBufferedWriter.close(); publicFileWriter.close(); privateBufferedWriter.flush(); privateBufferedWriter.close(); privateFileWriter.close(); }catch (Exception e){ e.printStackTrace(); log.error(e.getMessage()); } } /** * @Description 从文件中输入流中获得密钥(公钥或者私钥[根据传入的地址不同读取不同的文件])字符串 * @Author SuXingYong * @Date 2020/7/11 23:35 * @Param [keyFilePath] * @Return java.lang.String **/ public static String getKeyByFile(String keyFilePath) throws Exception { try { BufferedReader bufferedReader = new BufferedReader(new FileReader(keyFilePath)); String readLine = null; StringBuilder keyOutStr = new StringBuilder(); // 读取文件 while ((readLine = bufferedReader.readLine()) != null) { keyOutStr.append(readLine); } bufferedReader.close(); // 密钥字符串 String keyStr = ""; if (keyOutStr.toString().indexOf(KEY_AND_VALUE_SEPARATOR) != -1){ String[] keyOutStrArr = keyOutStr.toString().split(KEY_AND_VALUE_SEPARATOR); if (keyOutStrArr != null && keyOutStrArr.length >1){ keyStr = keyOutStrArr[1]; } } return keyStr; } catch (IOException e) { throw new Exception("密钥数据流读取错误"); } catch (NullPointerException e) { throw new Exception("密钥输入流为空"); } } /** * @Description 获取持久的密钥对(直接从密钥文件中读取的) * @Author SuXingYong * @Date 2020/7/11 23:35 * @Param [] * @Return java.util.Map<java.lang.String,java.lang.Object> 返回持久的公钥和私钥 **/ public static Map<String, Object> getLastingKeyPair() throws Exception { Map<String, Object> returnMap = new LinkedHashMap<>(); // 读取文件中的公钥 获取方式为:基础文件路径 + 公钥文件存储地址 String publicKeyFileStr = RsaUtils.getKeyByFile(PUBLIC_KEY_FILE_ULR); if (publicKeyFileStr != null && !publicKeyFileStr.equals("")){ // 公钥 returnMap.put(PUBLIC_KEY,publicKeyFileStr); log.info("持久化公钥:"+publicKeyFileStr); } // 读取文件中的私钥 获取方式为:基础文件路径 + 私钥文件存储地址 String privateKeyFileStr = RsaUtils.getKeyByFile(PRIVATE_KEY_FILE_ULR); if (privateKeyFileStr != null && !privateKeyFileStr.equals("")){ // 私钥 returnMap.put(PRIVATE_KEY,privateKeyFileStr); log.info("持久化私钥:"+privateKeyFileStr); } return returnMap; } /************************************************* 密钥初始化、持久化、获取end *************************************************/ /** * @Description 分组加密/解密 * @Author SuXingYong * @Date 2020/7/11 23:35 * @Param [rsaMode, dataByteArr, cipher] * @param rsaMode RSA模式:encrypt:加密 decrypt:解密 * @param dataByteArr 需要加密/解密的数据字节数组 * @param cipher * @Return byte[] 完成加密/解密之后的字节数组 **/ public static byte[] groupEncryptOrDecrypt(String rsaMode,byte[] dataByteArr, Cipher cipher) throws BadPaddingException, IllegalBlockSizeException { // 结果数组 byte[] returnByteArr = {}; // 分段处理 int dataByteArrLength = dataByteArr.length; log.info("数据字节数:" + dataByteArrLength); // 最大加密/解密字节数,超出最大字节数需要分组加密/解密 int MAX_BLOCK = 0; if (rsaMode != null && !rsaMode.equals("")){ // 加密模式 if (RSA_MODE_01.equalsIgnoreCase(rsaMode)){ // 117 MAX_BLOCK = ENCRYPT_MAX_SIZE; } // 解密模式 if (RSA_MODE_02.equalsIgnoreCase(rsaMode)){ // 128 MAX_BLOCK = DECRYPT_MAX_SIZE; } } // 标识 int offSet = 0; // 缓存数组 byte[] tempByteArr = {}; // 判断加密/解密字节数 - 标识 是否到达末尾 while (dataByteArrLength - offSet > 0) { // 如果加密/解密字节数 - 标识 > 最大加密/解密字节数 if (dataByteArrLength - offSet > MAX_BLOCK) { // 执行加密/解密 标识位 到 最大加密/解密字节数位 tempByteArr = cipher.doFinal(dataByteArr, offSet, MAX_BLOCK); // 标识 = 自身 + 最大加密/解密字节数 offSet += MAX_BLOCK; } else { // 如果加密/解密字节数 - 标识 小于等于 最大加密/解密字节数 // 执行加密/解密 标识位 到 (加密/解密字节数 - 标志)位 tempByteArr = cipher.doFinal(dataByteArr, offSet, dataByteArrLength - offSet); // 标识 = 加密/解密字节数 offSet = dataByteArrLength; } // 创建信息的数组 原来数组的长度 想要得到的新数组的长度(原数组长度 + 缓存数组长度) returnByteArr = Arrays.copyOf(returnByteArr, returnByteArr.length + tempByteArr.length); // 数组复制 (源数组, 源数组要复制的起始位置, 目标数组, 目标数组放置的起始位置, 要复制的长度) // 将缓存数组中的数据 复制到结果数组中 System.arraycopy(tempByteArr, 0, returnByteArr, returnByteArr.length - tempByteArr.length, tempByteArr.length); } return returnByteArr; } /************************************************* 加密start *************************************************/ /** * @Description 私钥加密(字节数组) * @Author SuXingYong * @Date 2020/7/11 23:35 * @Param [data, key] * @param data 待加密数据 * @param key 密钥 * @Return byte[] 加密之后的数据 **/ public static byte[] encryptByPrivateKey(byte[] data,byte[] key) throws Exception{ // 返回结果 byte[] result = {}; // 取得私钥 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key); // 实例化密钥工厂 RSA 算法的 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); // 数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); // 加密模式 1 cipher.init(Cipher.ENCRYPT_MODE, privateKey); // RSA模式 加密模式 String rsaMode = RSA_MODE_01; // 分组加密 byte[] returnByteArr = RsaUtils.groupEncryptOrDecrypt(rsaMode,data,cipher); if (returnByteArr != null && returnByteArr.length > 0){ result = returnByteArr; } return result; } /** * @Description 公钥加密(字节数组) * @Author SuXingYong * @Date 2020/7/11 23:35 * @Param [data, key] * @param data 待加密的数据 * @param key 密钥 * @Return byte[] 加密之后的数据 **/ public static byte[] encryptByPublicKey(byte[] data,byte[] key) throws Exception{ // 返回结果 byte[] result = {}; // 实例化密钥工厂 RSA 算法的 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 初始化公钥 // 密钥材料转换 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key); // 产生公钥 PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); // 数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); // 加密模式 cipher.init(Cipher.ENCRYPT_MODE, publicKey); // RSA模式 加密模式 String rsaMode = RSA_MODE_01; // 分组加密 byte[] returnByteArr = RsaUtils.groupEncryptOrDecrypt(rsaMode,data,cipher); if (returnByteArr != null && returnByteArr.length > 0){ result = returnByteArr; } return result; } /** * @Description 公钥加密(字符串) * @Author SuXingYong * @Date 2020/7/11 23:35 * @Param [data, key] * @param data 待加密的数据 * @param key 密钥 * @Return java.lang.String 加密之后的数据 **/ public static String encryptByPublicKey(String data,String key) throws Exception{ // 返回结果 StringBuilder result = new StringBuilder(""); // 实例化密钥工厂 RSA 算法的 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 初始化公钥 // 密钥材料转换 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(key)); // 产生公钥 PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); // 数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); // 加密模式 cipher.init(Cipher.ENCRYPT_MODE, publicKey); // 将数据字符串转换为字节数组 byte[] dataByteArr = data.getBytes(); // RSA模式 加密模式 String rsaMode = RSA_MODE_01; // 分组加密 byte[] returnByteArr = RsaUtils.groupEncryptOrDecrypt(rsaMode,dataByteArr,cipher); if (returnByteArr != null && returnByteArr.length > 0){ result.append(Base64.encode(returnByteArr)); } return result.toString(); } /** * @Description 私钥加密(字符串) * @Author SuXingYong * @Date 2020/7/11 23:35 * @Param [data, key] * @param data 待加密数据 * @param key 密钥 * @Return java.lang.String 加密之后的数据 **/ public static String encryptByPrivateKey(String data,String key) throws Exception{ // 返回结果 StringBuilder result = new StringBuilder(""); // 取得私钥 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decode(key)); // 实例化密钥工厂 RSA 算法的 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); // 数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); // 加密模式 1 cipher.init(Cipher.ENCRYPT_MODE, privateKey); // 将数据字符串转换为字节数组 byte[] dataByteArr = data.getBytes(); // RSA模式 加密模式 String rsaMode = RSA_MODE_01; // 分组加密 byte[] returnByteArr = RsaUtils.groupEncryptOrDecrypt(rsaMode,dataByteArr,cipher); if (returnByteArr != null && returnByteArr.length > 0){ result.append(Base64.encode(returnByteArr)); } return result.toString(); } /************************************************* 加密end *************************************************/ /************************************************* 解密start *************************************************/ /** * @Description 私钥解密(字节数组) * @Author SuXingYong * @Date 2020/7/11 23:35 * @Param [data, key] * @param data 待解密数据 * @param key 密钥 * @Return byte[] 解密之后的数据 **/ public static byte[] decryptByPrivateKey(byte[] data,byte[] key) throws Exception{ // 返回的结果字节数组 byte[] resultByteArr = {}; // 取得私钥 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key); // 实例化密钥工厂 RSA算法的 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); // 数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); // 解密模式 cipher.init(Cipher.DECRYPT_MODE, privateKey); // RSA模式 解密模式 String rsaMode = RSA_MODE_02; // 分组解密 byte[] returnBytes = RsaUtils.groupEncryptOrDecrypt(rsaMode,data,cipher); if (returnBytes != null && resultByteArr.length >0){ resultByteArr = returnBytes; } return resultByteArr; } /** * @Description 公钥解密(字节数组) * @Author SuXingYong * @Date 2020/7/11 23:35 * @Param [data, key] * @param data 待解密数据 * @param key 密钥 * @Return byte[] 解密之后的数据 **/ public static byte[] decryptByPublicKey(byte[] data,byte[] key) throws Exception{ // 返回的结果字节数组 byte[] resultByteArr = {}; // 实例化密钥工厂 RSA算法的 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 初始化公钥 // 密钥材料转换 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key); // 产生公钥 PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); // 数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); // 解密模式 cipher.init(Cipher.DECRYPT_MODE, publicKey); // RSA模式 解密模式 String rsaMode = RSA_MODE_02; // 分组解密 byte[] returnBytes = RsaUtils.groupEncryptOrDecrypt(rsaMode,data,cipher); if (returnBytes != null && resultByteArr.length >0){ resultByteArr = returnBytes; } return resultByteArr; } /** * @Description 私钥解密(字符串) * @Author SuXingYong * @Date 2020/7/11 23:35 * @Param [data, key] * @param data 待解密数据 * @param key 密钥 * @Return java.lang.String 解密之后的数据 **/ public static String decryptByPrivateKey(String data,String key) throws Exception{ // 解密之后的明文字符串 StringBuilder result = new StringBuilder(""); // 取得私钥 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decode(key)); // 实例化密钥工厂 RSA算法的 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); // 数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); // 解密模式 cipher.init(Cipher.DECRYPT_MODE, privateKey); // 将字符串数据转换为字节数组 byte[] dataByteArr = Base64.decode(data); // RSA模式 解密模式 String rsaMode = RSA_MODE_02; // 分组解密 byte[] resultBytes = RsaUtils.groupEncryptOrDecrypt(rsaMode,dataByteArr,cipher); // 给返回结果赋值 // TODO 特别注意: 本处将字节数组装换为字符串的时候,必须使用 new String()方法,不能使用toString()方法 // TODO toString()方法是调用的对象本身的,也就是继承或者重写的object.toString()方法,如果是byte[] b,那么返回的是b的内存地址。 // TODO new String()方法是使用虚拟机默认的编码base返回对应的字符。 result.append(new String(resultBytes)); return result.toString(); } /** * @Description 公钥解密(字节数组) * @Author SuXingYong * @Date 2020/7/11 23:35 * @Param [data, key] * @param data 待解密数据 * @param key 密钥 * @Return ava.lang.String 解密之后的数据 **/ public static String decryptByPublicKey(String data,String key) throws Exception{ // 解密之后的明文字符串 StringBuilder result = new StringBuilder(""); // 实例化密钥工厂 RSA算法的 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 初始化公钥 // 密钥材料转换 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(key)); // 产生公钥 PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); // 数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); // 解密模式 cipher.init(Cipher.DECRYPT_MODE, publicKey); // 将字符串数据转换为字节数组 byte[] dataByteArr = Base64.decode(data); // RSA模式 解密模式 String rsaMode = RSA_MODE_02; // 分组解密 byte[] resultBytes = RsaUtils.groupEncryptOrDecrypt(rsaMode,dataByteArr,cipher); // 给返回结果赋值 // TODO 特别注意: 本处将字节数组装换为字符串的时候,必须使用 new String()方法,不能使用toString()方法 // TODO toString()方法是调用的对象本身的,也就是继承或者重写的object.toString()方法,如果是byte[] b,那么返回的是b的内存地址。 // TODO new String()方法是使用虚拟机默认的编码base返回对应的字符。 result.append(new String(resultBytes)); return result.toString(); } /************************************************* 解密end *************************************************/ /************************************************* 生成签名、签名验证start *************************************************/ /** * @Description 生成签名 * @Author SuXingYong * @Date 2020/7/11 23:35 * @Param [content, privateKey] * @param content 待签名的数据原文 * @param privateKey 私钥字符串 * @Return java.lang.String 签名值 **/ public static String generatorSign(String content, String privateKey) { String signStr = ""; try { // 取得私钥 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKey)); // 实例化密钥工厂 RSA算法的 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 生成私钥 PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); // 实例化签名 Signature signature = Signature.getInstance(SIGN_ALGORITHMS); // 初始化签名 signature.initSign(priKey); // 签名更新 signature.update(content.getBytes()); // 生成的签名字节数组 byte[] signByteArr = signature.sign(); // 返回Base64编码的签名字符串 signStr = Base64.encode(signByteArr); } catch (Exception e) { e.printStackTrace(); log.error(e.getMessage()); } return signStr; } /** * @Description 检查签名是否合法性 * @Author SuXingYong * @Date 2020/7/11 23:35 * @Param [content, sign, publicKey] * @param content 待签名的数据原文 * @param sign 签名值 * @param publicKey 私钥 * @Return boolean 是否合法 **/ public static boolean checkSignVerify(String content, String sign, String publicKey) { boolean isOK = false; try { // 取得公钥 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(publicKey)); // 实例化密钥工厂 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 生成公钥 PublicKey pubKey = keyFactory.generatePublic(x509EncodedKeySpec); // 实例化签名 Signature signature = Signature.getInstance(SIGN_ALGORITHMS); // 签名验证初始化 signature.initVerify(pubKey); // 更新签名 signature.update(content.getBytes()); // 验证签名是否合法 isOK = signature.verify(Base64.decode(sign)); } catch (Exception e) { e.printStackTrace(); log.error(e.getMessage()); } return isOK; } /************************************************* 生成签名、签名验证end *************************************************/ }

RsaUtils.java

Base64类可以使用java自带的Base64替代:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/7465a0bce2263cbc0d8e543992cf0ce5.html