Attack

防止對 AES 加密數據進行可預測的修改

  • May 24, 2017

我對密碼學相當陌生,正在嘗試找出這種情況的最佳實踐。假設我有一些程式碼將用於傳遞加密的電子郵件地址。我對其進行加密並在連結中傳遞編碼數據:

// pass in "bill@microsoft.com"
public String encryptMessage(final String message) throws Exception {
   // cipher created with Cipher.getInstance("AES/CBC/PKCS5Padding");
   cipher.get().init(Cipher.ENCRYPT_MODE, secretKey);
   byte[] cipherText = cipher.get().doFinal(message.getBytes());

   AlgorithmParameters params = cipher.get().getParameters();
   byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
   byte[] data = Arrays.copyOf(iv, iv.length + cipherText.length);
   System.arraycopy(cipherText, 0, data, iv.length, cipherText.length);
   return Base64.encodeBase64URLSafeString(data);
}

現在,接收者將生成的字元串傳回,但猜測前 16 個字節是 IV(這是隨機數嗎?)並對它們進行修改,從而在加密數據中創建(半)可預測的更改。例如,以下程式碼中對字節 5 的更改在大多數情況下會將“bill@microsoft.com”更改為“bill@oicrosoft.com”或“bill@kicrosoft.com”。(假設我想註冊這些域來攔截電子郵件):

public String decryptMessage(final String message) throws Exception {
   byte[] encData = Base64.decodeBase64(message);

   encData[5] += 2; // Attacker modifies IV to create a predictable change in the data
   cipher.get().init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(Arrays.copyOfRange(encData, 0, 16)));
   byte[] plaintext = cipher.get().doFinal(Arrays.copyOfRange(encData, 16, encData.length));
   return new String(plaintext);
}

我應該怎麼做才能防止這種情況發生 - 這是我應該使用某種數字簽名以確保攻擊者無法更改數據的情況,還是有更好的方法在這裡使用加密?

使用經過身份驗證的模式,例如GCM。您無法阻止修改,但您可以檢測到它。

引用自:https://crypto.stackexchange.com/questions/47681