2014-06-16 37 views
0

我使用加密來創建查詢參數,通過下載鏈接到各個文件,通過電子郵件發送給個人。但是,我注意到加密的字符串對於類似的文件名非常相似。我想改變這一點。Java/Groovy:隨機化加密字符串更好

這裏是我目前使用的代碼:

Cipher cipher = Cipher.getInstance('AES/CBC/PKCS5Padding') 
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec('****************' as byte[], AES'), 
    new IvParameterSpec('***************' as byte[])) 
String fileId = Base64.encodeBase64String(
    IOUtils.toByteArray(
     new CipherInputStream(
      new DeflaterInputStream(
       new ByteArrayInputStream(
        ('File: ' + filename).getBytes('UTF-8') 
       ) 
      ), cipher 
     ) 
    ) 
) 

例如,如果我有一個名爲Something_8.3.0.1471.exe和Something_8.3.0.1471_License.txt文件我會得到以下兩個字符串:

mVjCmP2GCyxMJ1i5GHT1OOZEYXy1%2Buz%2BQ53QMelR4QU%2FTowMdjNcMjojlbjuTJEd 

mVjCmP2GCyxMJ1i5GHT1OB%2F5S1rolp%2BwK9dATPdPtHn3uQiXnYUhLmym6hMI65TVfjA5IzSYInI9iIjZn9eExg%3D%3D 

第20個或所以加密的STR的字符ing是相同的,顯然是因爲文件名的開始是相同的。我想知道是否有可能刪除這種相同性(如果這是一個字)。未加密的字符串中的任何更改是否可能對整個加密字符串造成更顯着的影響?如果是這樣,我將如何在上述代碼中對Java/Groovy進行更改?

回答

1

deterministic encryption方案中使用相同的密鑰和相同的純文本將始終生成相同的密文。 Probabilistic encryption方案引入了一些隨機因子,以便用相同的密鑰和相同的純文本連續調用加密產生不同的密文。

一些加密算法(如EC簽名)在內部生成隨機值,甚至不向用戶公開它們,因爲它們不需要存儲該隨機因子的值以解密密文(或驗證簽名)但是在大多數密碼中,用戶是可信以提供諸如初始化向量或隨機數的隨機因子。

AES的塊大小爲16字節,這意味着它將輸入拆分爲16字節的塊,並分別處理每個塊(在ECB模式下)或以某種方式混合前面的處理結果(在大多數其他密碼模式)。對於第一個塊,不管使用哪種密碼模式,唯一的輸入是密鑰,IV和輸入的前16個字節。

在你的例子中,在這兩種情況下,前16個字節是相同的,而且你似乎使用相同的密鑰和相同的IV(順便說一句,最大的加密罪之一)。正如所料,前16個字節(或等同於前20個Base64字符)是相同的。 輸入的接下來的16個字節是不同的,這導致完全不同的第二塊密文。

您不能兩次使用相同的IV值。使用SecureRandom爲每次加密嘗試生成唯一的IV值。

SecureRandom random = new SecureRandom(); 
byte bytes[] = new byte[16]; // use the proper IV size for selected cipher 
random.nextBytes(bytes); 

當使用一個單一的存儲實體(單個文件,例如)存儲IV之前的密文是事實上的標準,但它不是必需的(可以存儲IV和密文中例如一個單獨的數據庫列)。

您不能使用通過簡單地將字符序列轉換爲字節序列而創建的密鑰。這些鍵具有可預測的屬性(例如,對於ASCII文本,鍵不會包含[0..31]範圍內的字節)。如果您需要基於密碼的密鑰,請使用正確的密鑰派生函數,如PBKDF2。