I am trying to read a file of size 1KB, then encrypting and decrypting it with AES algorithm in CBC mode. When I am trying to initialize cipher it is throwing an error. Please find the code below.
I could not find an init method in cipher class which accepts "encryption mode", "secret key", and the initialization vector of class IvParameterSpec. I can see init method with expecting parameters like(int encryption mode, Key key, AlgorithmParameters algoParameters, SecureRandom secureRandom)
Do I need to convert my key and initialization vector to the required class.
Any insights to proceed further would be helpful.
import sun.security.provider.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.io.File;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidParameterSpecException;
public class AESFileEncryptionDecryption {
public class AES128CBC{
SecretKey secretKey;
Cipher cipher;
SecureRandom secureRandom = new SecureRandom();
byte[] iv = new byte[16];
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
{
try {
secretKey = KeyGenerator.getInstance("AES").generateKey();
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(1,secretKey,ivParameterSpec);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
File inputFile_1KB = new File("/Users/siddharthsinha/Desktop/input1KB.txt");
File encryptedFile_1KB = new File("/Users/siddharthsinha/Desktop/input1KB.encrypted");
File decryptedFile_1KB = new File("/Users/siddharthsinha/Desktop/input1KB.decrypted.txt");
}
}
your code is neither catching nor throwing two possibly thrown exceptions:
try {
secretKey = KeyGenerator.getInstance("AES").generateKey();
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(1,secretKey,ivParameterSpec);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
Related
Im working on a custom protocol that works via UDP. The packets sent across the network are encoded with AES/CBC/NOPADDING algorithm in a JAVA client.
Im using a python3 client, so i need to decrypt this packets. My question is if there is any implementation of AES/CBC/NOPADDING in python3.
Im currently using this to decode in python:
def decrypt(key, data):
from Crypto.Hash.MD5 import MD5Hash
if data is None:
return None
cipher = AES.new(key.encode('utf8'), AES.MODE_CBC, bytes([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]))
return cipher.decrypt(data)
But the data return is random and not well decoded.
However, i can succesfuly decode the packets in java like this:
Cipher cipher;
try {
cipher = Cipher.getInstance("AES/CBC/NOPADDING");
try {
cipher.init(Cipher.DECRYPT_MODE, aesKey, new IvParameterSpec(iv));
try {
cipher.doFinal(buffer, *** ...);
} catch (ShortBufferException | IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
}
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
e.printStackTrace();
}
}
Here i put a working example:
Firstr, i encrypt on java:
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.io.UnsupportedEncodingException;
import java.util.List;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class MyClass {
public static void main(String args[]) {
String keyBytes = "UfrGUmAJq86pVtkd";
String text_to_encrypt = "topotatopotatota";
SecretKey aesKey = new SecretKeySpec(keyBytes.getBytes(), "AES");
byte [] iv = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
Cipher cipher;
try {
cipher = Cipher.getInstance("AES/CBC/NOPADDING");
try {
cipher.init(Cipher.ENCRYPT_MODE, aesKey, new IvParameterSpec(iv));
try {
String test = Base64.getEncoder().encodeToString(cipher.doFinal(text_to_encrypt.getBytes("UTF-8")));
System.out.println(test);
} catch (IllegalBlockSizeException | UnsupportedEncodingException | BadPaddingException e ) {
e.printStackTrace();
}
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
e.printStackTrace();
}
}
}
Late i decode in python:
from hashlib import md5
from base64 import b64decode
from base64 import b64encode
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad
class AESCipher:
def __init__(self, key):
self.key = md5(key.encode('utf8')).digest()
def decrypt(self, data):
raw = b64decode(data)
self.cipher = AES.new(self.key, AES.MODE_CBC, bytes([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]))
return self.cipher.decrypt(raw)
if __name__ == '__main__':
key = "UfrGUmAJq86pVtkd"
expectedt_result = "topotatopotatota"
encrypted_data = "ynCF3bJejxlLn1aAk8vcAw=="
cipher = AESCipher(key)
decrypted_data = cipher.decrypt(encrypted_data)
print(decrypted_data)
I am new to React Native.
The server side guy has written encryption logic in Java which goes as following
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
#Service
public class AES {
#Autowired
static AesProps props;
private static String secretkey = "abcdefghijklmnopqhijklmnopq"; // Sample key
private static SecretKeySpec secretKey;
private static byte[] key;
public static void setKey(String myKey) {
MessageDigest sha = null;
try {
key = myKey.getBytes("UTF-8");
sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
secretKey = new SecretKeySpec(key, "AES");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
public static String encrypt(String strToEncrypt) {
try {
setKey(secretkey);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
} catch (Exception e) {
System.out.println("Error while encrypting: " + e.toString());
}
return null;
}
I am trying to find a way to encrypt in React Native, which will give me the same cipher as above Java code.
I went through react-native-aes-cryptobut many things are missing. Like how to use PKCS5PADDING and how to do corresponding SecretKeySpec.
Any help would be much appreciated.
I'm trying to convert JAVA Code into Objective - C language. I have a requirement where I should Use the same code that Android developers are using. Code follows as
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class EncDec {
public static void main(String args[])
{
String reqMessage="{\"accountType\":\"ALL\",\"uId\":\"c8ff46be-a083-4009-8a33-fc2d22cc40e3|123456784\",\"deviceId\":\"qvxy1234\"}";
Map requestMap=new HashMap();
requestMap.put("body", reqMessage);
String bodyString=(String) requestMap.get("body");
String authKey="M/98hZivBqJQftMHsPvMgg&&";
String encString= encode(authKey,bodyString);
System.out.println("encString ::: "+ encString);
String decString= decode(authKey,encString);
System.out.println("decString ::: "+ decString);
}
public static String encode(String keyString, String stringToEncode) throws NullPointerException {
if (keyString.length() == 0 || keyString == null) {
throw new NullPointerException("Please give Password");
}
if (stringToEncode.length() == 0 || stringToEncode == null) {
throw new NullPointerException("Please give text");
}
try {
SecretKeySpec skeySpec = getKey(keyString);
byte[] clearText = stringToEncode.getBytes("UTF8");
// IMPORTANT TO GET SAME RESULTS ON iOS and ANDROID
final byte[] iv = new byte[16];
Arrays.fill(iv, (byte) 0x00);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// Cipher is not thread safe
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);
byte[] encryptedByte=cipher.doFinal(clearText);
String encrypedValue = new String(Base64.encodeBase64(encryptedByte));
System.out.println("Encrypted: " + stringToEncode + " -> " + encrypedValue);
return encrypedValue;
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return "";
}
/**
* Decodes a String using AES-128 and Base64
*
* #param context
* #param password
* #param text
* #return desoded String
*/
public static String decode(String password, String text) throws NullPointerException {
if (password.length() == 0 || password == null) {
throw new NullPointerException("Please give Password");
}
if (text.length() == 0 || text == null) {
throw new NullPointerException("Please give text");
}
try {
SecretKey key = getKey(password);
// IMPORTANT TO GET SAME RESULTS ON iOS and ANDROID
final byte[] iv = new byte[16];
Arrays.fill(iv, (byte) 0x00);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
byte[] encrypedPwdBytes = Base64.decodeBase64(text.getBytes());
// cipher is not thread safe
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
byte[] decrypedValueBytes = (cipher.doFinal(encrypedPwdBytes));
String decrypedValue = new String(decrypedValueBytes);
System.out.println("Decrypted: " + text + " -> " + decrypedValue);
return decrypedValue;
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return "";
}
/**
* Generates a SecretKeySpec for given password
*
* #param password
* #return SecretKeySpec
* #throws UnsupportedEncodingException
*/
private static SecretKeySpec getKey(String password) throws UnsupportedEncodingException {
// You can change it to 256 if you wish
int keyLength = 128;
byte[] keyBytes = new byte[keyLength / 8];
// explicitly fill with zeros
Arrays.fill(keyBytes, (byte) 0x0);
// if password is shorter then key length, it will be zero-padded
// to key length
byte[] passwordBytes = password.getBytes("UTF-8");
int length = passwordBytes.length < keyBytes.length ? passwordBytes.length : keyBytes.length;
System.arraycopy(passwordBytes, 0, keyBytes, 0, length);
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
return key;
}
}
So I want this to be converted in to Objective C. I don't know how to do this. Help me out in this !!
I have searched some code in JAVA And I tried of doing it. But the problem is it will give some other decrypted data but not the exact one that gives using this code. So If I convert the same thing I may get the exact code I guess.
People might be knowing JAVA as well as Objective c here. Those people can help me i guess.
I'm not sure, but you can try it :).
For the encode phase :
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// Cipher is not thread safe
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);
byte[] encryptedByte=cipher.doFinal(clearText);
String encrypedValue = new String(Base64.encodeBase64(encryptedByte));
Using CCCrypt in Obj-C :
CCCryptorStatus CCCrypt(
CCOperation op, //is kCCEncrypt in your case
CCAlgorithm alg, //is kCCAlgorithmAES128
CCOptions options, //is kCCModeCBC
const void *key, //may be skeySpec
size_t keyLength,
const void *iv, // is your iv key : ivParameterSpec
const void *dataIn,
size_t dataInLength,
void *dataOut, /* data RETURNED here */
size_t dataOutAvailable,
size_t *dataOutMoved)
__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0);
Please reference : CCCrypt decrypting in AES CBC works even without IV
for more information, Hope this help you.
Hey I got the answer go through these links below you will get the exact code for Android and IOS...
https://gist.github.com/m1entus/f70d4d1465b90d9ee024
I've been staring at this code for hours, and I must be missing something silly. As a result someone's help here is greatly appreciated.
Below is example code, the simplest I could get it to repro this issue. The code works fine the first time it runs, but then after the preference has been created for the IV, it fails then after.
My real code has much more stored in preferences than this one, I simplified it a lot in troubleh shooting to make it easier to isolate.
My goal is to create a class that allows me to store preferences encrypted with AES 128 encryption with a key derived from a user-supplied password. e.g. Secure preferences. I took out all the user-supplied pwd stuff in troubleshooting.
package com.test;
import java.io.UnsupportedEncodingException;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidParameterSpecException;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.Preferences;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import org.apache.commons.codec.binary.Base64;
public class Settings {
private Preferences prefs = null;
private byte[] iv = null;
private SecretKey secret = null;
Cipher cipher = null;
public static void main(String[] args){
Settings t = new Settings();
String encText = t.encryptText("HELLO");//Encrypt a value
String output = t.decryptText(encText);//Decrypt the value
System.out.println(output); //Display the decrypted value.
}
public Settings(){
try {
String parentClass = new Exception().getStackTrace()[1].getClassName();//Really only controls where the prefs go, shouldn't matter.
this.prefs = Preferences.userNodeForPackage(Class.forName(parentClass));
Random r = new SecureRandom();
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128); // 128 bit key
this.secret = keyGen.generateKey();
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
} catch (Exception ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
}
}
private String encryptText(String plainText){
try {
cipher.init(Cipher.ENCRYPT_MODE, this.secret);
AlgorithmParameters params = cipher.getParameters();
this.iv = prefs.getByteArray("IV", null);
if(this.iv == null){
this.iv = params.getParameterSpec(IvParameterSpec.class).getIV();
prefs.putByteArray("IV", this.iv);
}
byte[] ciphertext = cipher.doFinal(plainText.getBytes("UTF-8"));
String ret = new String(Base64.encodeBase64(ciphertext));
return ret;
} catch (InvalidParameterSpecException | IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException | InvalidKeyException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
}
return "";
}
private String decryptText(String cipherText){
try {
this.iv = prefs.getByteArray("IV", null);
byte[] cText = Base64.decodeBase64(cipherText);
cipher.init(Cipher.DECRYPT_MODE, this.secret, new IvParameterSpec(this.iv));
String ret = new String(cipher.doFinal(cText), "UTF-8");
return ret;
} catch (IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException | InvalidKeyException | InvalidAlgorithmParameterException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
}
return "";
}
}
Stacktrace that is only received on 2+ runs:
Feb 07, 2015 9:02:46 PM com.test.Settings decryptText
SEVERE: null
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
at javax.crypto.Cipher.doFinal(Cipher.java:2087)
at com.test.Settings.decryptText(Settings.java:77)
at com.test.Settings.main(Settings.java:34)
------------ EDIT Correct Answer ------------
As GregS pointed out, I didn't load the IV into the encrypt routine when the preference existed, as a result there was a mismatch. Below is the updated encrypt function which the problem fixed.
private String encryptText(String plainText){
try {
this.iv = prefs.getByteArray("IV", null);
if(this.iv == null) { //If not set, set the IV
cipher.init(Cipher.ENCRYPT_MODE, this.secret);
AlgorithmParameters params = cipher.getParameters();
this.iv = params.getParameterSpec(IvParameterSpec.class).getIV();
prefs.putByteArray("IV", this.iv);
} else {
cipher.init(Cipher.ENCRYPT_MODE, this.secret, new IvParameterSpec(this.iv));
}
byte[] ciphertext = cipher.doFinal(plainText.getBytes("UTF-8"));
String ret = new String(Base64.encodeBase64(ciphertext));
return ret;
} catch (InvalidParameterSpecException | IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException | InvalidKeyException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
} catch (InvalidAlgorithmParameterException ex) {
Logger.getLogger(Settings.class.getName()).log(Level.SEVERE, null, ex);
}
return "";
}
As GregS pointed out, I didn't load the IV into the encrypt routine when the preference existed, as a result there was a mismatch. Below is the updated encrypt function which the problem fixed.
private String encryptText(String plainText){
try {
this.iv = prefs.getByteArray("IV", null);
if(this.iv == null) { //If not set, set the IV
cipher.init(Cipher.ENCRYPT_MODE, this.secret);
AlgorithmParameters params = cipher.getParameters();
this.iv = params.getParameterSpec(IvParameterSpec.class).getIV();
prefs.putByteArray("IV", this.iv);
} else {
cipher.init(Cipher.ENCRYPT_MODE, this.secret, new IvParameterSpec(this.iv));
}
byte[] ciphertext = cipher.doFinal(plainText.getBytes("UTF-8"));
String ret = new String(Base64.encodeBase64(ciphertext));
return ret;
} catch (InvalidParameterSpecException | IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException | InvalidKeyException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
} catch (InvalidAlgorithmParameterException ex) {
Logger.getLogger(Settings.class.getName()).log(Level.SEVERE, null, ex);
}
return "";
}
Here it is program for encryption and Decryption using DES. program is working when passing the output of encryption directly for decryption. but when taking input from user in string to decrypt, it showing this exception. how to pass cipher string in bytes so it becomes compatible for decryption?
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKeyFactory;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.DESKeySpec;
import javax.xml.bind.DatatypeConverter;
public class DESEncryptionDecryption {
private static Cipher encryptCipher;
private static Cipher decryptCipher;
public static void main(String[] args) throws InvalidKeySpecException {
try {
String desKey = "0123456789abcdef"; // value from user
byte[] keyBytes = DatatypeConverter.parseHexBinary(desKey);
System.out.println(keyBytes);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKey key = factory.generateSecret(new DESKeySpec(keyBytes));
encryptCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptedData = encryptData("Confidential data"); //String from user
String s=encryptedData.toString();//String input to decrypt From user
byte[] bb=s.getBytes();
decryptCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, key);
decryptData(bb); //Exception
}catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}}
//method for encryption
private static byte[] encryptData(String data)
throws IllegalBlockSizeException, BadPaddingException {
System.out.println("Data Before Encryption :" + data);
byte[] dataToEncrypt = data.getBytes();
byte[] encryptedData = encryptCipher.doFinal(dataToEncrypt);
System.out.println("Encryted Data: " + encryptedData);
return encryptedData;
}
//method for decryption
private static void decryptData(byte[] data)
throws IllegalBlockSizeException, BadPaddingException {
byte[] textDecrypted = decryptCipher.doFinal(data); //Exception trigered here
System.out.println("Decryted Data: " + new String(textDecrypted));
}}
I can't easily tell whether this is all that's wrong, but this is definitely wrong:
byte[] encryptedData = encryptData("Confidential data"); //String from user
String s=encryptedData.toString();//String input to decrypt From user
byte[] bb=s.getBytes();
Just decrypt encryptedData instead of of bb. Your s value is basically useless, because you've called toString() on a byte[], which won't give you what you're apparently expecting. The value of s will be something like "[B#15db9742" because arrays don't override toString() in Java.
If you really want to turn arbitrary binary data (such as the result of encryption) into text, use base64 instead. Encode the result of encryption using base64 to get a string, and then later base64-decode it from the string to a byte array, then decrypt that byte array.
Oh, and I'd strongly recommend against using String(byte[]) or String.getBytes() too - always use the overloads which take a character encoding instead.