RSA加密、解密、签名、验签的原理及方法
https://www.cnblogs.com/pcheng/p/9629621.html
package com.zhhs.project.yazq.app.utils; import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import java.io.*; import java.security.*; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; /** * @Date 2015-02-08 11:25:21 * <p> * rsa 加密工具 【非对称加密】 */ public class RSAUtils { /** * 加密算法RSA */ private static final String KEY_ALGORITHM = "RSA"; /** * 签名算法 */ private static final String SIGNATURE_ALGORITHM = "MD5withRSA"; /** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 244; /** * RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 256; /** * 创建私钥公钥 */ public static void generateSecretKey(String fileAbsolutePath) throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(2048); KeyPair keyPair = keyPairGen.generateKeyPair(); Key publicKey = (Key) keyPair.getPublic(); Key privateKey = (Key) keyPair.getPrivate(); StringBuilder str = new StringBuilder(); str.append("publicKey:\n").append(encode(publicKey.getEncoded())).append("\n"); str.append("privateKey:\n").append(encode(privateKey.getEncoded())).append("\n"); try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(fileAbsolutePath)))) { writer.write(str.toString()); writer.flush(); System.out.println("生成完成!"); } catch (IOException e) { e.printStackTrace(); } } /** * <p> * 用私钥对信息生成数字签名 * </p> * * @param data 已加密数据 * @param privateKey 私钥(BASE64编码) * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { byte[] keyBytes = decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(privateK); signature.update(data); return encode(signature.sign()); } /** * <p> * 校验数字签名 * </p> * * @param data 已加密数据 * @param publicKey 公钥(BASE64编码) * @param sign 数字签名 * @return * @throws Exception */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { byte[] keyBytes = decode(publicKey); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PublicKey publicK = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(publicK); signature.update(data); return signature.verify(decode(sign)); } /** * <P> * 私钥解密 * </p> * * @param str 已加密数据 * @param privateKey 私钥(BASE64编码) * @return * @throws Exception */ public static String decryptByPrivateKey(String str, String privateKey) throws Exception { byte[] encryptedData = decode(str); byte[] keyBytes = decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return new String(decryptedData); } /** * <p> * 公钥解密 * </p> * * @param str 已加密数据 * @param publicKey 公钥(BASE64编码) * @return * @throws Exception */ public static String decryptByPublicKey(String str, String publicKey) throws Exception { byte[] encryptedData = decode(str); byte[] keyBytes = decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return new String(decryptedData); } /** * <p> * 公钥加密 * </p> * * @param str 源数据 * @param publicKey 公钥(BASE64编码) * @return * @throws Exception */ public static String encryptByPublicKey(String str, String publicKey) throws Exception { byte[] data = str.getBytes(); byte[] keyBytes = decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); byte[] encryptedData1 = encryptedData; String encode = encode(encryptedData1); return encode; } /** * <p> * 私钥加密 * </p> * * @param str 源数据 * @param privateKey 私钥(BASE64编码) * @return * @throws Exception */ public static String encryptByPrivateKey(String str, String privateKey) throws Exception { //获取str的byte byte[] data = str.getBytes(); byte[] keyBytes = decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); //进行Base64加密 byte[] encryptedData1 = encryptedData; String encode = encode(encryptedData1); return encode; } /** * base64 编码 * * @param bytes * @return * @throws Exception */ public static String encode(byte[] bytes) throws Exception { return new String(Base64.encodeBase64(bytes)); } /** * base64 解码 * * @param base64 * @return * @throws Exception */ public static byte[] decode(String base64) throws Exception { return Base64.decodeBase64(base64.getBytes()); } /** * 将 2 进制转换成 16 进制字符串 */ private static String byte2Hex(byte buf[]) { StringBuilder sb = new StringBuilder(); for (byte aBuf : buf) { String hex = Integer.toHexString(aBuf & 0xFF); if (hex.length() == 1) { hex = '0' + hex; } sb.append(hex.toUpperCase()); } return sb.toString(); } /** * 将 16 进制字符串转换为 2 进制 */ private static byte[] hex2Byte(String hexStr) { if (hexStr.length() < 1) { return null; } byte[] result = new byte[hexStr.length() / 2]; for (int i = 0; i < hexStr.length() / 2; i++) { int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16); int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16); result[i] = (byte) (high * 16 + low); } return result; } /** * 公钥加密转成16进制 */ public static String encryptByPublicKeyToHex(String str, String publicKey) throws Exception { byte[] data = str.getBytes(); byte[] keyBytes = decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); String hex = byte2Hex(encryptedData); return hex; } /** * 16进制密文解密 */ public static String decryptHexStrByPrivateKey(String str, String privateKey) throws Exception { byte[] encryptedData = hex2Byte(str); byte[] keyBytes = decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return new String(decryptedData); } public static void main(String[] args) throws Exception { generateSecretKey("D:\\key.txt"); } }
rsa:
privateKey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgE..........
调用
String logName = RSAUtils.decryptByPrivateKey(loginName, privateKey);
前端调用
/*公钥*/
const publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwOuMADLF4Wj44..........";
/*公钥加密*/
function encryption(text) {
var encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);
var encryptData = encrypt.encrypt(text);
return strToHexCharCode(encryptData);
}
/*字符串转16进制*/
function strToHexCharCode(str) {
if (str === "") {
return "";
}
var hexCharCode = [];
for (var i = 0; i < str.length; i++) {
hexCharCode.push((str.charCodeAt(i)).toString(16));
}
return hexCharCode.join("");
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本