最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java中常用的幾種加密方式舉例詳解

 更新時(shí)間:2026年03月26日 09:37:27   作者:heartbeat..  
加密是以某種特殊的算法改變?cè)械男畔?shù)據(jù),使得未授權(quán)的用戶即使獲得了已加密的信息,但因不知解密的方法,仍然無法了解信息的內(nèi)容,這篇文章主要介紹了java中常用的幾種加密方式的相關(guān)資料,需要的朋友可以參考下

一、介紹

在 Java 開發(fā)中,加密方式主要分為 對(duì)稱加密、非對(duì)稱加密、哈希算法(摘要算法) 三大類,各自有不同的應(yīng)用場(chǎng)景(如數(shù)據(jù)傳輸、存儲(chǔ)加密、簽名驗(yàn)證等)。

二、哈希算法(摘要算法)

特點(diǎn):

  • 不可逆(無法從摘要反推原始數(shù)據(jù));
  • 相同輸入必然得到相同輸出,不同輸入大概率得到不同輸出(抗碰撞);
  • 輸出長(zhǎng)度固定(與輸入長(zhǎng)度無關(guān));
  • 主要用于 數(shù)據(jù)完整性校驗(yàn)(如文件校驗(yàn))、密碼存儲(chǔ)(如用戶密碼加密存儲(chǔ))。

常用算法及實(shí)現(xiàn):

1. MD5(Message-Digest Algorithm 5)

  • 輸出長(zhǎng)度:128 位(16 字節(jié),通常轉(zhuǎn) 32 位十六進(jìn)制字符串);
  • 特點(diǎn):速度快,但安全性較低(已被破解,存在碰撞風(fēng)險(xiǎn));
  • 適用場(chǎng)景:非敏感數(shù)據(jù)的完整性校驗(yàn)(如文件校驗(yàn)),不推薦用于密碼存儲(chǔ)。
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Utils {
    public static String md5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(input.getBytes()); // 生成摘要字節(jié)數(shù)組
            // 轉(zhuǎn)16進(jìn)制字符串
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(String.format("%02x", b)); // 02x確保不足兩位補(bǔ)0
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5算法不存在", e);
        }
    }
    public static void main(String[] args) {
        System.out.println(md5("123456")); // 輸出:e10adc3949ba59abbe56e057f20f883e
    }
}

2. SHA 系列(Secure Hash Algorithm)

  • 包括 SHA-1(160 位)、SHA-256(256 位)、SHA-512(512 位)等;
  • 特點(diǎn):安全性比 MD5 高,SHA-256/SHA-512 抗碰撞性強(qiáng),速度略慢于 MD5;
  • 適用場(chǎng)景:敏感數(shù)據(jù)的完整性校驗(yàn)、密碼存儲(chǔ)(推薦 SHA-256 + 鹽值)。
public class SHA256Utils {
    public static String sha256(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] digest = md.digest(input.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("SHA-256算法不存在", e);
        }
    }
    public static void main(String[] args) {
        System.out.println(sha256("123456")); // 輸出:8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c9
    }
}

3. 加鹽哈希(Salted Hash)

  • 問題:純哈希算法存在 “彩虹表破解” 風(fēng)險(xiǎn)(通過預(yù)計(jì)算的哈希值反查原始密碼);
  • 解決:給原始數(shù)據(jù)添加 隨機(jī)鹽值(Salt) 后再哈希,鹽值需與哈希結(jié)果一起存儲(chǔ);
  • 推薦方案:使用 PBKDF2、BCrypt、Argon2(Java 需引入第三方庫如 spring-security-crypto)。
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class BCryptUtils {
    private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    // 加密(自動(dòng)生成鹽值)
    public static String encrypt(String password) {
        return encoder.encode(password);
    }
    // 校驗(yàn)(自動(dòng)提取鹽值比對(duì))
    public static boolean verify(String password, String encryptedPassword) {
        return encoder.matches(password, encryptedPassword);
    }
    public static void main(String[] args) {
        String pwd = "123456";
        String encrypted = encrypt(pwd);
        System.out.println("加密后:" + encrypted); // 格式如 $2a$10$xxx...(包含鹽值)
        System.out.println("校驗(yàn)結(jié)果:" + verify(pwd, encrypted)); // true
    }
}

所引入的依賴(Maven):

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-crypto</artifactId>
    <version>5.7.3</version>
</dependency>

三、對(duì)稱加密

特點(diǎn):

  • 加密和解密使用 同一個(gè)密鑰(對(duì)稱密鑰);
  • 速度快、效率高,適合 大量數(shù)據(jù)加密(如文件加密、數(shù)據(jù)庫字段加密);
  • 缺點(diǎn):密鑰傳輸和存儲(chǔ)風(fēng)險(xiǎn)高(需安全通道傳輸密鑰)。

常用算法及實(shí)現(xiàn):

1. AES(Advanced Encryption Standard)

  • 替代 DES 的標(biāo)準(zhǔn)算法,安全性高、速度快;
  • 密鑰長(zhǎng)度:128 位(默認(rèn))、192 位、256 位(需 JCE 無限制權(quán)限文件);
  • 模式:ECB(不推薦,無 IV)、CBC(需 IV 向量,推薦)、GCM(帶認(rèn)證,更安全);
  • 填充方式:PKCS5Padding(常用)。
public class AESUtils {
    // 密鑰(16字節(jié)=128位,24字節(jié)=192位,32字節(jié)=256位)
    private static final String KEY = "1234567890abcdef"; // 16字節(jié)
    // IV向量(CBC模式必需,16字節(jié),需與密鑰長(zhǎng)度一致)
    private static final String IV = "abcdef9012345678";
    // 算法/模式/填充
    private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
    // 加密
    public static String encrypt(String input) {
        try {
            SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes(), "AES");
            IvParameterSpec ivSpec = new IvParameterSpec(IV.getBytes());
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
            byte[] encrypted = cipher.doFinal(input.getBytes());
            return Base64.getEncoder().encodeToString(encrypted); // 轉(zhuǎn)Base64方便存儲(chǔ)傳輸
        } catch (Exception e) {
            throw new RuntimeException("AES加密失敗", e);
        }
    }
    // 解密
    public static String decrypt(String encryptedInput) {
        try {
            SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes(), "AES");
            IvParameterSpec ivSpec = new IvParameterSpec(IV.getBytes());
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            byte[] encrypted = Base64.getDecoder().decode(encryptedInput);
            byte[] decrypted = cipher.doFinal(encrypted);
            return new String(decrypted);
        } catch (Exception e) {
            throw new RuntimeException("AES解密失敗", e);
        }
    }
    public static void main(String[] args) {
        String input = "Hello AES!";
        String encrypted = encrypt(input);
        System.out.println("加密后:" + encrypted);
        String decrypted = decrypt(encrypted);
        System.out.println("解密后:" + decrypted); // Hello AES!
    }
}

2. DES / 3DES

  • DES:密鑰長(zhǎng)度 56 位,安全性低,已淘汰;
  • 3DES:使用 3 個(gè) DES 密鑰(168 位),兼容性強(qiáng),但速度慢;
  • 推薦優(yōu)先使用 AES。

四、非對(duì)稱加密

特點(diǎn):

  • 生成一對(duì)密鑰:公鑰(公開)私鑰(保密);
  • 公鑰加密的數(shù)據(jù)只能用私鑰解密,私鑰加密的數(shù)據(jù)只能用公鑰解密;
  • 速度慢、效率低,適合 小量數(shù)據(jù)加密(如對(duì)稱密鑰傳輸、數(shù)字簽名);
  • 優(yōu)點(diǎn):無需安全通道傳輸密鑰(公鑰可公開)。

常用算法及實(shí)現(xiàn):

1. RSA

  • 應(yīng)用最廣泛的非對(duì)稱加密算法;
  • 密鑰長(zhǎng)度:1024 位(安全性不足)、2048 位(推薦)、4096 位(更安全但速度慢);
  • 適用場(chǎng)景:密鑰交換(如 AES 密鑰用 RSA 加密傳輸)、數(shù)字簽名、小數(shù)據(jù)加密。
public class RSAUtils {
    // 密鑰對(duì)(實(shí)際開發(fā)中需提前生成并存儲(chǔ),不硬編碼)
    private static KeyPair keyPair;
    static {
        try {
            // 生成RSA密鑰對(duì)(2048位)
            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
            generator.initialize(2048);
            keyPair = generator.generateKeyPair();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("RSA密鑰對(duì)生成失敗", e);
        }
    }
    // 獲取公鑰(Base64編碼)
    public static String getPublicKey() {
        return Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
    }
    // 獲取私鑰(Base64編碼)
    public static String getPrivateKey() {
        return Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
    }
    // 公鑰加密
    public static String encryptByPublicKey(String input, String publicKeyStr) {
        try {
            // 解碼公鑰
            byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyStr);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(keySpec);
            // 加密(RSA加密長(zhǎng)度有限制,2048位密鑰最多加密245字節(jié))
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] encrypted = cipher.doFinal(input.getBytes());
            return Base64.getEncoder().encodeToString(encrypted);
        } catch (Exception e) {
            throw new RuntimeException("RSA公鑰加密失敗", e);
        }
    }
    // 私鑰解密
    public static String decryptByPrivateKey(String encryptedInput, String privateKeyStr) {
        try {
            // 解碼私鑰
            byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyStr);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
            // 解密
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] encrypted = Base64.getDecoder().decode(encryptedInput);
            byte[] decrypted = cipher.doFinal(encrypted);
            return new String(decrypted);
        } catch (Exception e) {
            throw new RuntimeException("RSA私鑰解密失敗", e);
        }
    }
    public static void main(String[] args) {
        String input = "AES密鑰1234567890abcdef"; // 小數(shù)據(jù)示例
        String publicKey = getPublicKey();
        String privateKey = getPrivateKey();
        System.out.println("公鑰:" + publicKey);
        System.out.println("私鑰:" + privateKey);
        String encrypted = encryptByPublicKey(input, publicKey);
        System.out.println("公鑰加密后:" + encrypted);
        String decrypted = decryptByPrivateKey(encrypted, privateKey);
        System.out.println("私鑰解密后:" + decrypted); // AES密鑰1234567890abcdef
    }
}

2. ECC(Elliptic Curve Cryptography)

  • 基于橢圓曲線數(shù)學(xué),相同安全性下,密鑰長(zhǎng)度遠(yuǎn)小于 RSA(如 256 位 ECC ≈ 3072 位 RSA);
  • 速度快、占用資源少,適合移動(dòng)設(shè)備、物聯(lián)網(wǎng)等場(chǎng)景;
  • Java 支持(需 JDK 1.7+),但使用較少,推薦在資源受限場(chǎng)景使用。

五、數(shù)字簽名(非對(duì)稱加密的延伸)

特點(diǎn):

  • 用于 身份認(rèn)證數(shù)據(jù)完整性校驗(yàn)(防止數(shù)據(jù)篡改和偽造);
  • 原理:發(fā)送方用 私鑰 對(duì)數(shù)據(jù)摘要簽名,接收方用 公鑰 驗(yàn)證簽名。

常用算法:RSA-SHA256、ECDSA

public class SignatureUtils {
    private static final String ALGORITHM = "SHA256withRSA"; // RSA+SHA256簽名
    // 私鑰簽名
    public static String sign(String data, String privateKeyStr) {
        try {
            byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyStr);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
            Signature signature = Signature.getInstance(ALGORITHM);
            signature.initSign(privateKey);
            signature.update(data.getBytes());
            byte[] signBytes = signature.sign();
            return Base64.getEncoder().encodeToString(signBytes);
        } catch (Exception e) {
            throw new RuntimeException("簽名失敗", e);
        }
    }
    // 公鑰驗(yàn)簽
    public static boolean verify(String data, String signStr, String publicKeyStr) {
        try {
            byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyStr);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(keySpec);
            Signature signature = Signature.getInstance(ALGORITHM);
            signature.initVerify(publicKey);
            signature.update(data.getBytes());
            byte[] signBytes = Base64.getDecoder().decode(signStr);
            return signature.verify(signBytes);
        } catch (Exception e) {
            throw new RuntimeException("驗(yàn)簽失敗", e);
        }
    }
    public static void main(String[] args) {
        String data = "需要簽名的數(shù)據(jù)";
        String privateKey = RSAUtils.getPrivateKey(); // 復(fù)用RSA密鑰對(duì)
        String publicKey = RSAUtils.getPublicKey();
        String sign = sign(data, privateKey);
        System.out.println("簽名:" + sign);
        boolean verifyResult = verify(data, sign, publicKey);
        System.out.println("驗(yàn)簽結(jié)果:" + verifyResult); // true
        // 篡改數(shù)據(jù)后驗(yàn)簽
        boolean fakeVerify = verify(data + "篡改", sign, publicKey);
        System.out.println("篡改后驗(yàn)簽結(jié)果:" + fakeVerify); // false
    }
}

六、常用加密方式選型建議

實(shí)際業(yè)務(wù)場(chǎng)景推薦加密方式使用原因
用戶密碼存儲(chǔ)BCrypt/PBKDF2不可逆、加鹽、防彩虹表破解
數(shù)據(jù)庫敏感字段(手機(jī)號(hào) / 身份證)AES-256-CBC/GCM可逆、速度快、適合短文本
大文件加密(合同 / 報(bào)表)AES-256-GCM速度快、帶認(rèn)證、防篡改
客戶端 - 服務(wù)器密鑰傳輸RSA-2048公鑰公開、私鑰保密、無需安全通道
第三方接口調(diào)用(防篡改 / 身份認(rèn)證)RSA-SHA256 數(shù)字簽名驗(yàn)證身份、防止數(shù)據(jù)篡改和重放攻擊
數(shù)據(jù)完整性校驗(yàn)(文件校驗(yàn))SHA-256不可逆、相同輸入固定輸出

七、注意

  1. 密鑰管理:避免硬編碼密鑰,使用配置中心、密鑰倉(cāng)庫(如 Vault)存儲(chǔ);
  2. 算法選擇:淘汰 MD5、DES、RSA-1024 等弱算法,優(yōu)先選擇 AES-256、RSA-2048+、SHA-256+;
  3. 填充和模式:AES 避免使用 ECB 模式,推薦 CBC(需隨機(jī) IV)或 GCM(帶認(rèn)證);
  4. 鹽值:密碼存儲(chǔ)必須加鹽,鹽值需隨機(jī)且唯一(如 BCrypt 自動(dòng)生成);
  5. 權(quán)限:AES-256 需 JCE 無限制權(quán)限文件(JDK 8u161+ 默認(rèn)開啟)。

八、補(bǔ)充

1.什么是碰撞風(fēng)險(xiǎn)?

兩個(gè)不同的輸入數(shù)據(jù)(明文),經(jīng)過加密 / 哈希計(jì)算后,得到了相同的輸出結(jié)果(密文 / 摘要) —— 這種 “不同輸入→相同輸出” 的現(xiàn)象被稱為 “哈希碰撞”,而碰撞風(fēng)險(xiǎn)就是這種現(xiàn)象發(fā)生的概率及帶來的安全隱患。

舉個(gè)簡(jiǎn)單的例子:

哈希算法就像一臺(tái) “壓縮機(jī)器”,無論輸入的是一張 10GB 的電影、一段文字,還是一個(gè)數(shù)字,都會(huì)被壓縮成固定長(zhǎng)度的 “壓縮包”(摘要)。正常情況下,不同輸入應(yīng)該對(duì)應(yīng)不同壓縮包,但如果出現(xiàn) “兩個(gè)完全不同的文件,壓縮后得到一模一樣的壓縮包”,這就是 “碰撞”;而 “碰撞風(fēng)險(xiǎn)” 就是你擔(dān)心這種情況發(fā)生的概率,以及如果發(fā)生會(huì)造成什么問題。

本質(zhì):數(shù)學(xué)底層原因:“鴿巢原理”

哈希算法的輸出長(zhǎng)度是固定的(比如 MD5 輸出 128 位,SHA-256 輸出 256 位),而輸入數(shù)據(jù)的可能性是無限的(比如任意長(zhǎng)度的字符串、文件)。

這就像:用 100 個(gè)鴿巢(固定輸出)容納無限多的鴿子(輸入數(shù)據(jù))—— 無論鴿巢再多,最終必然會(huì)有 “多只鴿子擠同一個(gè)鴿巢” 的情況,這就是數(shù)學(xué)上的 “鴿巢原理”,也是碰撞風(fēng)險(xiǎn)存在的根本原因。

常見場(chǎng)景舉例:

數(shù)字簽名場(chǎng)景(非對(duì)稱加密 + 哈希)

數(shù)字簽名的核心是 “用私鑰對(duì)數(shù)據(jù)摘要簽名,公鑰驗(yàn)簽”:

  • 若哈希算法存在碰撞風(fēng)險(xiǎn),攻擊者可找到兩個(gè)不同數(shù)據(jù)(比如 “轉(zhuǎn)賬 0.01 元” 和 “轉(zhuǎn)賬 10000 元”),其摘要相同;
  • 攻擊者誘導(dǎo)用戶對(duì) “轉(zhuǎn)賬 0.01元” 簽名,然后將簽名用于 “轉(zhuǎn)賬 10000 元” 的請(qǐng)求中,服務(wù)端驗(yàn)簽時(shí)因摘要相同而通過,造成用戶財(cái)產(chǎn)損失。

2.什么是鹽值?

鹽值(Salt)是一串隨機(jī)生成、與原始數(shù)據(jù)(如密碼)結(jié)合后再進(jìn)行哈希計(jì)算的字符串—— 它就像烹飪時(shí)加的 “調(diào)味料”,相同的食材(原始密碼)加不同的 “調(diào)味料”(鹽值),會(huì)得到完全不同的 “成品”(哈希摘要)。

舉個(gè)例子:

用戶注冊(cè)(加密存儲(chǔ))

  1. 用戶輸入明文密碼:123456aB!
  2. 系統(tǒng)生成隨機(jī)鹽值:f8d2e1c3b4a59607(16 字節(jié));
  3. 計(jì)算哈希:SHA-256(密碼 + 鹽值) → 得到摘要 8d969eef...;
  4. 存儲(chǔ)結(jié)果:將 “鹽值 + 哈希摘要” 一起存入數(shù)據(jù)庫(如拼接為 f8d2e1c3b4a59607:8d969eef...)。

常見誤區(qū):

  1. 鹽值需要保密?→ 可以不需要,鹽值的作用是 “破壞哈希固定性”,而非 “加密”,必須明文存儲(chǔ)才能校驗(yàn);
  2. 鹽值可以重復(fù)使用?→ 不推薦,同一系統(tǒng)中鹽值重復(fù)會(huì)降低安全性,建議每個(gè)用戶 / 每次修改密碼都生成新鹽值;
  3. 用用戶 ID、手機(jī)號(hào)當(dāng)鹽值?→ 不推薦,這類值可預(yù)測(cè),攻擊者可針對(duì)特定用戶生成定制彩虹表,破解難度大幅降低;
  4. 鹽值越長(zhǎng)越好?→ 不是,16 字節(jié)(128 位)已足夠安全,過長(zhǎng)的鹽值會(huì)增加存儲(chǔ)和計(jì)算成本,性價(jià)比極低。

使用原則:鹽值必須 “隨機(jī)、唯一、足夠長(zhǎng)”,且明文存儲(chǔ)。

簡(jiǎn)單場(chǎng)景:可手動(dòng)用 SecureRandom 生成鹽值,搭配 SHA-256 使用;

實(shí)際開發(fā)場(chǎng)景:優(yōu)先使用 BCrypt、PBKDF2 等自動(dòng)加鹽算法,無需關(guān)注鹽值的生成和存儲(chǔ),安全性更高、使用更高效。

3.什么是彩虹表?

彩虹表(Rainbow Table)是一種預(yù)計(jì)算的、包含海量 “明文→哈希值” 映射關(guān)系的數(shù)據(jù)庫

舉個(gè)例子:

裸哈希場(chǎng)景:MD5("123456") = e10adc3949ba59abbe56e057f20f883e;

彩虹表中會(huì)提前存儲(chǔ) e10adc3949ba59abbe56e057f20f883e → 123456 這個(gè)映射關(guān)系;

攻擊者從數(shù)據(jù)庫拿到該哈希值后,查詢彩虹表,1 秒內(nèi)就能得到明文 “123456”。

4.什么是 JCE 無限制權(quán)限文件?(Java 加密的 “權(quán)限解鎖包”)

JCE(Java Cryptography Extension,Java 加密擴(kuò)展)是 Java 平臺(tái)提供的一套加密相關(guān) API 和算法實(shí)現(xiàn)(如 AES、RSA 等)。而 JCE 無限制權(quán)限文件(Unlimited Strength Jurisdiction Files),是用來解除 Java 對(duì) “強(qiáng)加密算法”(如 AES-256、RSA-4096)密鑰長(zhǎng)度限制的補(bǔ)丁文件

為什么需要 “解鎖”?

早年由于國(guó)際加密技術(shù)出口管制政策(部分國(guó)家限制高強(qiáng)度加密算法出口),Oracle JDK 默認(rèn)內(nèi)置了 “受限的 JCE 策略文件”,對(duì)加密算法的密鑰長(zhǎng)度做了嚴(yán)格限制:

  • AES 密鑰長(zhǎng)度最多只能用 128 位(AES-128),無法使用更安全的 192 位、256 位;
  • 其他算法(如 3DES、RC2)也有類似的密鑰長(zhǎng)度限制。

JCE 無限制權(quán)限文件的適用范圍:

JDK 版本是否需要手動(dòng)安裝?說明
JDK 1.7 及以下是(必須手動(dòng)安裝)需下載對(duì)應(yīng)版本的無限制策略文件,替換系統(tǒng)文件
JDK 1.8(8u161 之前)是(需手動(dòng)安裝)8u161 是關(guān)鍵版本,之后默認(rèn)解鎖
JDK 1.8u161 及以上否(默認(rèn)解鎖)無需手動(dòng)操作,直接支持強(qiáng)加密算法
JDK 9 及以上(JDK 11/17)否(默認(rèn)解鎖)徹底移除了 JCE 策略限制,原生支持強(qiáng)加密

注意:OpenJDK(如 AdoptOpenJDK、Eclipse Temurin)默認(rèn)無此限制(從誕生起就支持強(qiáng)加密),只有 Oracle JDK 存在歷史限制 —— 這也是很多項(xiàng)目選擇 OpenJDK 的原因之一。

5.什么是IV/IV向量?

IV 向量(Initialization Vector,初始化向量),本質(zhì)就是對(duì)稱加密算法(如 AES、DES)中,用于初始化加密流程的一串固定長(zhǎng)度隨機(jī)字節(jié)數(shù)組—— 它不是密鑰,也無需保密,核心作用是讓 “相同明文 + 相同密鑰” 產(chǎn)生不同密文,破壞密文的規(guī)律性,抵御攻擊。

可以把它理解為:對(duì)稱加密的 “隨機(jī)啟動(dòng)參數(shù)”—— 就像用同一臺(tái)打印機(jī)(密鑰)打印同一篇文檔(明文),每次用不同的 “打印設(shè)置參數(shù)”(IV 向量),最終打印出的 “成品”(密文)會(huì)完全不同,避免攻擊者通過重復(fù)密文推斷明文。

對(duì)稱加密若沒有 IV 向量(如 AES-ECB 模式),會(huì)存在致命缺陷:相同明文 → 相同密文 ,即使明文和密鑰完全相同,只要 IV 向量不同,最終密文就不同,攻擊者無法通過密文的重復(fù)性推斷明文,加密安全性大幅提升。

IV 向量的適用場(chǎng)景

加密模式是否需要 IV 向量說明推薦度
ECB(電子密碼本模式)不需要無 IV,相同明文→相同密文,易被破解不推薦使用
CBC(密碼分組鏈接模式)需要依賴 IV 啟動(dòng)加密,IV 隨機(jī)即可,兼容性好推薦(常用)
GCM(伽羅瓦 / 計(jì)數(shù)器模式)需要不僅需要 IV,還自帶 “認(rèn)證標(biāo)簽”(防篡改),IV 推薦 12 字節(jié)(最優(yōu)實(shí)踐)推薦(更安全)
CTR(計(jì)數(shù)器模式)需要IV 作為計(jì)數(shù)器初始值,需保證同一密鑰下不重復(fù)可選(適合流式數(shù)據(jù))

誤區(qū):

  1. IV 向量是密鑰? → 并不是,IV 僅用于初始化加密,無需保密;密鑰是加密核心,必須嚴(yán)格保密(如用密鑰倉(cāng)庫存儲(chǔ))。
  2. 用固定 IV 更方便? → 不建議,固定 IV 會(huì)讓相同明文的密文一致,攻擊者可通過密文規(guī)律破解,完全失去 IV 的意義。
  3. IV 越長(zhǎng)越安全? → IV 長(zhǎng)度必須與算法塊大小一致(AES 固定 16 字節(jié)),過長(zhǎng) / 過短都會(huì)報(bào)錯(cuò),且不會(huì)提升安全性。
  4. IV 可以重復(fù)使用? → 同一密鑰下重復(fù)使用 IV 會(huì)導(dǎo)致密文被破解(如 CBC 模式的 “重放攻擊” 漏洞)。
  5. IV 需要加密存儲(chǔ)? → IV 可隨密文公開傳輸 / 存儲(chǔ)(如拼接在密文前),解密時(shí)必須提取原始 IV 才能還原明文。

總結(jié) 

到此這篇關(guān)于java中常用的幾種加密方式的文章就介紹到這了,更多相關(guān)java加密方式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot整合clickhouse配置多分片地址的示例詳解

    SpringBoot整合clickhouse配置多分片地址的示例詳解

    這篇文章主要為大家詳細(xì)介紹了SpringBoot整合clickhouse配置多分片地址的相關(guān)方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-10-10
  • 關(guān)于重寫equals()方法和hashCode()方法及其簡(jiǎn)單的應(yīng)用

    關(guān)于重寫equals()方法和hashCode()方法及其簡(jiǎn)單的應(yīng)用

    這篇文章主要介紹了關(guān)于重寫equals()方法和hashCode()方法及其簡(jiǎn)單的應(yīng)用,網(wǎng)上的知識(shí)有些可能是錯(cuò)誤的,關(guān)于?equals()?方法的理解,大家討論不一樣,需要的朋友可以參考下
    2023-04-04
  • springboot + rabbitmq 如何實(shí)現(xiàn)消息確認(rèn)機(jī)制(踩坑經(jīng)驗(yàn))

    springboot + rabbitmq 如何實(shí)現(xiàn)消息確認(rèn)機(jī)制(踩坑經(jīng)驗(yàn))

    這篇文章主要介紹了springboot + rabbitmq 如何實(shí)現(xiàn)消息確認(rèn)機(jī)制,本文給大家分享小編實(shí)際開發(fā)中的一點(diǎn)踩坑經(jīng)驗(yàn),內(nèi)容簡(jiǎn)單易懂,需要的朋友可以參考下
    2020-07-07
  • Java 繼承方法實(shí)例詳解

    Java 繼承方法實(shí)例詳解

    這篇文章主要介紹了Java繼承中方法實(shí)例,非常的實(shí)用,這里推薦給大家,有需要的小伙伴可以參考下
    2017-04-04
  • java實(shí)現(xiàn)鮮花銷售系統(tǒng)

    java實(shí)現(xiàn)鮮花銷售系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)鮮花銷售系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • redisson分布式限流RRateLimiter源碼解析

    redisson分布式限流RRateLimiter源碼解析

    這篇文章主要為大家介紹了redisson分布式限流RRateLimiter源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Spring Cloud下實(shí)現(xiàn)用戶鑒權(quán)的方案

    Spring Cloud下實(shí)現(xiàn)用戶鑒權(quán)的方案

    Java下常用的安全框架主要有Spring Security和shiro,都可提供非常強(qiáng)大的功能,但學(xué)習(xí)成本較高。但在微服務(wù)下鑒權(quán)又會(huì)對(duì)服務(wù)有一定的入侵性。 因此,本文將介紹Spring Cloud下實(shí)現(xiàn)用戶鑒權(quán)的方案,感興趣的同學(xué)可以關(guān)注一下
    2021-11-11
  • openEuler?搭建java開發(fā)環(huán)境的詳細(xì)過程

    openEuler?搭建java開發(fā)環(huán)境的詳細(xì)過程

    這篇文章主要介紹了openEuler?搭建java開發(fā)環(huán)境,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • MybatisX 快速開發(fā)插件過程詳解

    MybatisX 快速開發(fā)插件過程詳解

    MybatisX 是一款基于 IDEA 的快速開發(fā)插件,方便在使用mybatis以及mybatis-plus開始時(shí)簡(jiǎn)化繁瑣的重復(fù)操作,提高開發(fā)速率。這篇文章主要介紹了MybatisX 快速開發(fā)插件,需要的朋友可以參考下
    2021-10-10
  • SpringCloud如何創(chuàng)建一個(gè)服務(wù)提供者provider

    SpringCloud如何創(chuàng)建一個(gè)服務(wù)提供者provider

    這篇文章主要介紹了SpringCloud如何創(chuàng)建一個(gè)服務(wù)提供者provider,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07

最新評(píng)論

潞城市| 安阳市| 舞钢市| 辽阳市| 慈利县| 新郑市| 阿坝| 宽城| 罗定市| 射阳县| 象州县| 嫩江县| 沈丘县| 含山县| 广西| 青神县| 长乐市| 秦安县| 牙克石市| 日喀则市| 河间市| 阳泉市| 阿克苏市| 冀州市| 五大连池市| 屏山县| 永登县| 天水市| 哈巴河县| 肥乡县| 佳木斯市| 察哈| 全南县| 新巴尔虎左旗| 通江县| 即墨市| 冀州市| 瑞金市| 苗栗市| 绍兴县| 绥阳县|