List of usage examples for org.bouncycastle.crypto.modes GCMBlockCipher processBytes
public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException
From source file:dbn.crypto.Crypto.java
public static byte[] aesGCMEncrypt(byte[] plaintext, byte[] key) { try {//from w w w .ja va2s . c om byte[] iv = new byte[16]; secureRandom.get().nextBytes(iv); GCMBlockCipher aes = new GCMBlockCipher(new AESEngine()); CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv); aes.init(true, ivAndKey); byte[] output = new byte[aes.getOutputSize(plaintext.length)]; int ciphertextLength = aes.processBytes(plaintext, 0, plaintext.length, output, 0); ciphertextLength += aes.doFinal(output, ciphertextLength); byte[] result = new byte[iv.length + ciphertextLength]; System.arraycopy(iv, 0, result, 0, iv.length); System.arraycopy(output, 0, result, iv.length, ciphertextLength); return result; } catch (InvalidCipherTextException e) { throw new RuntimeException(e.getMessage(), e); } }
From source file:dbn.crypto.Crypto.java
public static byte[] aesGCMDecrypt(byte[] ivCiphertext, byte[] key) { try {// ww w . ja va2 s . c o m if (ivCiphertext.length < 16) { throw new InvalidCipherTextException("invalid ivCiphertext length"); } byte[] iv = Arrays.copyOfRange(ivCiphertext, 0, 16); byte[] ciphertext = Arrays.copyOfRange(ivCiphertext, 16, ivCiphertext.length); GCMBlockCipher aes = new GCMBlockCipher(new AESEngine()); CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv); aes.init(false, ivAndKey); byte[] output = new byte[aes.getOutputSize(ciphertext.length)]; int plaintextLength = aes.processBytes(ciphertext, 0, ciphertext.length, output, 0); plaintextLength += aes.doFinal(output, plaintextLength); byte[] result = new byte[plaintextLength]; System.arraycopy(output, 0, result, 0, result.length); return result; } catch (InvalidCipherTextException e) { throw new RuntimeException(e.getMessage(), e); } }
From source file:dorkbox.network.connection.KryoExtra.java
License:Apache License
public synchronized void writeCrypto(final Connection_ connection, final ByteBuf buffer, final Object message) throws IOException { // required by RMI and some serializers to determine which connection wrote (or has info about) this object this.rmiSupport = connection.rmiSupport(); ByteBuf objectOutputBuffer = this.tempBuffer; objectOutputBuffer.clear(); // always have to reset everything // write the object to a TEMP buffer! this will be compressed writer.setBuffer(objectOutputBuffer); writeClassAndObject(writer, message); // save off how much data the object took int length = objectOutputBuffer.writerIndex(); // NOTE: compression and encryption MUST work with byte[] because they use JNI! // Realistically, it is impossible to get the backing arrays out of a Heap Buffer once they are resized and begin to use // sliced. It's lame that there is a "double copy" of bytes here, but I don't know how to avoid it... // see: https://stackoverflow.com/questions/19296386/netty-java-getting-data-from-bytebuf byte[] inputArray; int inputOffset; // Even if a ByteBuf has a backing array (i.e. buf.hasArray() returns true), the using it isn't always possible because // the buffer might be a slice of other buffer or a pooled buffer: //noinspection Duplicates if (objectOutputBuffer.hasArray() && objectOutputBuffer.array()[0] == objectOutputBuffer.getByte(0) && objectOutputBuffer.array().length == objectOutputBuffer.capacity()) { // we can use it... inputArray = objectOutputBuffer.array(); inputArrayLength = -1; // this is so we don't REUSE this array accidentally! inputOffset = objectOutputBuffer.arrayOffset(); } else {/*from w w w. j a v a 2s .c o m*/ // we can NOT use it. if (length > inputArrayLength) { inputArrayLength = length; inputArray = new byte[length]; this.inputArray = inputArray; } else { inputArray = this.inputArray; } objectOutputBuffer.getBytes(objectOutputBuffer.readerIndex(), inputArray, 0, length); inputOffset = 0; } ////////// compressing data // we ALWAYS compress our data stream -- because of how AES-GCM pads data out, the small input (that would result in a larger // output), will be negated by the increase in size by the encryption byte[] compressOutput = this.compressOutput; int maxLengthLengthOffset = 4; // length is never negative, so 4 is OK (5 means it's negative) int maxCompressedLength = compressor.maxCompressedLength(length); // add 4 so there is room to write the compressed size to the buffer int maxCompressedLengthWithOffset = maxCompressedLength + maxLengthLengthOffset; // lazy initialize the compression output buffer if (maxCompressedLengthWithOffset > compressOutputLength) { compressOutputLength = maxCompressedLengthWithOffset; compressOutput = new byte[maxCompressedLengthWithOffset]; this.compressOutput = compressOutput; } // LZ4 compress. output offset max 4 bytes to leave room for length of tempOutput data int compressedLength = compressor.compress(inputArray, inputOffset, length, compressOutput, maxLengthLengthOffset, maxCompressedLength); // bytes can now be written to, because our compressed data is stored in a temp array. final int lengthLength = OptimizeUtilsByteArray.intLength(length, true); // correct input. compression output is now encryption input inputArray = compressOutput; inputOffset = maxLengthLengthOffset - lengthLength; // now write the ORIGINAL (uncompressed) length to the front of the byte array. This is so we can use the FAST decompress version OptimizeUtilsByteArray.writeInt(inputArray, length, true, inputOffset); // correct length for encryption length = compressedLength + lengthLength; // +1 to +4 for the uncompressed size bytes /////// encrypting data. final long nextGcmSequence = connection.getNextGcmSequence(); // this is a threadlocal, so that we don't clobber other threads that are performing crypto on the same connection at the same time final ParametersWithIV cryptoParameters = connection.getCryptoParameters(); BigEndian.Long_.toBytes(nextGcmSequence, cryptoParameters.getIV(), 4); // put our counter into the IV final GCMBlockCipher aes = this.aesEngine; aes.reset(); aes.init(true, cryptoParameters); byte[] cryptoOutput; // lazy initialize the crypto output buffer int cryptoSize = length + 16; // from: aes.getOutputSize(length); // 'output' is the temp byte array if (cryptoSize > cryptoOutputLength) { cryptoOutputLength = cryptoSize; cryptoOutput = new byte[cryptoSize]; this.cryptoOutput = cryptoOutput; } else { cryptoOutput = this.cryptoOutput; } int encryptedLength = aes.processBytes(inputArray, inputOffset, length, cryptoOutput, 0); try { // authentication tag for GCM encryptedLength += aes.doFinal(cryptoOutput, encryptedLength); } catch (Exception e) { throw new IOException("Unable to AES encrypt the data", e); } // write out our GCM counter OptimizeUtilsByteBuf.writeLong(buffer, nextGcmSequence, true); // have to copy over the orig data, because we used the temp buffer buffer.writeBytes(cryptoOutput, 0, encryptedLength); }
From source file:dorkbox.network.connection.KryoExtra.java
License:Apache License
public Object readCrypto(final Connection_ connection, final ByteBuf buffer, int length) throws IOException { // required by RMI and some serializers to determine which connection wrote (or has info about) this object this.rmiSupport = connection.rmiSupport(); //////////////// // Note: we CANNOT write BACK to the buffer as "temp" storage, since there could be additional data on it! //////////////// ByteBuf inputBuf = buffer;/*from w ww . j a v a2s . co m*/ final long gcmIVCounter = OptimizeUtilsByteBuf.readLong(buffer, true); int lengthLength = OptimizeUtilsByteArray.longLength(gcmIVCounter, true); // have to adjust for the gcmIVCounter length = length - lengthLength; /////////// decrypting data // NOTE: compression and encryption MUST work with byte[] because they use JNI! // Realistically, it is impossible to get the backing arrays out of a Heap Buffer once they are resized and begin to use // sliced. It's lame that there is a "double copy" of bytes here, but I don't know how to avoid it... // see: https://stackoverflow.com/questions/19296386/netty-java-getting-data-from-bytebuf byte[] inputArray; int inputOffset; // Even if a ByteBuf has a backing array (i.e. buf.hasArray() returns true), the using it isn't always possible because // the buffer might be a slice of other buffer or a pooled buffer: //noinspection Duplicates if (inputBuf.hasArray() && inputBuf.array()[0] == inputBuf.getByte(0) && inputBuf.array().length == inputBuf.capacity()) { // we can use it... inputArray = inputBuf.array(); inputArrayLength = -1; // this is so we don't REUSE this array accidentally! inputOffset = inputBuf.arrayOffset() + lengthLength; } else { // we can NOT use it. if (length > inputArrayLength) { inputArrayLength = length; inputArray = new byte[length]; this.inputArray = inputArray; } else { inputArray = this.inputArray; } inputBuf.getBytes(inputBuf.readerIndex(), inputArray, 0, length); inputOffset = 0; } // have to make sure to set the position of the buffer, since our conversion to array DOES NOT set the new reader index. buffer.readerIndex(buffer.readerIndex() + length); // this is a threadlocal, so that we don't clobber other threads that are performing crypto on the same connection at the same time final ParametersWithIV cryptoParameters = connection.getCryptoParameters(); BigEndian.Long_.toBytes(gcmIVCounter, cryptoParameters.getIV(), 4); // put our counter into the IV final GCMBlockCipher aes = this.aesEngine; aes.reset(); aes.init(false, cryptoParameters); int cryptoSize = length - 16; // from: aes.getOutputSize(length); // lazy initialize the decrypt output buffer byte[] decryptOutputArray; if (cryptoSize > decryptOutputLength) { decryptOutputLength = cryptoSize; decryptOutputArray = new byte[cryptoSize]; this.decryptOutput = decryptOutputArray; decryptBuf = Unpooled.wrappedBuffer(decryptOutputArray); } else { decryptOutputArray = this.decryptOutput; } int decryptedLength = aes.processBytes(inputArray, inputOffset, length, decryptOutputArray, 0); try { // authentication tag for GCM decryptedLength += aes.doFinal(decryptOutputArray, decryptedLength); } catch (Exception e) { throw new IOException("Unable to AES decrypt the data", e); } ///////// decompress data -- as it's ALWAYS compressed // get the decompressed length (at the beginning of the array) inputArray = decryptOutputArray; final int uncompressedLength = OptimizeUtilsByteArray.readInt(inputArray, true); inputOffset = OptimizeUtilsByteArray.intLength(uncompressedLength, true); // because 1-4 bytes for the decompressed size byte[] decompressOutputArray = this.decompressOutput; if (uncompressedLength > decompressOutputLength) { decompressOutputLength = uncompressedLength; decompressOutputArray = new byte[uncompressedLength]; this.decompressOutput = decompressOutputArray; decompressBuf = Unpooled.wrappedBuffer(decompressOutputArray); // so we can read via kryo } inputBuf = decompressBuf; // LZ4 decompress, requires the size of the ORIGINAL length (because we use the FAST decompressor decompressor.decompress(inputArray, inputOffset, decompressOutputArray, 0, uncompressedLength); inputBuf.setIndex(0, uncompressedLength); // read the object from the buffer. reader.setBuffer(inputBuf); return readClassAndObject(reader); // this properly sets the readerIndex, but only if it's the correct buffer }
From source file:dorkbox.util.crypto.CryptoAES.java
License:Apache License
/** * AES encrypts data with a specified key. * * @param logger/*from w ww . j av a 2 s .c om*/ * may be null, if no log output is necessary * * @return length of encrypted data, -1 if there was an error. */ public static byte[] encrypt(GCMBlockCipher aesEngine, CipherParameters aesIVAndKey, byte[] data, int length, Logger logger) { aesEngine.reset(); aesEngine.init(true, aesIVAndKey); int minSize = aesEngine.getOutputSize(length); byte[] outArray = new byte[minSize]; int actualLength = aesEngine.processBytes(data, 0, length, outArray, 0); try { actualLength += aesEngine.doFinal(outArray, actualLength); } catch (Exception e) { if (logger != null) { logger.error("Unable to perform AES cipher.", e); } return new byte[0]; } if (outArray.length == actualLength) { return outArray; } else { byte[] result = new byte[actualLength]; System.arraycopy(outArray, 0, result, 0, result.length); return result; } }
From source file:dorkbox.util.crypto.CryptoAES.java
License:Apache License
/** * AES encrypt from one stream to another. * * @param logger//from ww w. java 2 s . c o m * may be null, if no log output is necessary * @param aesIV * must be a nonce (unique value) !! * * @return true if successful */ public static boolean encryptStream(GCMBlockCipher aesEngine, byte[] aesKey, byte[] aesIV, InputStream in, OutputStream out, Logger logger) { byte[] buf = new byte[ivSize]; byte[] outbuf = new byte[512]; CipherParameters aesIVAndKey = new ParametersWithIV(new KeyParameter(aesKey), aesIV); aesEngine.reset(); aesEngine.init(true, aesIVAndKey); try { int bytesRead; int bytesProcessed; while ((bytesRead = in.read(buf)) >= 0) { bytesProcessed = aesEngine.processBytes(buf, 0, bytesRead, outbuf, 0); out.write(outbuf, 0, bytesProcessed); } bytesProcessed = aesEngine.doFinal(outbuf, 0); out.write(outbuf, 0, bytesProcessed); out.flush(); } catch (Exception e) { if (logger != null) { logger.error("Unable to perform AES cipher.", e); } return false; } return true; }
From source file:dorkbox.util.crypto.CryptoAES.java
License:Apache License
/** * AES decrypt (if we already know the aes IV -- and it's NOT included in the data) * * @param aesIV// w w w . j av a 2 s .c o m * must be a nonce (unique value) !! * @param logger * may be null, if no log output is necessary * * @return empty byte[] if error */ public static byte[] decrypt(GCMBlockCipher aesEngine, byte[] aesKey, byte[] aesIV, byte[] data, Logger logger) { int length = data.length; CipherParameters aesIVAndKey = new ParametersWithIV(new KeyParameter(aesKey), aesIV); aesEngine.reset(); aesEngine.init(false, aesIVAndKey); int minSize = aesEngine.getOutputSize(length); byte[] outBuf = new byte[minSize]; int actualLength = aesEngine.processBytes(data, 0, length, outBuf, 0); try { actualLength += aesEngine.doFinal(outBuf, actualLength); } catch (Exception e) { if (logger != null) { logger.debug("Unable to perform AES cipher.", e); } return new byte[0]; } if (outBuf.length == actualLength) { return outBuf; } else { byte[] result = new byte[actualLength]; System.arraycopy(outBuf, 0, result, 0, result.length); return result; } }
From source file:dorkbox.util.crypto.CryptoAES.java
License:Apache License
/** * AES decrypt from one stream to another. * * @param aesIV/*from ww w .j ava 2 s .c om*/ * must be a nonce (unique value) !! * @param logger * may be null, if no log output is necessary * * @return true if successful */ public static boolean decryptStream(GCMBlockCipher aesEngine, byte[] aesKey, byte[] aesIV, InputStream in, OutputStream out, Logger logger) { byte[] buf = new byte[ivSize]; byte[] outbuf = new byte[512]; CipherParameters aesIVAndKey = new ParametersWithIV(new KeyParameter(aesKey), aesIV); aesEngine.reset(); aesEngine.init(false, aesIVAndKey); try { int bytesRead; int bytesProcessed; while ((bytesRead = in.read(buf)) >= 0) { bytesProcessed = aesEngine.processBytes(buf, 0, bytesRead, outbuf, 0); out.write(outbuf, 0, bytesProcessed); } bytesProcessed = aesEngine.doFinal(outbuf, 0); out.write(outbuf, 0, bytesProcessed); out.flush(); } catch (Exception e) { if (logger != null) { logger.error("Unable to perform AES cipher.", e); } return false; } return true; }
From source file:dorkbox.util.crypto.PerformanceTest.java
License:Apache License
PerformanceTest(boolean isWarmup) { final byte[] bytes = new byte[64 * 1024]; byte[] encrypted = null; final byte[] aesKey = new byte[32]; final byte[] aesIV = new byte[12]; final Random random = new SecureRandom(entropySeed.getBytes()); random.nextBytes(bytes);//w ww . j av a2 s. co m random.nextBytes(aesKey); random.nextBytes(aesIV); int length = bytes.length; if (!isWarmup) { System.out.println("Benchmarking AES-256 GCM encryption"); } long javaEncryptInputBytes = 0; long javaEncryptStartTime = System.currentTimeMillis(); // convert to bouncycastle GCMBlockCipher aesEngine = new GCMBlockCipher(new AESFastEngine()); CipherParameters aesIVAndKey = new ParametersWithIV(new KeyParameter(aesKey), aesIV); long encryptInitTime = 0L; long encryptUpdate1Time = 0L; long encryptDoFinalTime = 0L; while (System.currentTimeMillis() - javaEncryptStartTime < 10000) { random.nextBytes(aesIV); long n1 = System.nanoTime(); aesEngine.reset(); aesEngine.init(true, aesIVAndKey); if (encrypted == null) { int minSize = aesEngine.getOutputSize(length); encrypted = new byte[minSize]; } long n2 = System.nanoTime(); int actualLength = aesEngine.processBytes(bytes, 0, length, encrypted, 0); long n3 = System.nanoTime(); try { actualLength += aesEngine.doFinal(encrypted, actualLength); } catch (Exception e) { logger.error("Unable to perform AES cipher.", e); } if (encrypted.length != actualLength) { byte[] result = new byte[actualLength]; System.arraycopy(encrypted, 0, result, 0, result.length); encrypted = result; } long n4 = System.nanoTime(); javaEncryptInputBytes += actualLength; encryptInitTime = n2 - n1; encryptUpdate1Time = n3 - n2; encryptDoFinalTime = n4 - n3; } long javaEncryptEndTime = System.currentTimeMillis(); if (!isWarmup) { System.out.println("Time init (ns): " + encryptInitTime); System.out.println("Time update (ns): " + encryptUpdate1Time); System.out.println("Time do final (ns): " + encryptDoFinalTime); System.out.println("Java calculated at " + (javaEncryptInputBytes / 1024 / 1024 / ((javaEncryptEndTime - javaEncryptStartTime) / 1000)) + " MB/s"); System.out.println("Benchmarking AES-256 GCM decryption"); } long javaDecryptInputBytes = 0; long javaDecryptStartTime = System.currentTimeMillis(); length = encrypted.length; long decryptInitTime = 0L; long decryptUpdate1Time = 0L; long decryptDoFinalTime = 0L; while (System.currentTimeMillis() - javaDecryptStartTime < 10000) { long n1 = System.nanoTime(); aesEngine.reset(); aesEngine.init(false, aesIVAndKey); long n2 = System.nanoTime(); int actualLength = aesEngine.processBytes(encrypted, 0, length, bytes, 0); long n3 = System.nanoTime(); try { actualLength += aesEngine.doFinal(bytes, actualLength); } catch (Exception e) { logger.debug("Unable to perform AES cipher.", e); } long n4 = System.nanoTime(); javaDecryptInputBytes += actualLength; decryptInitTime += n2 - n1; decryptUpdate1Time += n3 - n2; decryptDoFinalTime += n4 - n3; } long javaDecryptEndTime = System.currentTimeMillis(); if (!isWarmup) { System.out.println("Time init (ns): " + decryptInitTime); System.out.println("Time update 1 (ns): " + decryptUpdate1Time); System.out.println("Time do final (ns): " + decryptDoFinalTime); System.out.println("Total bytes processed: " + javaDecryptInputBytes); System.out.println("Java calculated at " + (javaDecryptInputBytes / 1024 / 1024 / ((javaDecryptEndTime - javaDecryptStartTime) / 1000)) + " MB/s"); } }
From source file:org.openmuc.jdlms.internal.security.CipheringGcm.java
License:Open Source License
public static byte[] encrypt(byte[] plaintext, int off, int len, byte[] systemTitle, int frameCounter, byte[] encryptionKey, byte[] authenticationKey, byte tag) throws IOException { byte[] frameCounterBytes = intToByteArray(frameCounter); byte[] iv = concat(systemTitle, frameCounterBytes); byte[] associatedData = new byte[authenticationKey.length + 1]; associatedData[0] = SECURITY_CONTROL_BYTES_AUTH_CIPH; System.arraycopy(authenticationKey, 0, associatedData, 1, authenticationKey.length); AEADParameters parameters = new AEADParameters(new KeyParameter(encryptionKey), 96, iv, associatedData); GCMBlockCipher encCipher = new GCMBlockCipher(new AESFastEngine(), new BasicGCMMultiplier()); encCipher.init(true, parameters);/*from ww w .j a va2s.c om*/ byte[] enc = new byte[encCipher.getOutputSize(len)]; int length = encCipher.processBytes(plaintext, off, len, enc, 0); try { length += encCipher.doFinal(enc, length); } catch (IllegalStateException e) { throw new IOException("Unable to cipher/encrypt xDLMS pdu", e); } catch (InvalidCipherTextException e) { throw new IOException("Unable to cipher/encrypt xDLMS pdu", e); } byte[] result = new byte[enc.length + 7]; result[0] = tag; result[1] = (byte) (enc.length + 5); result[2] = SECURITY_CONTROL_BYTES_AUTH_CIPH; System.arraycopy(frameCounterBytes, 0, result, 3, 4); System.arraycopy(enc, 0, result, 7, enc.length); return result; }