private KeyVersion decryptEncryptedKey(final Decryptor decryptor, final KeyVersion encryptionKey, final EncryptedKeyVersion encryptedKeyVersion) throws IOException, GeneralSecurityException { // Encryption key IV is determined from encrypted key's IV final byte[] encryptionIV = EncryptedKeyVersion.deriveIV(encryptedKeyVersion.getEncryptedKeyIv()); decryptor.init(encryptionKey.getMaterial(), encryptionIV); final KeyVersion encryptedKV = encryptedKeyVersion.getEncryptedKeyVersion(); int keyLen = encryptedKV.getMaterial().length; ByteBuffer bbIn = ByteBuffer.allocateDirect(keyLen); ByteBuffer bbOut = ByteBuffer.allocateDirect(keyLen); bbIn.put(encryptedKV.getMaterial()); bbIn.flip(); decryptor.decrypt(bbIn, bbOut); bbOut.flip(); byte[] decryptedKey = new byte[keyLen]; bbOut.get(decryptedKey); return new KeyVersion(encryptionKey.getName(), EK, decryptedKey); }
/** * This method is executed immediately after decryption. Check whether * decryptor should be updated and recalculate padding if needed. */ private byte afterDecryption(Decryptor decryptor, ByteBuffer inBuffer, long position, byte[] iv) throws IOException { byte padding = 0; if (decryptor.isContextReset()) { /* * This code is generally not executed since the decryptor usually * maintains decryption context (e.g. the counter) internally. However, * some implementations can't maintain context so a re-init is necessary * after each decryption call. */ updateDecryptor(decryptor, position, iv); padding = getPadding(position); inBuffer.position(padding); } return padding; }
public DecryptHandler(CryptoCodec codec, byte[] key, byte[] iv) throws GeneralSecurityException, IOException { this.decryptor = codec.createDecryptor(); this.decryptor.init(key, Arrays.copyOf(iv, iv.length)); }
/** * Do the decryption using inBuffer as input and outBuffer as output. * Upon return, inBuffer is cleared; the decrypted data starts at * outBuffer.position() and ends at outBuffer.limit(); */ private void decrypt(Decryptor decryptor, ByteBuffer inBuffer, ByteBuffer outBuffer, byte padding) throws IOException { Preconditions.checkState(inBuffer.position() >= padding); if(inBuffer.position() == padding) { // There is no real data in inBuffer. return; } inBuffer.flip(); outBuffer.clear(); decryptor.decrypt(inBuffer, outBuffer); inBuffer.clear(); outBuffer.flip(); if (padding > 0) { /* * The plain text and cipher text have a 1:1 mapping, they start at the * same position. */ outBuffer.position(padding); } }
/** Calculate the counter and iv, update the decryptor. */ private void updateDecryptor(Decryptor decryptor, long position, byte[] iv) throws IOException { final long counter = getCounter(position); codec.calculateIV(initIV, counter, iv); decryptor.init(key, iv); }
@Override protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { ByteBuf inBuf; boolean release = false; if (msg.nioBufferCount() == 1) { inBuf = msg; } else { inBuf = ctx.alloc().directBuffer(msg.readableBytes()); msg.readBytes(inBuf); release = true; } ByteBuffer inBuffer = inBuf.nioBuffer(); ByteBuf outBuf = ctx.alloc().directBuffer(inBuf.readableBytes()); ByteBuffer outBuffer = outBuf.nioBuffer(0, inBuf.readableBytes()); decryptor.decrypt(inBuffer, outBuffer); outBuf.writerIndex(inBuf.readableBytes()); if (release) { inBuf.release(); } ctx.fireChannelRead(outBuf); } }
/** Calculate the counter and iv, update the decryptor. */ private void updateDecryptor(Decryptor decryptor, long position, byte[] iv) throws IOException { final long counter = getCounter(position); codec.calculateIV(initIV, counter, iv); decryptor.init(key, iv); }
/** * Do the decryption using inBuffer as input and outBuffer as output. * Upon return, inBuffer is cleared; the decrypted data starts at * outBuffer.position() and ends at outBuffer.limit(); */ private void decrypt(Decryptor decryptor, ByteBuffer inBuffer, ByteBuffer outBuffer, byte padding) throws IOException { Preconditions.checkState(inBuffer.position() >= padding); if(inBuffer.position() == padding) { // There is no real data in inBuffer. return; } inBuffer.flip(); outBuffer.clear(); decryptor.decrypt(inBuffer, outBuffer); inBuffer.clear(); outBuffer.flip(); if (padding > 0) { /* * The plain text and cipher text have a 1:1 mapping, they start at the * same position. */ outBuffer.position(padding); } }
/** * This method is executed immediately after decryption. Check whether * decryptor should be updated and recalculate padding if needed. */ private byte afterDecryption(Decryptor decryptor, ByteBuffer inBuffer, long position, byte[] iv) throws IOException { byte padding = 0; if (decryptor.isContextReset()) { /* * This code is generally not executed since the decryptor usually * maintains decryption context (e.g. the counter) internally. However, * some implementations can't maintain context so a re-init is necessary * after each decryption call. */ updateDecryptor(decryptor, position, iv); padding = getPadding(position); inBuffer.position(padding); } return padding; }
/** Calculate the counter and iv, update the decryptor. */ private void updateDecryptor(Decryptor decryptor, long position, byte[] iv) throws IOException { final long counter = getCounter(position); codec.calculateIV(initIV, counter, iv); decryptor.init(key, iv); }
/** * Do the decryption using inBuffer as input and outBuffer as output. * Upon return, inBuffer is cleared; the decrypted data starts at * outBuffer.position() and ends at outBuffer.limit(); */ private void decrypt(Decryptor decryptor, ByteBuffer inBuffer, ByteBuffer outBuffer, byte padding) throws IOException { Preconditions.checkState(inBuffer.position() >= padding); if(inBuffer.position() == padding) { // There is no real data in inBuffer. return; } inBuffer.flip(); outBuffer.clear(); decryptor.decrypt(inBuffer, outBuffer); inBuffer.clear(); outBuffer.flip(); if (padding > 0) { /* * The plain text and cipher text have a 1:1 mapping, they start at the * same position. */ outBuffer.position(padding); } }
/** * This method is executed immediately after decryption. Check whether * decryptor should be updated and recalculate padding if needed. */ private byte afterDecryption(Decryptor decryptor, ByteBuffer inBuffer, long position, byte[] iv) throws IOException { byte padding = 0; if (decryptor.isContextReset()) { /* * This code is generally not executed since the decryptor usually * maintains decryption context (e.g. the counter) internally. However, * some implementations can't maintain context so a re-init is necessary * after each decryption call. */ updateDecryptor(decryptor, position, iv); padding = getPadding(position); inBuffer.position(padding); } return padding; }
/** Calculate the counter and iv, update the decryptor. */ private void updateDecryptor(Decryptor decryptor, long position, byte[] iv) throws IOException { final long counter = getCounter(position); codec.calculateIV(initIV, counter, iv); decryptor.init(key, iv); }
/** * Do the decryption using inBuffer as input and outBuffer as output. * Upon return, inBuffer is cleared; the decrypted data starts at * outBuffer.position() and ends at outBuffer.limit(); */ private void decrypt(Decryptor decryptor, ByteBuffer inBuffer, ByteBuffer outBuffer, byte padding) throws IOException { Preconditions.checkState(inBuffer.position() >= padding); if(inBuffer.position() == padding) { // There is no real data in inBuffer. return; } inBuffer.flip(); outBuffer.clear(); decryptor.decrypt(inBuffer, outBuffer); inBuffer.clear(); outBuffer.flip(); if (padding > 0) { /* * The plain text and cipher text have a 1:1 mapping, they start at the * same position. */ outBuffer.position(padding); } }
/** * This method is executed immediately after decryption. Check whether * decryptor should be updated and recalculate padding if needed. */ private byte afterDecryption(Decryptor decryptor, ByteBuffer inBuffer, long position, byte[] iv) throws IOException { byte padding = 0; if (decryptor.isContextReset()) { /* * This code is generally not executed since the decryptor usually * maintains decryption context (e.g. the counter) internally. However, * some implementations can't maintain context so a re-init is necessary * after each decryption call. */ updateDecryptor(decryptor, position, iv); padding = getPadding(position); inBuffer.position(padding); } return padding; }
/** Calculate the counter and iv, update the decryptor. */ private void updateDecryptor(Decryptor decryptor, long position, byte[] iv) throws IOException { final long counter = getCounter(position); codec.calculateIV(initIV, counter, iv); decryptor.init(key, iv); }