RSA非对称加密怎么实现,Java语言轻松搞定

核心概念
  • 非对称加密:使用公钥加密、私钥解密

  • 密钥对:公钥(公开)和私钥(保密)

  • 典型应用:数据加密、数字签名

Java实现代码

import javax.crypto.Cipher;
import java.security.*;
import java.util.Base64;

public class RSAExample {
    
    public static void main(String[] args) throws Exception {
        // 1. 生成密钥对
        KeyPair keyPair = generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        
        String originalMessage = "重要机密数据: 42";
        System.out.println("原始消息: " + originalMessage);
        
        // 2. 加密示例
        String encryptedMsg = encrypt(originalMessage, publicKey);
        System.out.println("加密消息: " + encryptedMsg);
        
        // 3. 解密示例
        String decryptedMsg = decrypt(encryptedMsg, privateKey);
        System.out.println("解密消息: " + decryptedMsg);
        
        // 4. 数字签名示例
        String signature = sign(originalMessage, privateKey);
        System.out.println("数字签名: " + signature);
        
        // 5. 签名验证
        boolean isValid = verify(originalMessage, signature, publicKey);
        System.out.println("签名验证: " + (isValid ? "有效" : "无效"));
    }
    
    // 生成RSA密钥对(2048位)
    public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048);
        return keyGen.generateKeyPair();
    }
    
    // RSA加密
    public static String encrypt(String plainText, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }
    
    // RSA解密
    public static String decrypt(String encryptedText, PrivateKey privateKey) throws Exception {
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return new String(cipher.doFinal(encryptedBytes));
    }
    
    // 数字签名(SHA256withRSA)
    public static String sign(String plainText, PrivateKey privateKey) throws Exception {
        Signature privateSignature = Signature.getInstance("SHA256withRSA");
        privateSignature.initSign(privateKey);
        privateSignature.update(plainText.getBytes());
        byte[] signature = privateSignature.sign();
        return Base64.getEncoder().encodeToString(signature);
    }
    
    // 签名验证
    public static boolean verify(String plainText, String signature, PublicKey publicKey) throws Exception {
        Signature publicSignature = Signature.getInstance("SHA256withRSA");
        publicSignature.initVerify(publicKey);
        publicSignature.update(plainText.getBytes());
        byte[] signatureBytes = Base64.getDecoder().decode(signature);
        return publicSignature.verify(signatureBytes);
    }
}

典型应用场景

1. 安全数据传输
// 客户端:用服务器公钥加密数据
String clientData = "用户凭证: ABC-123";
String encrypted = encrypt(clientData, serverPublicKey);

// 服务器:用自己的私钥解密
String decrypted = decrypt(encrypted, serverPrivateKey);
2. 数字签名(防篡改)
// 发送方:生成文件签名
String document = "合同条款...";
String signature = sign(document, senderPrivateKey);

// 接收方:验证签名
boolean valid = verify(document, signature, senderPublicKey);
3. 登录令牌验证
// 认证服务器生成令牌
String token = "user=admin|expiry=20231231";
String signedToken = sign(token, serverPrivateKey);

// 客户端携带令牌:token + "|" + signedToken

// 资源服务器验证
String[] parts = token.split("\\|");
boolean valid = verify(parts[0], parts[1], serverPublicKey);

关键注意事项

  1. 密钥长度:至少使用2048位(3072位更安全)

  2. 加密限制:RSA单次加密数据长度 < 密钥长度-11字节

  3. 密钥处理

    // 实际应用中应结合AES加密数据,用RSA加密AES密钥
    String aesKey = "AES-256密钥";
    String encryptedKey = encrypt(aesKey, rsaPublicKey);

  4. 密钥存储

    • 公钥:可公开发布(PEM格式)

    • 私钥:使用HSM或密钥库保护(如Java KeyStore)

  5. 填充方案:推荐RSA/ECB/OAEPWithSHA-256AndMGF1Padding

安全增强建议

  1. 定期轮换密钥(每年至少一次)

  2. 使用硬件安全模块(HSM)保护私钥

  3. 敏感操作添加时间戳防重放攻击

  4. 完整实现应包含异常处理和日志审计

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值