I am working on a project that requires appending to a AES/CTR encrypted file. Now, since it is counter mode I know that I can advance the counter to any location and start reading at the location in the file. What I am wondering though is if there is a way for me to fetch the current IV that Cipher has access to after it has been used.
Cipher c = Cipher.getInstance("AES/CTR/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aeskey, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
c.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
CipherOutputStream cipher_out = new CipherOutputStream(output, c);
try {
while (true) {
cipher_out.write(input.readByte());
}
} catch (EOFException e) {
}
byte curIV[] = c.getIV();
Instead I am finding that curIV rather than having the updated IV has the same IV that I passed into the ivSpec to begin with. Is there no way to get the current IV?
The idea is to store:
<AES key><begin IV><current IV>
in a asymmetricly encrypted file, this way that can be decrypted, read and we can start reading the AES encrypted file from the beginning or we can append new data to our output file using the <current IV> that we have stored.
Any other suggestions on how to implement this?
Java according to documentation I have found uses the following (close to RFC3686):
<NONCE><COUNTER>
As its input into the CTR, and to update the counter it is considered to be a big endian number.
This is provided as the IvParameterSpec seen above.
Besides the point, what I am trying to get back is the counter, whether we want to call that the IV, or if we want to call it the counter, or the nonce + iv + counter.
More information about Suns implementation of CTR: http://javamex.ning.com/forum/topics/questions-on-aes-ctr-mode
In experimenting with the “SunJCE” provider, AES in CTR-mode follows the proposal published by NIST, where an initial counter value is simply incremented by one with each successive block. This is consistent with the general guidance given in NIST SP 800‑38A, Appendix B.1., when the number of incremented bits,
m, is the number of bits in the block,b.This is contrary to RFC 3686. That is, the entire counter is incremented, not just a limited portion as specified in RFC 3686.
You can know the block index by counting blocks (starting with zero), or by measuring the length of the cipher text and performing integer division by the block size. If those options seem too easy, you can also XOR the last block of cipher text with the corresponding plain text, decrypt that result, and subtract the IV to yield the block index.
To append, simply set the IV to the original IV plus the block index. If you are writing streams that can end with a partial block, you’ll have some extra work to do to get the stream into the correct state.