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

Java 六大加密技術完整實戰指南

     編輯:Java 相關知識

加密體系分類

類別特點典型算法
對稱加密同一金鑰加解密,速度快,適合大量數據DES、3DES、AES、PBE
非對稱加密公鑰加密/私鑰解密,金鑰管理靈活,速度慢RSA、DH
訊息摘要單向不可逆,驗證數據完整性MD5、SHA 系列
編碼轉換非加密,單純格式轉換Base64

常用提供者

  • JDK 內建:java.security、javax.crypto(位於 jre/lib/jce.jar)
  • BouncyCastle (BC):功能最全、支援國密算法
  • Apache Commons Codec:優雅的 Hex/Base64 工具類

六大核心技術實作

1. Base64 編碼

非加密,單純將二進位轉為可列印字串(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);
    }
}

2. 訊息摘要

MD5(已不建議用於安全場景)

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);
    }
}

SHA-256(推薦)

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);
    }
}

3. 對稱加密

AES(現代標準,推薦)

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);
    }
}

PBE(基於密碼加密,適合用戶記憶的金鑰)

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);
    }
}

4. 非對稱加密

RSA(加密/簽名雙料冠軍)

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));
    }
}

DH 密鑰協商(雙方協商對稱金鑰)

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 金鑰
    }
}

5. 數位簽名與憑證

結合非對稱加密與摘要算法:

  1. 發送方:私鑰簽名(SHA256withRSA)
  2. 接收方:公鑰驗證簽名
  3. 防竄改:簽名綁定內容,內容變動驗證失敗
  4. 防抵賴:唯有持有私鑰者能產生有效簽名
  5. 法律效力:《電子簽名法》賦予合法地位

算法選型建議

場景推薦算法備註
密碼儲存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-3MD5 已有碰撞風險

安全注意事項

  1. 不要自己設計加密協議:使用成熟庫(如 JJWT、BouncyCastle、Google Tink)
  2. 金鑰管理:生產環境金鑰應存放於 HSM/KMS,不可硬編碼
  3. 隨機數:必須使用 SecureRandom,不可用 Random
  4. 模式選擇:AES 推薦 GCM/CBC+PKCS7Padding,**禁用 ECB**
  5. 填充攻擊:PKCS#7 填充在某些場景下存在 Padding Oracle 攻擊,優先選用 GCM
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved