簡體   English   中英

Java AES加密問題

[英]Java AES encryption issue

每次使用AES更改加密值時,請讓任何人調查以下代碼並讓我知道該問題

碼:

private static final String secretKeys = "58BA833E57A51CBF9BF8BAB696BF9"

public static String encrypt() throws Exception {
        byte[] salt = new byte[16];
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        PBEKeySpec pbeKeySpec = new PBEKeySpec(secretKeys.getChars(),salt,1000, 256);
        Key secretKey = factory.generateSecret(pbeKeySpec);
        byte[] key = new byte[32];
        byte[] iv = new byte[16];
        SecretKeySpec secret = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secret);
        byte[] result = cipher.doFinal("welcome".getBytes("UTF-8"));
        String s = Base64.getEncoder().encodeToString(result);
        return s
        }

輸出第一次我得到以下加密的字符串

CZRIP35M4CnJtuDQ6YpmaQ==

我第二次得到以下加密的字符串

/fylTjohAZDsnCaHhiZo3A==

我有三個問題:

  1. 為什么加密的字符串不是常量?

  2. 如何設置Blocksize? AES.BlockSize = 128;

  3. 如何設置填充模式? AES.Padding = PaddingMode.PKCS7;

  1. 對於第一個問題,@ Freiheit已經回答了這個問題 長話短說,基於iv(啟動向量),它充當鹽,並且對於每個加密將是不同的。 話雖如此,加密相同的純文本將導致不同的加密文本,但解密(如果需要)將返回到相同的純文本。 IV有助於使加密可預測。 在數據庫中為2個不同的用戶存儲相同的密碼將具有不同的值,但密碼相同。

  2. 配置當前密碼后,您已經擁有128個塊大小。 您可以在此處閱讀有關不同cypher轉換的更多信息。 您還可以在此處找到有關不同算法的塊大小的更多信息

  3. 您只需將Cipher.getInstance()更改為AES/CBC/PKCS7Padding

1)加密文本總是不同的,因為Cipher初始化提供它自己的IV,因為你沒有提供。 您需要提供已經“計算”的IV才能獲得一致的輸出。 請記住,對於此代碼最終打算執行的操作,您絕不會多次使用IV。

2)密鑰大小可以是128,192或256,但塊大小總是128。

3)Java僅提供PKCS5,但AES的實現沒有區別。 看看pkcs5-padding-and-pkcs7-padding之間有什么區別

正如已經指出的那樣,提供的代碼存在一些問題,例如第一行沒有實際執行任何操作,而鍵和iv都未初始化。 我還建議您使用SecureRandom初始化您的密鑰和iv。 如果您計划僅使用一個AES密鑰,則可以計算一次並將其放在代碼或配置文件中,而不是每次都運行PBKDF2。

只添加@micker提供的答案,您需要調用另一個版本的Cipher.init() ; 將IV考慮在內的:

...
byte[] iv = new byte[16];
IvParameterSpec ivSpec = new IvParameterSpec(iv); // <= Wrap your IV bytes here.
SecretKeySpec secret = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret, ivSpec); // <= Add IV here.
...

話雖這么說,實現還有很多其他問題(關鍵是全零,IV全為零,前4行不為你做任何事情(正如@JBNizet指出的那樣))。 我希望你只是用它來研究Java的加密機制是如何工作的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM