I made a password generating program some time ago in java.
it generated passwords based on an input string and password.
it used: pbewithMD5andDES
now i'm making a new version of this for mobile devices in javascript.
i found the library crypto-js witch allows me to generate MD5-hashes and encrypt using DES
but i can't seem to generate identical passwords
what am i doing wrong?
java version:
public static String generate(String password, String passphase) throws Exception {
try {
PBEKeySpec pbeKeySpec = new PBEKeySpec(passphase.toCharArray());
PBEParameterSpec pbeParamSpec;
SecretKeyFactory keyFac;
// Salt
byte[] salt = {(byte) 0xc8, (byte) 0x73, (byte) 0x61, (byte) 0x1d, (byte) 0x1a, (byte) 0xf2, (byte) 0xa8, (byte) 0x99};
// Iteration count
int count = 20;
// Create PBE parameter set
pbeParamSpec = new PBEParameterSpec(salt, count);
keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
// Create PBE Cipher
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
// Initialize PBE Cipher with key and parameters
pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);
// Our cleartext
byte[] cleartext = password.getBytes();
// Encrypt the cleartext
byte[] ciphertext = pbeCipher.doFinal(cleartext);
return byteArrayToHexString(ciphertext).substring(0, 12);
} catch (Exception ex) {
throw new Exception(ex.getMessage());
}
}
public static String byteArrayToHexString(byte[] b){
StringBuilder sb = new StringBuilder(b.length * 2);
for (int i = 0; i < b.length; i++){
int v = b[i] & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
}
return sb.toString().toUpperCase();
}
the new javascript version (not compete): (i tried both orders: first hashing then DES, and the oher way around)
var hashedPassword = CryptoJS.MD5(password);
var encryptedPassword = CryptoJS.DES.encrypt(hashedPassword, passphrase).toString();
var result = encryptedPassword.toString().substring(0, 12).toUpperCase();
am i on the right way?
Related
I feel like I have tried everything to get java to PHP using AES; however, I have found that the keys are not the same after I hashed them. I have kept the salt as a string because I couldn't get it to work with an empty byte array; however, it hasn't changed anything. I heard somewhere that dividing the key length by 8 is needed in PHP, so that's why I have it.
I know the hash functions to check for matching works as I have tested it with a random string, and they match up.
JAVA:
public static void main(String[] args) {
SecretKey secret = generateSecret("PASSWORD");
System.out.println(hashString(new String(secret.getEncoded()));
}
public static SecretKey generateSecret(String password) throws Exception {
//byte[] salt = new byte[8];
byte[] salt = "SALT".getBytes("UTF-8");
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);
SecretKey secretKey = factory.generateSecret(keySpec);
return new SecretKeySpec(secretKey.getEncoded(), "AES");
}
public static String hashString(String request) throws Exception {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-512");
byte[] buffer = messageDigest.digest(request.getBytes());
StringBuffer sb = new StringBuffer(buffer.length * 2);
for (int i = 0; i < buffer.length; i++) {
int v = buffer[i] & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
}
return sb.toString().toUpperCase();
}
PHP:
$password = 'PASSWORD';
salt = 'SALT';//pack('nvc*', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
$bytes = derivateKey($password, $salt, 65536, 256);
echo hash('sha512', $bytes);
function derivateKey($password, $salt, $iterations, $keyLengthBits){
return hash_pbkdf2('sha512', $password, $salt, $iterations, $keyLengthBits/8, true);
}
Java returns with this hash:
9E6B73EA6FA176F8D0651AC4DA73F0CEBE603DA6B31A226443CABBB80EDF51BCE663F92945F5DC1C0B8F0098DDE61C3117CCEDFEB7DB4A959315DE635BC7F1BB
php returns with this hash:
135d49502ca99da44f3050f37e7ca0e8ca16c18a9b3120c95bb8cf45e97c0120053c51a3f134fbf38c4105186362086e9504a130dc3ad5633c9968f2b12c1ac6
I referred to the below link
AES Encryption .net to swift,
But, applying the same for ANDROID, I am not able to get the correct AES encryption with version(PBKDF2) conversion for my code. NEED HELP.
public static String Encrypt(String PlainText) throws Exception {
try {
byte[] salt = new byte[] { 0x49, 0x76, 0x61, 0x6E, 0x20, 0x4D,
0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 };
System.out.println("Exception setting up cipher: "+pbkdf2("<keyname>",salt.toString(),1024,128));
Cipher _aesCipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
byte[] keyBytes =pbkdf2("<keyname>",salt.toString(),1024,128).getBytes();
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
byte[] iv ="OFRna73m*aze01xY".getBytes();//pbkdf2("<keyname>",salt.toString(),2,64).getBytes();
IvParameterSpec ivSpec = new IvParameterSpec(iv);
_aesCipher.init(1, keySpec, ivSpec);
byte[] plainText = PlainText.getBytes();
byte[] result = _aesCipher.doFinal(plainText);
return Base64.encodeToString(result, Base64.DEFAULT);//Base64.encode(result,1));
} catch (Exception ex1) {
System.out.println("Exception setting up cipher: "
+ ex1.getMessage() + "\r\n");
ex1.printStackTrace();
return "";
}
}
public static String pbkdf2(String password, String salt, int iterations, int keyLength) throws NoSuchAlgorithmException, InvalidKeySpecException {
char[] chars = password.toCharArray();
PBEKeySpec spec = new PBEKeySpec(chars, salt.getBytes(), iterations, keyLength);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] hash = skf.generateSecret(spec).getEncoded();
return toHex(hash);
}
// Converts byte array to a hexadecimal string
private static String toHex(byte[] array) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < array.length; i++) {
sb.append(Integer.toString((array[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
Please check below code .
I have created Singletone class for the same so that i can access it anywhere in app.
Below Points Should be same like .net or swift
Important Points are IV , SALT and PASSWORD
Please check this too PBKDF2WithHmacSHA1
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
to generate key we used this
KeySpec spec = new PBEKeySpec(password, salt, 2, 256);
Importnant points are (password, salt,iterantion,bytes) this must be same like other platform which you are using with like .net or swift
public class AesBase64Wrapper {
private static String IV = "it should be same like server or other platform";
private static String PASSWORD = "it should be same like server or other platform";
private static String SALT = "it should be same like server or other platform";
private static volatile AesBase64Wrapper sSoleInstance = new AesBase64Wrapper();
//private constructor.
private AesBase64Wrapper() {
}
public static AesBase64Wrapper getInstance() {
return sSoleInstance;
}
// For Encryption
public String encryptAndEncode(String raw) {
try {
Cipher c = getCipher(Cipher.ENCRYPT_MODE);
byte[] encryptedVal = c.doFinal(getBytes(raw));
//String retVal = Base64.encodeToString(encryptedVal, Base64.DEFAULT);
String retVal = Base64.encodeToString(encryptedVal, Base64.NO_WRAP);
return retVal;
}catch (Throwable t) {
throw new RuntimeException(t);
}
}
public String decodeAndDecrypt(String encrypted) throws Exception {
// byte[] decodedValue = Base64.decode(getBytes(encrypted),Base64.DEFAULT);
byte[] decodedValue = Base64.decode(getBytes(encrypted), Base64.NO_WRAP);
Cipher c = getCipher(Cipher.DECRYPT_MODE);
byte[] decValue = c.doFinal(decodedValue);
return new String(decValue);
}
private String getString(byte[] bytes) throws UnsupportedEncodingException {
return new String(bytes, "UTF-8");
}
private byte[] getBytes(String str) throws UnsupportedEncodingException {
return str.getBytes("UTF-8");
}
private Cipher getCipher(int mode) throws Exception {
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = getBytes(IV);
String xyz = String.valueOf(generateKey());
Log.i("generateKey", xyz);
c.init(mode, generateKey(), new IvParameterSpec(iv));
return c;
}
private Key generateKey() throws Exception {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
char[] password = PASSWORD.toCharArray();
byte[] salt = getBytes(SALT);
KeySpec spec = new PBEKeySpec(password, salt, 2, 256);
SecretKey tmp = factory.generateSecret(spec);
byte[] encoded = tmp.getEncoded();
byte b = encoded[1];
Log.e("Secrete Key", String.valueOf(encoded));
return new SecretKeySpec(encoded, "CBC");
}
}
In Activity you can use it like
String EncryptString = AesBase64Wrapper.getInstance().encryptAndEncode("hello");
String DecryptString = AesBase64Wrapper.getInstance().encryptAndEncode(EncryptString);
// You will Get Output in Decrypted String
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have an encrypted AES-256 string from CryptoJS with a passphrase. I need to decrypt it in Java but can't figure out how to do it. It seems that you need IV, key and salt to decrypt, and as in CryptoJS mainpage, the encrypted data already contains all of them, and CryptoJS can somehow parse them out of encrypted input.
Anyone know how to do that? I've seen so much example about CryptoJS - Java encrypt/decrypt but most of them use hardcoded IV/key, or just send IV/key from cryptoJS side to Java side. All I have is a passphrase, just like what this site do!
When a message is encrypted in this way:
CryptoJS.AES.encrypt("message", "passphrase")
a password-based approach is used. For that CryptoJS generates a new salt and uses this salt in conjunction with the passphrase to derive the key and IV (I've recreated a derivation function for this question).
After the ciphertext is produced a special OpenSSL formatter is used to encode the ciphertext including the used salt:
var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);
You need to decode the Base64 encoded string to get the byte array out if it. Then you can check if the header matches:
byte[] ctBytes = Base64.getDecoder().decode(ciphertext.getBytes("UTF-8"));
System.out.println("Is salted: " + new String(Arrays.copyOf(ctBytes, 8)).equals("Salted__"));
After that you can recover the salt and ciphertext from it:
byte[] saltBytes = Arrays.copyOfRange(ctBytes, 8, 16);
byte[] ciphertextBytes = Arrays.copyOfRange(ctBytes, 16, ctBytes.length);
Derive the key+IV:
byte[] key = new byte[keySize/8];
byte[] iv = new byte[ivSize/8];
EvpKDF(password.getBytes("UTF-8"), keySize, ivSize, saltBytes, key, iv);
And decrypt the ciphertext:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"),
new IvParameterSpec(iv));
byte[] recoveredPlaintextBytes = cipher.doFinal(ciphertextBytes);
String recoveredPlaintext = new String(recoveredPlaintextBytes);
Complete code:
public static void main(String[] args) throws UnsupportedEncodingException, GeneralSecurityException {
String ciphertext = "U2FsdGVkX1+0m/gle/XQX1shjnpveUrl1fO3oOlurPMlTks6+oQlEPfOrucihzEz";
String plaintext = "This is some example plaintext";
String password = "This is a very strong password";
int keySize = 256;
int ivSize = 128;
// var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);
byte[] ctBytes = Base64.getDecoder().decode(ciphertext.getBytes("UTF-8"));
System.out.println("Is salted: " + Arrays.equals(Arrays.copyOf(ctBytes, 8), new byte[]{0x53, 0x61, 0x6c, 0x74, 0x65, 0x64, 0x5f, 0x5f}));
System.out.println("Is salted: " + new String(Arrays.copyOf(ctBytes, 8)).equals("Salted__"));
byte[] saltBytes = Arrays.copyOfRange(ctBytes, 8, 16);
System.out.println("Salt matches: " + Arrays.equals(saltBytes, hexStringToByteArray("b49bf8257bf5d05f")));
byte[] ciphertextBytes = Arrays.copyOfRange(ctBytes, 16, ctBytes.length);
System.out.println("CT matches: " + Arrays.equals(ciphertextBytes, hexStringToByteArray("5b218e7a6f794ae5d5f3b7a0e96eacf3254e4b3afa842510f7ceaee722873133")));
byte[] key = new byte[keySize/8];
byte[] iv = new byte[ivSize/8];
EvpKDF(password.getBytes("UTF-8"), keySize, ivSize, saltBytes, key, iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));
byte[] recoveredPlaintextBytes = cipher.doFinal(ciphertextBytes);
String recoveredPlaintext = new String(recoveredPlaintextBytes);
System.out.println("Recovered Plaintext: " + recoveredPlaintext);
System.out.println("Expected Plaintext: " + plaintext);
}
public static byte[] EvpKDF(byte[] password, int keySize, int ivSize, byte[] salt, byte[] resultKey, byte[] resultIv) throws NoSuchAlgorithmException {
return EvpKDF(password, keySize, ivSize, salt, 1, "MD5", resultKey, resultIv);
}
public static byte[] EvpKDF(byte[] password, int keySize, int ivSize, byte[] salt, int iterations, String hashAlgorithm, byte[] resultKey, byte[] resultIv) throws NoSuchAlgorithmException {
keySize = keySize / 32;
ivSize = ivSize / 32;
int targetKeySize = keySize + ivSize;
byte[] derivedBytes = new byte[targetKeySize * 4];
int numberOfDerivedWords = 0;
byte[] block = null;
MessageDigest hasher = MessageDigest.getInstance(hashAlgorithm);
while (numberOfDerivedWords < targetKeySize) {
if (block != null) {
hasher.update(block);
}
hasher.update(password);
block = hasher.digest(salt);
hasher.reset();
// Iterations
for (int i = 1; i < iterations; i++) {
block = hasher.digest(block);
hasher.reset();
}
System.arraycopy(block, 0, derivedBytes, numberOfDerivedWords * 4,
Math.min(block.length, (targetKeySize - numberOfDerivedWords) * 4));
numberOfDerivedWords += block.length/4;
}
System.arraycopy(derivedBytes, 0, resultKey, 0, keySize * 4);
System.arraycopy(derivedBytes, keySize * 4, resultIv, 0, ivSize * 4);
return derivedBytes; // key + iv
}
/**
* Copied from https://stackoverflow.com/a/140861
* */
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
JavaScript code:
var pw = "This is a very strong password";
var pt = "This is some example plaintext";
var encrypted = CryptoJS.AES.encrypt(pt, pw);
encrypted.toString(); // U2FsdGVkX1+0m/gle/XQX1shjnpveUrl1fO3oOlurPMlTks6+oQlEPfOrucihzEz
encrypted.salt.toString(); // b49bf8257bf5d05f
encrypted.ciphertext.toString(); // 5b218e7a6f794ae5d5f3b7a0e96eacf3254e4b3afa842510f7ceaee722873133
I am using this class for encoding/decoding:
public class enc_dec {
public static Cipher dcipher, ecipher;
public enc_dec() {
byte[] salt = { (byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32,
(byte) 0x56, (byte) 0x34, (byte) 0xE3, (byte) 0x03 };
int iterationCount = 19;
try {
// Generate a temporary key. In practice, you would save this key
// Encrypting with DES Using a Pass Phrase
KeySpec keySpec = new PBEKeySpec("".toCharArray(), salt,iterationCount);
SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES")
.generateSecret(keySpec);
ecipher = Cipher.getInstance(key.getAlgorithm());
dcipher = Cipher.getInstance(key.getAlgorithm());
// Prepare the parameters to the cipthers
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt,
iterationCount);
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (Exception e) { }
}
// Encrpt Password
#SuppressWarnings("unused")
public String encrypt(String str) {
try {
// Encode the string into bytes using utf-8
byte[] utf8 = str.getBytes("UTF8");
// Encrypt
byte[] enc = ecipher.doFinal(utf8);
// Encode bytes to base64 to get a string
return new sun.misc.BASE64Encoder().encode(enc);
} catch (Exception e) {
}
return null;
}
// Decrpt password
// To decrypt the encryted password
public String decrypt(String str) {
Cipher dcipher = null;
try {
byte[] salt = { (byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32,
(byte) 0x56, (byte) 0x34, (byte) 0xE3, (byte) 0x03 };
int iterationCount = 19;
try {
String passPhrase = "";
KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(),
salt, iterationCount);
SecretKey key = SecretKeyFactory
.getInstance("PBEWithMD5AndDES")
.generateSecret(keySpec);
dcipher = Cipher.getInstance(key.getAlgorithm());
// Prepare the parameters to the cipthers
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt,
iterationCount);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (Exception e) {}
// Decode base64 to get bytes
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
// Decrypt
byte[] utf8 = dcipher.doFinal(dec);
// Decode using utf-8
return new String(utf8, "UTF8");
} catch (Exception e) {
}
return null;
}
This is my URL-which i am sending from a JSP page:
http://localhost:8080/Sample_Project/send_encode.ENC?type=M0z7jTCb8PPfSZxfAdhw3Q==&payment=UxCU5BdZh4U=&sr_no=eN1X3XOeYuI=
This is my send_encode servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session=request.getSession(false);
if(session.getAttribute("session_set")!=null)
{
classes.enc_dec enc=new classes.enc_dec();
response.setContentType("text/html;charset=UTF-8");
PrintWriter out=response.getWriter();
String type=enc.decrypt(request.getParameter("type"));
String payment=enc.decrypt(request.getParameter("payment"));
long sr_no=Long.parseLong(request.getParameter("sr_no"));
try{
RequestDispatcher comprd = getServletContext().getRequestDispatcher("/new_page.jsp?type="+enc.encrypt(type)+"&payment="+enc.encrypt(payment)+"");
comprd.include(request, response);
}
catch(Exception e)
{
System.out.println("The ecxeption is "+e);
}
}
The exception I am facing is:
WARNING: StandardWrapperValve[send_encode]: Servlet.service() for servlet send_encode threw exception
java.lang.NumberFormatException: For input string: "eN1X3XOeYuI="
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:441)
at java.lang.Long.parseLong(Long.java:483)
at controller.send_encode.doGet(send_encode.java:30)
I have set encoding as UTF-8 but still i am getting the exception.I have also tried other questions posted on SO but unable to get any help.
Thanks in advance
I want to use the PBE to generate other encryption keys.
public SecretKey generateKey(String Ags) throws Exception {
// make password
PBEKeySpec keySpec = new PBEKeySpec(this.password.toCharArray(),this.salt,20,56);
SecretKeyFactory keyFactory = SecretKeyFactory
.getInstance("PBE");
SecretKey key = keyFactory.generateSecret(keySpec);
System.out.println();
/*
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(k);
//
SecretKey FINAL_key = new SecretKeySpec(key.getEncoded(), "AES");
*/
return null;
}
My basic idea is use PBEKeySpec and SecretKeyFactory to generate the PBE key first, and then get the first few bytes, let's say 10 bytes, to generate the AES key. However, after searching the Internet, I still don't know how to get the final key as a byte[]. key.getEncoded() will just give me the input password. How do I get the final key as a byte[]?
As far as i understand by reading the the documentation, i understand that if you want to create a AES secret key you need to feed the algorithm with an at least 128 bit of a key.
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
so to generate key why do you insist getting the 128 bits from the PBE key, instead you can use
byte[] key = (Password+Username).getBytes("UTF-8"); // depends on your implementation
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // AES uses 16 byte of key as a parameter (?)
you can also use the PBE key to feed SHA and get the bytes in that way. Okey let's turn to your problem, here is a full working code from my security folder, i remember this worked for me, please feel free to ask any questions. In the code below, if you check you'll see that the key is generated using the pbeKeySpec however when i review the code, i cannot see what's your fault though.
public void testPBEWithSHA1AndAES() throws Exception {
String password = "test";
String message = "Hello World!";
byte[] salt = { (byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c,
(byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99 };
byte[] iv = { (byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c,
(byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99,
(byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c,
(byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99 };
int count = 1024;
// int keyLength = 256;
int keyLength = 128;
String cipherAlgorithm = "AES/CBC/PKCS5Padding";
String secretKeyAlgorithm = "PBKDF2WithHmacSHA1";
SecretKeyFactory keyFac = SecretKeyFactory
.getInstance(secretKeyAlgorithm);
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), salt,
count, keyLength);
SecretKey tmp = keyFac.generateSecret(pbeKeySpec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher ecipher = Cipher.getInstance(cipherAlgorithm);
ecipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(iv));
// decrypt
keyFac = SecretKeyFactory.getInstance(secretKeyAlgorithm);
pbeKeySpec = new PBEKeySpec(password.toCharArray(), salt, count,
keyLength);
tmp = keyFac.generateSecret(pbeKeySpec);
secret = new SecretKeySpec(tmp.getEncoded(), "AES");
// AlgorithmParameters params = ecipher.getParameters();
// byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
Cipher dcipher = Cipher.getInstance(cipherAlgorithm);
dcipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
byte[] encrypted = ecipher.doFinal(message.getBytes());
byte[] decrypted = dcipher.doFinal(encrypted);
assertEquals(message, new String(decrypted));
ByteArrayOutputStream out = new ByteArrayOutputStream();
CipherOutputStream cipherOut = new CipherOutputStream(out, ecipher);
cipherOut.write(message.getBytes());
StreamUtils.closeQuietly(cipherOut);
byte[] enc = out.toByteArray();
ByteArrayInputStream in = new ByteArrayInputStream(enc);
CipherInputStream cipherIn = new CipherInputStream(in, dcipher);
ByteArrayOutputStream dec = new ByteArrayOutputStream();
StreamUtils.copy(cipherIn, dec);
assertEquals(message, new String(dec.toByteArray()));
}