首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 實現 RSA 加密解密完整教學:從金鑰生成到數據加解密

     編輯:Java 相關知識

RSA 非對稱加密在 Java 中的完整實戰

RSA 是非對稱加密基石,廣泛用於數據傳輸加密、數位簽名、HTTPS/TLS。本文提供開箱即用的完整示例,涵蓋金鑰對生成、持久化、加密、解密全流程。

核心類設計:RSADemo

public class RSADemo {
    // 金鑰文件常量
    private static final String PUB_KEY_FILE = "pubkey.dat";
    private static final String PRI_KEY_FILE = "privatekey.dat";
    private static final String ENCRYPT_FILE = "encrypt.dat";
    private static final int KEY_SIZE = 1024; // 建議生產環境用 2048+
}

1. 金鑰對生成與持久化

public static void generateKey() throws Exception {
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
    kpg.initialize(KEY_SIZE);
    KeyPair kp = kpg.genKeyPair();
    
    // 序列化保存公鑰
    try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(PUB_KEY_FILE))) {
        out.writeObject(kp.getPublic());
    }
    // 序列化保存私鑰
    try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(PRI_KEY_FILE))) {
        out.writeObject(kp.getPrivate());
    }
}

關鍵點:使用 ObjectOutputStream 序列化 PublicKey/PrivateKey,實現跨會話復用。

2. 公鑰加密流程

public static void encrypt() throws Exception {
    String plainText = "Hello World!";
    
    // 讀取公鑰
    RSAPublicKey pubKey;
    try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(PUB_KEY_FILE))) {
        pubKey = (RSAPublicKey) in.readObject();
    }
    
    // 核心加密:c = m^e mod n
    BigInteger m = new BigInteger(plainText.getBytes("UTF-8"));
    BigInteger c = m.modPow(pubKey.getPublicExponent(), pubKey.getModulus());
    
    // 保存密文
    try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(ENCRYPT_FILE)))) {
        writer.write(c.toString());
    }
}

3. 私鑰解密流程

public static void decrypt() throws Exception {
    // 讀取密文
    String cText;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(ENCRYPT_FILE)))) {
        cText = reader.readLine();
    }
    BigInteger c = new BigInteger(cText);
    
    // 讀取私鑰
    RSAPrivateKey priKey;
    try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(PRI_KEY_FILE))) {
        priKey = (RSAPrivateKey) in.readObject();
    }
    
    // 核心解密:m = c^d mod n
    BigInteger m = c.modPow(priKey.getPrivateExponent(), priKey.getModulus());
    byte[] plainBytes = m.toByteArray();
    
    System.out.print("解密結果: ");
    for (byte b : plainBytes) System.out.print((char) b);
}

4. 主流程串聯

public static void main(String[] args) {
    try {
        generateKey();
        encrypt();
        decrypt();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

生產環境強化建議

項目建議
金鑰長度最小 2048 位,推薦 3072/4096
填充模式必須使用 OAEP:Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding")
大數據加密RSA 僅加密 AES 金鑰,數據用 AES-GCM
私鑰存儲PKCS#8 格式 + 加密存儲,或使用 Java KeyStore (JKS/PKCS12)
異常處理捕獲具體異常,避免吞噬 Exception

現代寫法片段

// 使用 Cipher API 替代手動 BigInteger 運算
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));

理解 RSA 數學原理固然重要,但生產代碼請優先使用成熟的 Cipher API 並遵循密碼學最佳實踐。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved