Java密碼架構(JCA)提供標準API,無需第三方庫即可完成RSA密鑰生成:
getModulus()、getPublicExponent()等細節訪問java.util.Base64,舊版用sun.misc.BASE64Encoder)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/Decoder | java.util.Base64.Encoder/Decoder | 內部API可能被移除,標準API穩定 |
| 隨機源 | 默認初始化 | new SecureRandom() | 顯式指定強隨機數生成器,增強安全性 |
| 密鑰長度 | 1024 bits | 2048/4096 bits | 1024位已被破解風險,NIST建議2048+ |
| 密鑰格式 | 直接getEncoded() | X509EncodedKeySpec / PKCS8EncodedKeySpec | 標準編碼格式,跨語言/平台互操作 |
PKCS#12或JKS密鑰庫,或通過PBE (Password-Based Encryption)加密後存文件/數據庫.cer/.crt),或直接Base64字符串分發Signature.sign(),公鑰驗簽 Signature.verify() (算法: SHA256withRSA)Cipher.ENCRYPT_MODE,私鑰解密 Cipher.DECRYPT_MODE (注意:RSA僅適用短數據,長數據用AES混合加密)⚠️ 合規提示:中國《商用密碼管理條例》要求關鍵信息基礎設施使用國產密碼算法(SM2/SM3/SM4)。涉密/關鍵系統請優先考慮
BCProvider的SM2實現或國產密碼庫(JCrypt/SM2SDK),RSA僅用於國際互操作場景。