| 類別 | 特點 | 典型算法 |
|---|---|---|
| 對稱加密 | 同一金鑰加解密,速度快,適合大量數據 | DES、3DES、AES、PBE |
| 非對稱加密 | 公鑰加密/私鑰解密,金鑰管理靈活,速度慢 | RSA、DH |
| 訊息摘要 | 單向不可逆,驗證數據完整性 | MD5、SHA 系列 |
| 編碼轉換 | 非加密,單純格式轉換 | Base64 |
java.security、javax.crypto(位於 jre/lib/jce.jar)非加密,單純將二進位轉為可列印字串(64 字符表)。常用於 URL 參數傳遞、JSON 嵌入二進位。
public class Base64Strategy {
public String encode(String src) {
return Base64.getEncoder().encodeToString(src.getBytes(StandardCharsets.UTF_8));
}
public String decode(String src) {
return new String(Base64.getDecoder().decode(src), StandardCharsets.UTF_8);
}
}
public String md5(String src) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(src.getBytes(StandardCharsets.UTF_8));
return Hex.encodeHexString(digest); // Commons Codec
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public String sha256(String src) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] digest = md.digest(src.getBytes(StandardCharsets.UTF_8));
return Hex.encodeHexString(digest);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public class AESStrategy {
private static final String ALGO = "AES/ECB/PKCS5Padding"; // 生產建議 CBC + IV
public String encrypt(String src, String key) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
Cipher cipher = Cipher.getInstance(ALGO);
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
return Base64.getEncoder().encodeToString(cipher.doFinal(src.getBytes(StandardCharsets.UTF_8)));
}
public String decrypt(String src, String key) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
Cipher cipher = Cipher.getInstance(ALGO);
cipher.init(Cipher.DECRYPT_MODE, keySpec);
return new String(cipher.doFinal(Base64.getDecoder().decode(src)), StandardCharsets.UTF_8);
}
}
public class PBEStrategy {
public String encrypt(String src, String password) throws Exception {
SecureRandom random = new SecureRandom();
byte[] salt = random.generateSeed(8); // 鹽值
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = factory.generateSecret(keySpec);
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 1000); // 迭代 1000 次
Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
byte[] result = cipher.doFinal(src.getBytes(StandardCharsets.UTF_8));
// 實務上需將 salt 與密文一起存儲(如 Base64(salt + ciphertext))
return Base64.getEncoder().encodeToString(result);
}
}
public class RSAStrategy {
private KeyPair keyPair;
public void init(int keySize) throws Exception {
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(keySize);
keyPair = gen.generateKeyPair();
}
// 公鑰加密,私鑰解密
public String encryptByPublic(String src) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
return Base64.getEncoder().encodeToString(cipher.doFinal(src.getBytes()));
}
public String decryptByPrivate(String src) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
return new String(cipher.doFinal(Base64.getDecoder().decode(src)));
}
// 私鑰簽名,公鑰驗證
public String sign(String src) throws Exception {
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initSign(keyPair.getPrivate());
sig.update(src.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(sig.sign());
}
public boolean verify(String src, String signBase64) throws Exception {
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initVerify(keyPair.getPublic());
sig.update(src.getBytes(StandardCharsets.UTF_8));
return sig.verify(Base64.getDecoder().decode(signBase64));
}
}
public class DHStrategy {
public SecretKey agreeKey(KeyPair myPair, PublicKey otherPublic) throws Exception {
KeyAgreement ka = KeyAgreement.getInstance("DH");
ka.init(myPair.getPrivate());
ka.doPhase(otherPublic, true);
return ka.generateSecret("AES"); // 產出 AES 金鑰
}
}
結合非對稱加密與摘要算法:
| 場景 | 推薦算法 | 備註 |
|---|---|---|
| 密碼儲存 | BCrypt / PBKDF2 / Argon2 | 不可用 MD5/SHA 直連,必須加鹽+多輪迭代 |
| API 簽名驗證 | HMAC-SHA256 / RSA-SHA256 | 含 timestamp、nonce 防重放 |
| 敏感數據傳輸 | AES-GCM / ChaCha20-Poly1305 | 認證加密,同時保證機密性與完整性 |
| 長期數據加密 | RSA-2048+ / ECC P-256 | 量子抗性考慮可評估 PQC 算法 |
| 檔案完整性校驗 | SHA-256 / SHA-3 | MD5 已有碰撞風險 |
SecureRandom,不可用 Random