I'm fairly new to cryptography and am trying to find out best practice for this situation. Let's say I have some code which is going to be used to pass around an encrypted e-mail address. I encrypt it and pass the encoded data out in a link:

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

Now, the recipient passes back the generated string, but guesses the first 16 bytes are the IV (is this a nonce?) and makes a modification to them which creates a (semi-)predicatable change in the encrypted data. For example, the change to byte 5 in the code below changes "bill@microsoft.com" to "bill@oicrosoft.com" or "bill@kicrosoft.com" in most cases. (Let's say I want to register these domains to intercept e-mails):

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

What should I be doing to prevent this - is this a case where I should be using some sort of digital signing to ensure an attacker cannot change the data, or is there a better way of using encryption here?

  • $\begingroup$ If you can afford some overhead (typically 16 bytes) you can use authenticated encryption. Which will reject any modified message with very high probability. $\endgroup$ – CodesInChaos May 24 '17 at 14:05

Use an authenticated mode such as GCM. You can't prevent the modification, but you can detect it.

  • $\begingroup$ That looks like it will do what I need. I assume this basically does the same as if I did what I was doing originally, and just added a MAC afterwards? $\endgroup$ – BarrySW19 May 24 '17 at 17:08
  • $\begingroup$ Yes, that's basically it. $\endgroup$ – Swashbuckler May 25 '17 at 11:19

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.