title: Java AES CTR IV and counter
body: <p>I have tried to find the answer by myself looking here and searching elsewhere for quite a while, but I still have some questions.</p>
  
  <p>Assume this Java code:</p>
  
  <pre><code>try
  {   
      int cipherMode = Cipher.ENCRYPT_MODE;
  
      SecretKeySpec secretKey = ...; // generated previously using KeyGenerator       
  
      byte[] nonceAndCounter = new byte[16];
      byte[] nonceBytes      = ...; // generated previously using SecureRandom's nextBytes(8);
  
      // use first 8 bytes as nonce
      Arrays.fill(nonceAndCounter, (byte) 0);
      System.arraycopy(nonceBytes, 0, nonceAndCounter, 0, 8);
  
      IvParameterSpec ivSpec = new IvParameterSpec(nonceAndCounter);
      Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
  
      cipher.init(cipherMode, secretKey, ivSpec);
  
      File inFile  = new File(...);
      File outFile = new File(...);
  
      long bytesRead = 0;
  
      try (FileInputStream is = new FileInputStream(inFile);
           FileOutputStream os = new FileOutputStream(outFile))
      {       
          byte[] inBuf       = new byte[512 * 1024];
          byte[] outBuf      = new byte[512 * 1024];
          int    readLen     = 0;
  
          ByteBuffer byteBuffer = ByteBuffer.allocate(8);
          byteBuffer.putLong(bytesRead);
  
          while ((readLen = is.read(inBuf)) != -1)
          {
              bytesRead += readLen;
  
              cipher.update(inBuf, 0, readLen, outBuf, 0);
  
              os.write(outBuf);
          }
  
          cipher.doFinal(outBuf, 0);
          os.write(outBuf);
          is.close();
          os.close();
      }
      catch (Exception e) {
          System.out.printf("Exception for file: %s\n", e);
      }
  } 
  catch (Exception e) { 
      System.out.printf("Exception: %s\n", e);
  }
  </code></pre>
  
  <p>My questions are:</p>
  
  <ol>
  <li><p>Is the above code considered OK regarding counter updates for CTR mode? Specifically, I am not updating the counter myself.  Should I use the following while loop instead? I tried this because I looked at what cipher.getIV() returns in the loop, but it does not change and the description for getIV() does not go into much details:</p>
  
  <pre><code>    while ((readLen = is.read(inBuf)) != -1)
      {   
          // use offset for last 8 bytes as counter
          byteBuffer.putLong(bytesRead);
          System.arraycopy(byteBuffer.array(), 0, nonceAndCounter, 8, 8);
  
          bytesRead += readLen;
  
          IvParameterSpec ivSpec = new IvParameterSpec(nonceAndCounter);
  
          cipher.init(cipherMode, secretKey, ivSpec);
  
          cipher.update(inBuf, 0, readLen, outBuf, 0);
  
          os.write(outBuf);
      }
  </code></pre>
  
  <ol start="2">
  <li><p>I have more questions related to the modified while loop approach. Is it OK to call cipher.init() in such a way? I do this because I haven't found a way to update just IV (counter really).</p></li>
  <li><p>Is such a large block size OK or should it be made smaller? In that case how big should it be?</p></li>
  </ol></li>
  </ol>