public DecryptingStream(BlockCipher cipher, InputStream inputStream) throws EncryptionError, IOException { this.inputStream = inputStream; byte[] iv = new byte[cipher.getBlockSize()]; inputStream.read(iv); transformer = new CTRTransformer(cipher, iv); }
protected BlockCipher getCipher() { if (cipher == null) { cipher = new AES256(); cipher.initialize(BlockCipher.Direction.ENCRYPT, this); } return cipher; }
private void prepareBlock() throws EncryptionError { System.arraycopy(nonce, 0, source, 0, blockSize); counterBytes[0] = (byte) (counter >> 24); counterBytes[1] = (byte) (counter >> 16); counterBytes[2] = (byte) (counter >> 8); counterBytes[3] = (byte) counter; applyXor(source, blockSize - 4, counterBytes); synchronized (cipher) { source = cipher.transformBlock(source); } counter++; index = 0; }
/** * Create CTR basic transformer * * @param cipher * properly initialized cipher with key and and direction that must always be set {@link * BlockCipher.Direction#ENCRYPT} * @param iv * null to generate new random IV, get it with {@link #getIV()} and store somewhere with * encrypted data. * * @throws EncryptionError */ public CTRTransformer(BlockCipher cipher, byte[] iv) throws EncryptionError { this.cipher = cipher; blockSize = cipher.getBlockSize(); nonce = iv == null ? randomBytes(blockSize) : iv; counter = 0; source = new byte[blockSize]; counterBytes = new byte[4]; prepareBlock(); }
/** * Helps to create block cipher with a given class and key, by properly initializing it. * @param cipherClass cipher class to instantiate * @param key * @return properly initialized encpytor * @throws EncryptionError */ public static BlockCipher makeCipher(Class<? extends BlockCipher> cipherClass, byte[] key) throws EncryptionError { try { BlockCipher cipher = cipherClass.newInstance(); cipher.initialize(BlockCipher.Direction.DECRYPT, new SymmetricKey(key)); return cipher; } catch (InstantiationException | IllegalAccessException e) { throw new EncryptionError("failed to instantiate BlockCipher class " + cipherClass .getName(), e); } }
EtaDecryptingStream(InputStream inputStream) throws IOException, EncryptionError { this.inputStream = inputStream; byte[] IV = new byte[getCipher().getBlockSize()]; inputStream.read(IV); transformer = new CTRTransformer(getCipher(), IV); hmac = new HMAC(key); // We should have always block bytes in the buffer to finish: ring = new ByteRingBuffer(hmac.getLength() + 8); for (int i = 0; i < hmac.getLength(); i++) ring.put(inputStream.read()); }