/** Encrypt the specified section of the provided byte[] in-place */ public void encrypt(byte[] input, int offset, int len) { encrypt(input, offset, len, input, offset); }
@Test public void testOverlappingEncode() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt, crypt2; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); crypt2 = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); crypt2 = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] originalPlaintext = Hex.decode(plainText[i]); byte[] originalCiphertext = crypt2.encryptCopy(originalPlaintext); byte[] buf = new byte[originalPlaintext.length+1]; System.arraycopy(originalPlaintext, 0, buf, 0, originalPlaintext.length); crypt.encrypt(buf, 0, originalPlaintext.length, buf, 1); assertArrayEquals(originalCiphertext, Arrays.copyOfRange(buf, 1, buf.length)); } }
int r = buf.length - j; int copy = 1 + (r == 1 ? 0 : random.nextInt(r-1)); crypt2.encrypt(buf, j, copy); j += copy;
/** * Encrypts the specified section of provided byte[] into a new array returned as a ByteBuffer. * Does not modify the original array. If you are using a RijndaelECB alg then len must equal * the block size. * @param input The bytes to be encrypted. Contents will not be modified. * @param offset The position of input to start encrypting at * @param len The number of bytes after offset to encrypt * @return Returns a new array containing the ciphertext encoding the specified range. */ public byte[] encryptCopy(byte[] input, int offset, int len){ byte[] output = Arrays.copyOfRange(input, offset, offset+len); encrypt(input, offset, len, output, 0); return output; }
@Test public void testRoundOneByte() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt1; CryptByteBuffer crypt2; if(!type.isStreamCipher) continue; if(ivs[i] == null){ crypt1 = new CryptByteBuffer(type, keys[i]); crypt2 = new CryptByteBuffer(type, keys[i]); } else { crypt1 = new CryptByteBuffer(type, keys[i], ivs[i]); crypt2 = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] origPlaintext = Hex.decode(plainText[i]); byte[] origCiphertext = crypt1.encryptCopy(origPlaintext); // Now encrypt one byte at a time. byte[] buf = origPlaintext.clone(); for(int j=0;j<buf.length;j++) { crypt2.encrypt(buf, j, 1); assertEquals(buf[j], origCiphertext[j]); } for(int j=0;j<buf.length;j++) { crypt2.decrypt(buf, j, 1); assertEquals(buf[j], origPlaintext[j]); } } }
/** Get bytes from one ByteBuffer and encrypt them and put them into the other ByteBuffer. */ public void encrypt(ByteBuffer input, ByteBuffer output) { if(input.hasArray() && output.hasArray()) { int moved = Math.min(input.remaining(), output.remaining()); encrypt(input.array(), input.arrayOffset()+input.position(), moved, output.array(), output.arrayOffset()+output.position()); input.position(input.position()+moved); output.position(output.position()+moved); } else if(!(type == CryptByteBufferType.RijndaelPCFB || type.cipherName.equals("RIJNDAEL"))) { // Use ByteBuffer to ByteBuffer operations. try { int copy = Math.min(input.remaining(), output.remaining()); int copied = encryptCipher.update(input, output); if(copied != copy) throw new IllegalStateException("Not a stream cipher???"); } catch (ShortBufferException e) { throw new Error("Impossible: "+e, e); } } else { // FIXME use a smaller temporary buffer int moved = Math.min(input.remaining(), output.remaining()); byte[] buf = new byte[moved]; input.get(buf); encrypt(buf, 0, buf.length); output.put(buf); } }
encrypt(temp, 0, temp.length); System.arraycopy(temp, 0, output, outputOffset, len); return;
plaintext.position(0); ByteBuffer ciphertext = ByteBuffer.allocateDirect(origPlaintext.length); crypt.encrypt(plaintext, ciphertext); assertEquals(plaintext.position(), origPlaintext.length); assertEquals(ciphertext.position(), origPlaintext.length);
byte[] copyCiphertextBuf = ciphertextBuf.clone(); ByteBuffer ciphertext = ByteBuffer.wrap(ciphertextBuf, header, origPlaintext.length); crypt.encrypt(plaintext, ciphertext); assertEquals(plaintext.position(), header+origPlaintext.length); assertEquals(ciphertext.position(), header+origPlaintext.length);
@Test public void testSuccessfulRoundTripInPlaceOffset() throws GeneralSecurityException { int header = 5; int footer = 5; for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] originalPlaintext = Hex.decode(plainText[i]); byte[] buffer = new byte[header+originalPlaintext.length+footer]; byte[] copyBuffer = buffer.clone(); System.arraycopy(originalPlaintext, 0, buffer, header, originalPlaintext.length); crypt.encrypt(buffer, footer, originalPlaintext.length); assertTrue(!Arrays.equals(buffer, copyBuffer)); crypt.decrypt(buffer, footer, originalPlaintext.length); assertArrayEquals("CryptByteBufferType: "+type.name(), originalPlaintext, Arrays.copyOfRange(buffer, footer, footer+originalPlaintext.length)); } }
@Test public void testSuccessfulRoundTripOutOfPlaceOffset() throws GeneralSecurityException { int inHeader = 5; int inFooter = 5; int outHeader = 33; int outFooter = 33; for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] originalPlaintext = Hex.decode(plainText[i]); byte[] buffer = new byte[inHeader+originalPlaintext.length+inFooter]; System.arraycopy(originalPlaintext, 0, buffer, inHeader, originalPlaintext.length); byte[] copyBuffer = buffer.clone(); byte[] outBuffer = new byte[outHeader + originalPlaintext.length + outFooter]; crypt.encrypt(buffer, inFooter, originalPlaintext.length, outBuffer, outHeader); assertTrue(Arrays.equals(buffer, copyBuffer)); copyBuffer = outBuffer.clone(); crypt.decrypt(outBuffer, outHeader, originalPlaintext.length, buffer, inFooter); assertTrue(Arrays.equals(copyBuffer, outBuffer)); assertArrayEquals("CryptByteBufferType: "+type.name(), originalPlaintext, Arrays.copyOfRange(buffer, inFooter, inFooter+originalPlaintext.length)); } }
@Test public void testSuccessfulRoundTripInPlace() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } byte[] buffer = Hex.decode(plainText[i]); byte[] plaintextCopy = buffer.clone(); crypt.encrypt(buffer, 0, buffer.length); assertTrue(!Arrays.equals(buffer, plaintextCopy)); crypt.decrypt(buffer, 0, buffer.length); assertArrayEquals("CryptByteBufferType: "+type.name(), plaintextCopy, buffer); } }