title: How does AES decrypt with a different IV?
body: <p>I am trying to learn more about AES encryption. AES encryption uses both the key and <a href="https://en.wikipedia.org/wiki/Initialization_vector" rel="nofollow noreferrer">initialization vector</a> (IV) for encryption, but since each IV is different, how does AES decrypt the ciphertext and return the plaintext?</p>
  <ul>
  <li><p><em><a href="http://www.moserware.com/2009/09/stick-figure-guide-to-advanced.html" rel="nofollow noreferrer">A Stick Figure Guide to the Advanced Encryption Standard (AES)</a></em></p>
  </li>
  <li><p><em><a href="https://www.securecoding.cert.org/confluence/display/java/MSC61-J.+Do+not+use+insecure+or+weak+cryptographic+algorithms" rel="nofollow noreferrer">MSC61-J. Do not use insecure or weak cryptographic algorithms</a></em></p>
  </li>
  </ul>
  <p> </p>
  <pre><code>public static byte[] encrypt_cbc(SecretKey skey, String plaintext) {
      /* Precondition: skey is valid; otherwise IllegalStateException will be thrown. */
      try {
          byte[] ciphertext = null;
          Cipher cipher = Cipher.getInstance(&quot;AES/CBC/PKCS5Padding&quot;);
          final int blockSize = cipher.getBlockSize();
          byte[] initVector = new byte[blockSize];
          (new SecureRandom()).nextBytes(initVector);
          IvParameterSpec ivSpec = new IvParameterSpec(initVector);
          cipher.init(Cipher.ENCRYPT_MODE, skey, ivSpec);
          byte[] encoded = plaintext.getBytes(java.nio.charset.StandardCharsets.UTF_8);
          ciphertext = new byte[initVector.length + cipher.getOutputSize(encoded.length)];
          for (int i=0; i &lt; initVector.length; i++) {
              ciphertext[i] = initVector[i];
          }
          // Perform encryption
          cipher.doFinal(encoded, 0, encoded.length, ciphertext, initVector.length);
          return ciphertext;
      } catch (NoSuchPaddingException | InvalidAlgorithmParameterException | ShortBufferException |
          BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchAlgorithmException e)
      {
          /* None of these exceptions should be possible if the precondition is met. */
          throw new IllegalStateException(e.toString());
      }
  }
  
  public static String decrypt_cbc(SecretKey skey, byte[] ciphertext)
      throws BadPaddingException, IllegalBlockSizeException /* These indicate corrupt or malicious ciphertext */
  {
      try {
          Cipher cipher = Cipher.getInstance(&quot;AES/CBC/PKCS5Padding&quot;);
          final int blockSize = cipher.getBlockSize();
          byte[] initVector = Arrays.copyOfRange(ciphertext, 0, blockSize);
          IvParameterSpec ivSpec = new IvParameterSpec(initVector);
          cipher.init(Cipher.DECRYPT_MODE, skey, ivSpec);
          byte[] plaintext = cipher.doFinal(ciphertext, blockSize, ciphertext.length - blockSize);
          return new String(plaintext);
      } catch (NoSuchPaddingException | InvalidAlgorithmParameterException |
          InvalidKeyException | NoSuchAlgorithmException e)
      {
          /* None of these exceptions should be possible if precond is met. */
          throw new IllegalStateException(e.toString());
      }
  }
  </code></pre>