/** * Decrypts the provided byte[]. If you are using a RijndaelECB * alg then the length of input must equal the block size. * @param input The byte[] to be decrypted * @return The decrypted plaintext bytes. */ public byte[] decryptCopy(byte[] input){ return decryptCopy(input, 0, input.length); }
/** * Decrypts the provided ByteBuffer, returning a new ByteBuffer. Only reads the bytes that are * actually readable, i.e. from position to limit, so equivalent to get()ing into a buffer, * decrypting that and returning. If you are using a RijndaelECB alg then the length of input * must equal the block size. * @param input The buffer to be decrypted * @return A new ByteBuffer containing the plaintext. It will have a backing array and its * arrayOffset() will be 0, its position will be 0 and its capacity will be the length of the * input data. */ public ByteBuffer decryptCopy(ByteBuffer input){ if(input.hasArray()) return ByteBuffer.wrap(decryptCopy(input.array(), input.arrayOffset() + input.position(), input.remaining())); else return ByteBuffer.wrap(decryptCopy(Fields.copyToArray(input))); }
private boolean verifyHeader(byte[] fullHeader) throws IOException, InvalidKeyException { byte[] footer = Arrays.copyOfRange(fullHeader, 0, fullHeader.length-VERSION_AND_MAGIC_LENGTH); int offset = 0; headerEncIV = new byte[type.encryptType.ivSize]; System.arraycopy(footer, offset, headerEncIV, 0, headerEncIV.length); offset += headerEncIV.length; int keySize = type.encryptKey.keySize >> 3; byte[] encryptedKey = new byte[keySize]; System.arraycopy(footer, offset, encryptedKey, 0, keySize); offset += keySize; try { CryptByteBuffer crypt = new CryptByteBuffer(type.encryptType, headerEncKey, headerEncIV); unencryptedBaseKey = KeyGenUtils.getSecretKey(type.encryptKey, crypt.decryptCopy(encryptedKey)); } catch (InvalidKeyException e) { throw new IOException("Error reading encryption keys from header."); } catch (InvalidAlgorithmParameterException e) { throw new IOException("Error reading encryption keys from header."); } byte[] mac = new byte[type.macLen]; System.arraycopy(footer, offset, mac, 0, type.macLen); byte[] ver = ByteBuffer.allocate(4).putInt(version).array(); MessageAuthCode authcode = new MessageAuthCode(type.macType, headerMacKey); return authcode.verifyData(mac, headerEncIV, unencryptedBaseKey.getEncoded(), ver); }
headerEncIV); unencryptedBaseKey = KeyGenUtils.getSecretKey(type.encryptKey, crypt.decryptCopy(encryptedKey)); } catch (InvalidKeyException e) { throw new IOException("Error reading encryption keys from header.");
@Test public void testEncryptDirectByteBuffer() throws GeneralSecurityException { for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; byte[] origPlaintext = Hex.decode(plainText[i]); ByteBuffer plaintext = ByteBuffer.allocateDirect(origPlaintext.length); plaintext.clear(); plaintext.put(origPlaintext); plaintext.clear(); if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } ByteBuffer ciphertext = crypt.encryptCopy(plaintext); plaintext.clear(); byte[] copyPlaintext = new byte[origPlaintext.length]; plaintext.get(copyPlaintext); assertTrue(Arrays.equals(origPlaintext, copyPlaintext)); // Plaintext not modified. plaintext.clear(); assertEquals(ciphertext.remaining(), origPlaintext.length); ByteBuffer deciphered = crypt.decryptCopy(ciphertext); assertTrue(deciphered.equals(plaintext)); byte[] data = new byte[origPlaintext.length]; deciphered.get(data); assertTrue(Arrays.equals(data, origPlaintext)); } }
@Test public void testDecryptWrapByteBuffer() throws GeneralSecurityException { int header = 5; int footer = 5; for(int i = 0; i < cipherTypes.length; i++){ CryptByteBufferType type = cipherTypes[i]; CryptByteBuffer crypt; byte[] origPlaintext = Hex.decode(plainText[i]); byte[] buf = origPlaintext.clone(); if(ivs[i] == null){ crypt = new CryptByteBuffer(type, keys[i]); } else { crypt = new CryptByteBuffer(type, keys[i], ivs[i]); } ByteBuffer plaintext = ByteBuffer.wrap(buf); ByteBuffer ciphertext = crypt.encryptCopy(plaintext); assertTrue(Arrays.equals(buf, origPlaintext)); // Plaintext not modified. assertEquals(ciphertext.remaining(), origPlaintext.length); byte[] decryptBuf = new byte[header+origPlaintext.length+footer]; ciphertext.get(decryptBuf, header, origPlaintext.length); byte[] copyOfDecryptBuf = decryptBuf.clone(); ByteBuffer toDecipher = ByteBuffer.wrap(decryptBuf, header, origPlaintext.length); ByteBuffer deciphered = crypt.decryptCopy(toDecipher); assertTrue(Arrays.equals(decryptBuf, copyOfDecryptBuf)); assertTrue(deciphered.equals(plaintext)); byte[] data = new byte[origPlaintext.length]; deciphered.get(data); assertTrue(Arrays.equals(data, origPlaintext)); } }
@Test public void testDecryptByteArrayIntIntNullInput() 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[] nullArray = null; try{ crypt.decryptCopy(nullArray, 0, plainText[i].length()); fail("CryptByteBufferType: "+type.name()+": Expected IllegalArgumentException or " + "NullPointerException"); }catch(NullPointerException e) { } catch(IllegalArgumentException e){ } } }
ciphertext.position(0); assertTrue(Arrays.equals(altCiphertext, ciphertextBytes)); ByteBuffer deciphered = crypt.decryptCopy(ciphertext); assertTrue(deciphered.equals(plaintext)); byte[] data = new byte[origPlaintext.length];
@Test public void testDecryptByteArrayIntIntLengthOutOfBounds() 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]); } try{ crypt.decryptCopy(Hex.decode(plainText[i]), 0, plainText[i].length()+3); fail("CryptByteBufferType: "+type.name()+": Expected IllegalArgumentException or " + "ArrayIndexOutOfBoundsException"); }catch(IllegalArgumentException e) { } catch (IndexOutOfBoundsException e){ } } }
@Test public void testDecryptByteArrayIntIntOffsetOutOfBounds() 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]); } try{ crypt.decryptCopy(Hex.decode(plainText[i]), -3, plainText[i].length()-3); fail("CryptByteBufferType: "+type.name()+": Expected IllegalArgumentException or " + "ArrayIndexOutOfBoundsException"); }catch(IllegalArgumentException e) { } catch (IndexOutOfBoundsException e){ } } }
ByteBuffer decipheredtext1 = crypt.decryptCopy(ciphertext1); ByteBuffer decipheredtext2 = crypt.decryptCopy(ciphertext2); ByteBuffer decipheredtext3 = crypt.decryptCopy(ciphertext3); assertTrue("CryptByteBufferType: "+type.name(), plain.equals(decipheredtext1)); assertTrue("CryptByteBufferType: "+type.name(), plain.equals(decipheredtext2));
@Test public void testDecryptByteArrayNullInput() 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[] nullArray = null; try{ crypt.decryptCopy(nullArray); fail("CryptByteBufferType: "+type.name()+": Expected NullPointerException"); }catch(NullPointerException e){} } }
crypt = new CryptByteBuffer(type, keys[i], ivs[i]); byte[] decipheredtext = crypt.decryptCopy(ciphertext); assertArrayEquals("CryptByteBufferType: "+type.name(), plain, decipheredtext); decipheredtext = crypt.decryptCopy(ciphertext2); assertArrayEquals("CryptByteBufferType2: "+type.name(), plain, decipheredtext); decipheredtext = crypt.decryptCopy(ciphertext3); assertArrayEquals("CryptByteBufferType3: "+type.name(), plain, decipheredtext);
@Test public void testSuccessfulRoundTripByteArray() 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[] decipheredtext = crypt.decryptCopy(crypt.encryptCopy(Hex.decode(plainText[i]))); assertArrayEquals("CryptByteBufferType: "+type.name(), Hex.decode(plainText[i]), decipheredtext); } }