行业资讯
📅 2026/7/23 19:50:24
Java实现RSA密钥生成、加密解密、加签验签
一、RSA算法核心概述RSA是目前应用最广泛的非对称加密算法核心特征是使用一对密钥公钥、私钥完成数据交互两个密钥数学关联但无法由其中一个推导出另一个彻底解决对称加密密钥传输的安全难题。1.1 核心特性公钥Public Key公开透明可对外分发主要用于加密数据、验证签名私钥Private Key绝对保密仅持有者留存主要用于解密数据、生成签名核心逻辑公钥加密、私钥解密保证数据保密性私钥加签、公钥验签保证数据完整性、真实性、不可抵赖性1.2 基础数学原理极简易懂RSA的安全性基于大整数质因数分解难题核心数学流程如下随机选取两个不相等的大质数p、q计算模数 N p * q计算欧拉函数 φ(N) (p-1)*(q-1)选取公钥指数e常用65537满足1eφ(N)且与φ(N)互质计算私钥指数de关于φ(N)的模逆元满足 e*d ≡ 1 (mod φ(N))最终公钥(N,e)私钥(N,d)。加密公式$$C M^e \bmod N$$ M为明文C为密文解密公式$$M C^d \bmod N$$二、RSA核心功能场景区分很多开发者容易混淆加密解密、加签验签两者的使用场景、密钥用法、核心目的完全不同功能密钥使用规则核心目的适用场景加密/解密公钥加密私钥解密保证数据保密性数据仅私钥持有者可读取传输隐私数据密码、手机号、密钥加签/验签私钥加签公钥验签保证数据完整性、真实性、不可抵赖接口请求、文件校验、交易确认三、Java实现RSA完整流程Java通过java.security、javax.crypto原生包实现RSA无需引入第三方依赖本文实现密钥对生成、公钥加密、私钥解密、私钥加签、公钥验签全流程并逐行解析原理。3.1 前置工具说明密钥算法RSA加密填充方式RSA/ECB/PKCS1Padding通用标准兼容绝大多数场景签名算法SHA256withRSASHA256哈希RSA加密签名安全性高于MD5密钥长度2048位1024位已不安全4096位性能较低2048位为最优选择3.2 完整可运行代码import javax.crypto.Cipher; import java.security.*; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; /** * RSA非对称加密工具类 * 功能密钥对生成、公钥加密、私钥解密、私钥加签、公钥验签 */ public class RSAUtil { // 密钥算法 private static final String RSA_ALGORITHM RSA; // 加密算法填充模式 private static final String CIPHER_ALGORITHM RSA/ECB/PKCS1Padding; // 签名算法 private static final String SIGN_ALGORITHM SHA256withRSA; // 密钥长度2048位 private static final int KEY_SIZE 2048; /** * 1. 生成RSA公私钥对 */ public static KeyPair generateRSAKeyPair() throws Exception { // 获取密钥对生成器实例 KeyPairGenerator keyPairGenerator KeyPairGenerator.getInstance(RSA_ALGORITHM); // 初始化密钥长度 keyPairGenerator.initialize(KEY_SIZE); // 生成密钥对 return keyPairGenerator.generateKeyPair(); } /** * 2. 公钥加密 * param data 原始明文数据 * param publicKey 公钥 * return Base64编码后的密文 */ public static String encrypt(String data, PublicKey publicKey) throws Exception { // 获取加密器实例 Cipher cipher Cipher.getInstance(CIPHER_ALGORITHM); // 初始化加密器为加密模式 cipher.init(Cipher.ENCRYPT_MODE, publicKey); // 执行加密 byte[] encryptBytes cipher.doFinal(data.getBytes()); // 密文Base64编码方便传输存储 return Base64.getEncoder().encodeToString(encryptBytes); } /** * 3. 私钥解密 * param encryptData Base64编码的密文 * param privateKey 私钥 * return 解密后的明文 */ public static String decrypt(String encryptData, PrivateKey privateKey) throws Exception { // 获取解密器实例 Cipher cipher Cipher.getInstance(CIPHER_ALGORITHM); // 初始化解密器为解密模式 cipher.init(Cipher.DECRYPT_MODE, privateKey); // Base64解码密文 byte[] encryptBytes Base64.getDecoder().decode(encryptData); // 执行解密 byte[] decryptBytes cipher.doFinal(encryptBytes); return new String(decryptBytes); } /** * 4. 私钥加签生成数字签名 * param data 原始数据 * param privateKey 私钥 * return Base64编码的签名 */ public static String sign(String data, PrivateKey privateKey) throws Exception { // 获取签名对象 Signature signature Signature.getInstance(SIGN_ALGORITHM); // 初始化签名对象私钥签名 signature.initSign(privateKey); // 传入待签名数据 signature.update(data.getBytes()); // 生成签名并Base64编码 byte[] signBytes signature.sign(); return Base64.getEncoder().encodeToString(signBytes); } /** * 5. 公钥验签验证数据合法性 * param data 原始数据 * param signStr 签名字符串 * param publicKey 公钥 * return 验签结果 true合法 false篡改/伪造 */ public static boolean verify(String data, String signStr, PublicKey publicKey) throws Exception { // 获取签名验证对象 Signature signature Signature.getInstance(SIGN_ALGORITHM); // 初始化验签对象公钥验签 signature.initVerify(publicKey); // 传入待验证原始数据 signature.update(data.getBytes()); // Base64解码签名 byte[] signBytes Base64.getDecoder().decode(signStr); // 执行验签 return signature.verify(signBytes); } // 测试主方法 public static void main(String[] args) throws Exception { // 1. 生成密钥对 KeyPair keyPair generateRSAKeyPair(); PublicKey publicKey keyPair.getPublic(); PrivateKey privateKey keyPair.getPrivate(); System.out.println(公钥 Base64.getEncoder().encodeToString(publicKey.getEncoded())); System.out.println(私钥 Base64.getEncoder().encodeToString(privateKey.getEncoded())); // 待测试明文 String plainText Java RSA 加密解密加签验签测试123456; System.out.println(\n原始明文 plainText); // 2. 公钥加密 String encryptStr encrypt(plainText, publicKey); System.out.println(加密密文 encryptStr); // 3. 私钥解密 String decryptStr decrypt(encryptStr, privateKey); System.out.println(解密明文 decryptStr); // 4. 私钥加签 String signStr sign(plainText, privateKey); System.out.println(数据签名 signStr); // 5. 公钥验签正常数据 boolean verifyResult1 verify(plainText, signStr, publicKey); System.out.println(正常数据验签结果 verifyResult1); // 6. 篡改数据后验签模拟数据被篡改 String errorText 篡改后的RSA测试数据; boolean verifyResult2 verify(errorText, signStr, publicKey); System.out.println(篡改数据验签结果 verifyResult2); } }四、逐步骤原理与作用详解4.1 RSA密钥对生成核心基础执行代码KeyPairGenerator keyPairGenerator KeyPairGenerator.getInstance(RSA_ALGORITHM);keyPairGenerator.initialize(KEY_SIZE);KeyPair keyPair keyPairGenerator.generateKeyPair();原理与作用获取密钥生成器通过Java安全工厂获取RSA算法专用密钥生成器绑定底层加密算法实现初始化密钥长度2048位指定了模数N的长度长度越长破解难度越高但加密解密速度越慢2048位是安全与性能的平衡点生成密钥对程序自动执行前文数学逻辑选取大质数、计算N、φ(N)、e、d生成配对的公钥和私钥两个密钥绑定唯一数学关系。关键特点每次生成的密钥对均不重复私钥绝对无法通过公钥逆向推导。4.2 公钥加密保障数据保密性核心流程获取加密器 → 初始化为加密模式 → 明文转字节数组 → 执行RSA加密 → Base64编码输出原理与作用Cipher加密器Java加密核心类RSA/ECB/PKCS1Padding是标准填充模式解决原始RSA无法加密短数据、数据对齐问题兼容所有主流系统加密模式初始化Cipher.ENCRYPT_MODE绑定公钥确定加密逻辑为「公钥加密」加密运算底层执行 $$C M^e \bmod N$$ 公式将明文转为不可直接读取的密文Base64编码加密后的密文是二进制字节数组Base64编码后转为字符串方便HTTP传输、日志打印、数据库存储。使用意义任何人都可以用公钥加密数据但只有对应的私钥能解密彻底防止传输过程中数据泄露。4.3 私钥解密还原原始数据核心流程获取解密器 → 初始化为解密模式 → Base64解码密文 → 执行解密 → 转明文字符串原理与作用解密绑定私钥Cipher.DECRYPT_MODE绑定私钥只有持有对应私钥的服务才能触发解密逻辑解密运算底层执行 $$M C^d \bmod N$$ 公式通过私钥指数d还原明文数据还原将解密后的字节数组转为字符串得到原始业务数据。核心约束公钥加密的密文只能由对应私钥解密其他私钥无法破解保障数据专属保密性。4.4 私钥加签生成数字签名核心流程获取签名工具 → 私钥初始化签名器 → 传入原始数据 → 生成签名 → Base64编码原理与作用签名的本质是对数据的哈希值进行私钥加密区别于直接加密原始数据。SHA256哈希先对原始数据进行SHA256哈希运算生成固定长度的哈希值数据哪怕修改1个字符哈希值会完全改变保障数据完整性私钥加密哈希值用私钥对哈希值加密生成签名因为私钥唯一签名具有唯一性、不可伪造性签名作用证明数据由私钥持有者发送且数据未被篡改、不可抵赖。4.5 公钥验签校验数据合法性核心流程获取验签工具 → 公钥初始化验签器 → 传入原始数据 → 解码签名 → 校验匹配性原理与作用公钥解密签名用公钥解密签名得到原始数据的哈希值二次哈希比对对接收的原始数据重新计算SHA256哈希值与解密出的哈希值对比校验结果判定一致则说明数据未篡改、签名合法不一致则说明数据被修改或签名伪造。核心价值解决数据篡改、身份伪造、交易抵赖问题是接口鉴权、数据校验的核心方案。五、常见问题与注意事项5.1 加密数据长度限制RSA单次加密数据长度有限制密钥长度/8 - 112048位密钥最大加密245字节数据。如需加密大文本需使用「RSAAES」混合加密RSA加密AES密钥AES加密原始数据。5.2 密钥格式规范公钥默认X509编码格式对外分发私钥默认PKCS8编码格式严禁对外泄露存储传输密钥必须Base64编码避免格式错乱。5.3 算法安全性禁止使用1024位密钥已被暴力破解禁止使用MD5withRSA签名MD5哈希碰撞漏洞统一使用SHA256withRSA必须携带填充模式避免使用无填充原始RSA。六、总结1.RSA密钥对基于大整数分解难题生成公钥公开、私钥保密是所有功能的基础2.加密解密公钥加密、私钥解密核心解决数据保密性防止数据泄露3.加签验签私钥加签、公钥验签核心解决数据完整性、真实性、不可抵赖性4. Java原生API可完美实现RSA全功能无需第三方依赖2048位密钥SHA256withRSA是生产环境最优组合。