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

Java RSA密鑰對生成實戰:基於JCA標準API的完整實現

     編輯:Java 綜合教學

核心類與流程圖解

Java密碼架構(JCA)提供標準API,無需第三方庫即可完成RSA密鑰生成:

  1. KeyPairGenerator:密鑰對生成器,指定算法(RSA)與密鑰長度(1024/2048/4096)
  2. KeyPair:密鑰對容器,包含PublicKey與PrivateKey
  3. RSAPublicKey / RSAPrivateKey:RSA專用密鑰接口,提供getModulus()、getPublicExponent()等細節訪問
  4. Base64編碼:二進制密鑰轉字符串便於存儲傳輸 (Java 8+用java.util.Base64,舊版用sun.misc.BASE64Encoder)

完整工具類實現 (Java 8+ 現代寫法)

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.Base64;
import java.util.HashMap;
import java.util.Map;

public class RsaKeyGenerator {

    private static final String ALGORITHM = "RSA";
    private static final int KEY_SIZE = 2048; // 推薦2048位,1024已不安全
    private static final String PUBLIC_KEY = "RSAPublicKey";
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    /** 生成密鑰對並返回Base64編碼Map */
    public static Map<String, String> generateKeyPairBase64() throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(ALGORITHM);
        keyPairGen.initialize(KEY_SIZE, new SecureRandom()); // 顯式指定安全隨機源
        KeyPair keyPair = keyPairGen.generateKeyPair();

        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

        Map<String, String> keyMap = new HashMap<>(2);
        keyMap.put(PUBLIC_KEY, Base64.getEncoder().encodeToString(publicKey.getEncoded()));
        keyMap.put(PRIVATE_KEY, Base64.getEncoder().encodeToString(privateKey.getEncoded()));
        return keyMap;
    }

    /** 從Base64字符串恢復PublicKey對象 */
    public static PublicKey restorePublicKey(String base64PublicKey) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(base64PublicKey);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }

    /** 從Base64字符串恢復PrivateKey對象 */
    public static PrivateKey restorePrivateKey(String base64PrivateKey) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(base64PrivateKey);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePrivate(keySpec);
    }

    // 測試主方法
    public static void main(String[] args) {
        try {
            Map<String, String> keys = generateKeyPairBase64();
            System.out.println("=== Public Key (Base64) ===");
            System.out.println(keys.get(PUBLIC_KEY));
            System.out.println("\n=== Private Key (Base64) ===");
            System.out.println(keys.get(PRIVATE_KEY));

            // 驗證可恢復
            PublicKey pub = restorePublicKey(keys.get(PUBLIC_KEY));
            PrivateKey pri = restorePrivateKey(keys.get(PRIVATE_KEY));
            System.out.println("\n恢復驗證: " + (pub != null && pri != null ? "成功" : "失敗"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

關鍵技術點深度解析

環節舊寫法 (JDK 7/內部API)現代寫法 (JDK 8+ 標準API)說明
Base64編碼sun.misc.BASE64Encoder/Decoderjava.util.Base64.Encoder/Decoder內部API可能被移除,標準API穩定
隨機源默認初始化new SecureRandom()顯式指定強隨機數生成器,增強安全性
密鑰長度1024 bits2048/4096 bits1024位已被破解風險,NIST建議2048+
密鑰格式直接getEncoded()X509EncodedKeySpec / PKCS8EncodedKeySpec標準編碼格式,跨語言/平台互操作

密鑰存儲最佳實踐

  1. 私鑰加密存儲:生產環境絕不可明文存儲私鑰。使用PKCS#12或JKS密鑰庫,或通過PBE (Password-Based Encryption)加密後存文件/數據庫
  2. 公鑰分發:可制成X.509證書(.cer/.crt),或直接Base64字符串分發
  3. 密鑰輪換:建立定期輪換機制(如每90天),舊密鑰標記過期而非立即銷毀,平滑過渡

應用場景示例

  • 數字簽名:私鑰簽名 Signature.sign(),公鑰驗簽 Signature.verify() (算法: SHA256withRSA)
  • 數據加密:公鑰加密 Cipher.ENCRYPT_MODE,私鑰解密 Cipher.DECRYPT_MODE (注意:RSA僅適用短數據,長數據用AES混合加密)
  • JWT簽名:RS256算法簽發Token,資源服務器持公鑰驗證
  • HTTPS/SSL:服務器證書本質即RSA公鑰+CA簽名

安全合規提醒

⚠️ 合規提示:中國《商用密碼管理條例》要求關鍵信息基礎設施使用國產密碼算法(SM2/SM3/SM4)。涉密/關鍵系統請優先考慮BCProvider的SM2實現或國產密碼庫(JCrypt/SM2SDK),RSA僅用於國際互操作場景。

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