private void writeHeader() throws IOException {
if (!headerWritten) {
try {
SaltedSecretKey hmacSecretKey = cipherSession.getWriteSecretKey(HMAC_SPEC);
headerHmac = Mac.getInstance(HMAC_SPEC.getAlgorithm(), CRYPTO_PROVIDER_ID);
headerHmac.init(hmacSecretKey);
writeNoHmac(underlyingOutputStream, STREAM_MAGIC);
writeNoHmac(underlyingOutputStream, STREAM_VERSION);
writeNoHmac(underlyingOutputStream, hmacSecretKey.getSalt());
writeAndUpdateHmac(underlyingOutputStream, cipherSpecs.size());
cipherOutputStream = underlyingOutputStream;
for (CipherSpec cipherSpec : cipherSpecs) {
SaltedSecretKey saltedSecretKey = cipherSession.getWriteSecretKey(cipherSpec);
byte[] iv = CipherUtil.createRandomArray(cipherSpec.getIvSize()/8);
writeAndUpdateHmac(underlyingOutputStream, cipherSpec.getId());
writeAndUpdateHmac(underlyingOutputStream, saltedSecretKey.getSalt());
writeAndUpdateHmac(underlyingOutputStream, iv);
cipherOutputStream = cipherSpec.newCipherOutputStream(cipherOutputStream, saltedSecretKey.getEncoded(), iv);
}
writeNoHmac(underlyingOutputStream, headerHmac.doFinal());
}
catch (Exception e) {
throw new IOException(e);
}
headerWritten = true;
}
}