I am getting an encrypted string from the backend server, which I need to decrypt using private key in Android.The decryption works, but it appends a special character at the end of the decrypted string.
Here is the code I am using:
public static String decryptString(String value, Context context){
value = "Ss7LVqgWeamgPGkt62qSNydTJnwiUet8UemYWR0jzCLOvtW+RazpJmGG657/nWhu5UQGXzEMwIK1jcBXIXkw3EAX6WdocYBKpVJPWpmlEbf4IzPcev67wgx4vd3ylK8KrpPDj92EKE6ElDi/U91e+VS3bhURHye0w9ncaITTm+szGFiDL/fcy+0hnrYJdA3IrElZntYk14SCccb2M0LJ+nTFdfzEgsUH8vW5ei986d4HTKUqBvkoU+JAtHXTYq1sKNSd4L3Xm5fZ0OPpdIKEWqHDntjsMRsX62eTON+iC1OVsKK2vRqvSbVLvE45ww3N6iZNBG1gewcC8v5wJwonmA==";
byte[] decodedBytes = null;
try {
//Cipher c = Cipher.getInstance("AES/ECB/PKCS7Padding", "AndroidOpenSSL");
//Cipher c = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", "AndroidOpenSSL");
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
c.init(Cipher.DECRYPT_MODE, getPrivateKey(context) );
decodedBytes = c.doFinal(Base64.decode(value, Base64.DEFAULT));
//decodedBytes = c.doFinal(value.getBytes("ISO-8859-1"));
} catch (Exception e) {
e.printStackTrace();
}
return new String(decodedBytes);
}
public static PrivateKey getPrivateKey(Context context){
// reads the key_public key stored in a file
InputStream is = context.getResources().openRawResource(R.raw.key_private);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
List<String> lines = new ArrayList<String>();
String line = null;
try {
while ((line = br.readLine()) != null)
lines.add(line);
// removes the first and last lines of the file (comments)
if (lines.size() > 1 && lines.get(0).startsWith("-----") && lines.get(lines.size()-1).startsWith("-----")) {
lines.remove(0);
lines.remove(lines.size()-1);
}
// concats the remaining lines to a single String
StringBuilder sb = new StringBuilder();
for (String aLine: lines)
sb.append(aLine);
String keyString = sb.toString();
byte [] encoded = Base64.decode(keyString, Base64.DEFAULT);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey myPrivKey = keyFactory.generatePrivate(keySpec);
return myPrivKey;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
Finally, I call the first function from the main activity:
String decryptedString = AppUtils.decryptString(encryptedString, MainActivity.this);
I am attaching my private key for reference:
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDuDOP1sBXEKUwR
WQcH459iGj74fGPqnIFJ+cOxNFFeymXs0L0u4n7v6NCAGvZJ5HtdWeUbT+xMMNMW
k8swrQs/qZ36KXzxhL6hy0gj4i86G5L73vQ39g/qlnxhfR+OxhVnDUE4TOt9xhN9
20Mf6xVhVOVmUQwhny6sQqvkhaebzJ32QuTlHFVT8mMGSTwXcHUqRi2ApeyRW9ln
BCLf/P5k+/O5W4lRmyfvumZoipegf0e75hGmgJYxXETomU50DmLMNdQ05/rlpcW5
FEm3Gf60pd+/mqkB+3LlyTPAM7sEfwKgL+CZSqYtz3O/m7tYSK7BtCIbE1bvksjj
bPQA1DYXAgMBAAECggEAZDvDRLEnCRjGccuFvVmnw7v/ZcuimqfZfJeRQa0g0gPx
FNzzu6kc/9GM8VPo/kYZd74hTPXDLnWkfC4w8Ub7pIu7/Bi6Bkv5pNCeiJV1g0cX
BbzkIigWnZVNvBLeVdSsMF8RZi5lPelITcckJW1r7Da9/O4FaKbJFTlhfXCVmXCn
74Bs0q8QZHA/WLwcy5DP+uqdko8T3vtBSPx7HEBbEhy94SEAsQfkdLTa0KQ2WlLI
ythR5DH0GUIoTIBeFsM7w2Ldj7EYbviC8OlIu3h3wHwPutAVzweqsSq5OPAwPnNP
oQZz6gqNaldE0jwVDD8aoLOzCrw1+NW0AmzWJx1VgQKBgQD5g1m8PagCwb/2BQqi
Q3ORjmbHS9dIo3IV+2RM7bYag5fv5CEfApH42rGzPr/pebmYIVQnfYkqDrfHmR95
56+7bOXxKDTkSCdursRa23L3WbIokhLJOPVr7FARc+mKFUEkrpHZcDsIoIUw+Bn4
Sa2myhFvazuJoGpjjAk8olpc1wKBgQD0PT+/ahG5tWW9Nt7wvQfi+KWW5l0fWb+R
ozbuFnZbmKkQZ45bCdU/G3qImtdtTynGX4LjaSyh/vEtebLlrCsfzRc7hQRHpM3o
9tjPUX8zSFNQQA8I7+iTQRQtdiAeOeEt5kethWG9qSbnkBFzkXwVhdvdkhRy4EzW
aKVwU26IwQKBgQCa4oiPq45ht7fbliGVvF0/G7B9QnzvIFavgpAumNkT+GAWj/xn
bYcDfW4VoHwtCFzHLNk6clj0/JHkmw7I86NIqz7JxnWex5OCx4YoCFWDafCH8rUq
p+rhBZ5mVxe/mZYImTz8Rwi+QDatwTUNxV7ATGsqSNx6gFPKW6FYPEfvnQKBgEvd
fqCxjOH3k6urkKKMxRdejukJk2F6mkPdw+E+vvMCv3kmAZULv96DZZNrLYF5tos0
/c4vzDphm365r7Uhvp95MD8/uS2b5o33py72rKE8VQy3aTQoeUDMVT0t1RoudmCw
iBFBPjQQh9Ij8RfJ2BZDZyEzEAEC5TswdDso30vBAoGBAJQqlK6mjhyCmqAs8V2j
vHbzv2/NTG2sYOaMGMsk1Zeh5nQq98rHA/7s1eEkX4AlC38QXisvKi7ywYrlpZoz
+K0Z1sd0tlysH74cK8xWDnLQ4j9l0rD9RtxYHlrdldrsP4P4rE1a2SwAchM3GDpG
R3LcU9BOe9ch+aW3b+PRIkgK
-----END PRIVATE KEY-----
Here is the output:
NDcxMDQ3MjguMTQ2ODg3NTI4MTr4iAAldbBVX2RD3cNw/rlKpmOp1p8YXIYqUVlvX7rmgg==��
The decrypted string should end with "==".Can someone kindly help me to figure out, how to remove the special characters at the end of the decrypted string.
Thanks
These values at the end must have been added during encryption. They are probably 00 valued bytes that were added by a language with null terminated strings or similar. The point is that PKCS#1 unpadding will fail if the ciphertext itself is altered, so the only reasonable explanation is that the values have been included in the plaintext.
Print out the decodedBytes in hexadecimals to find out the values. You can likely get rid of them by using the String#trim() method.
Related
This is related to a situation I find myself in working with saving text files in Unity on Android, then reading them in native Android.
One of the files we read is a HMACMD5 signature, created with the code,
byte[] bData = System.Text.Encoding.UTF8.GetBytes (data);
byte[] bKey = System.Text.Encoding.UTF8.GetBytes (key);
using (HMACMD5 hmac = new HMACMD5(bKey)) {
byte[] signature = hmac.ComputeHash (bData);
return System.Convert.ToBase64String (signature);
}
And then written to the phone with,
public static void SaveText (string path, string data) {
using (FileStream fs = new FileStream(path, FileMode.Create)) {
using (StreamWriter sw = new StreamWriter(fs)) {
sw.Write (data);
}
}
}
The other string we're saving is a JSON string dump. The signature has a newline character at the end of the string, but the JSON string doesn't. I know I can manually add one, but this question is about reading the accurate file contents.
On Android, based on previous SO answers, I read the file with,
String readFile(File file) {
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append("\n");
}
br.close();
}
catch (IOException e) {
MyLogger.e(LOG_TAG, "Error opening file " + file.getPath(), e);
}
return text.toString();
}
I'm manually adding the newline character after every line, but if I do this, I don't accurately read the JSON file, which doesn't have a newline character at the end. If I don't add the newline, I don't accurately read the signature file, which does.
You better then do not use readLine() but read().
I need to use PublicKey to encrypt session key but I have public key as Base64 encoded string so I tried to convert it as :
KeyFactory kf = KeyFactory.getInstance("RSA"); // or "EC" or whatever
byte[] keyBytes = _publicKey.getBytes();
byte[] publicKeyBytes = Base64.decode(keyBytes, Base64.DEFAULT);
X509EncodedKeySpec publicKeySpecs = new X509EncodedKeySpec(publicKeyBytes);
Log.v("", "X509 KS" + publicKeySpecs);
publicKey = kf.generatePublic(publicKeySpecs);
But I am getting public key as null value and getting exception as :
java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
If anyone has idea how to do it or have working code then please help me.
Thanks in Advance
Hi guys I generated Public Key from Base64 encoded String .
after wondering for few days this code worked for me.
String _publicKey= base64encoded_publickey;
// InputStream fileInputStream = null;
try {
// Receiving side
byte[] decodedBytes = Base64.decode(_publicKey, Base64.DEFAULT);
fileInputStream = new ByteArrayInputStream(decodedBytes);
// Print the decoded string
String decodedString = new String(decodedBytes);
CertificateFactory certFactory = CertificateFactory
.getInstance(CERTIFICATE_TYPE);
// certFactory.
X509Certificate cert = (X509Certificate) certFactory
.generateCertificate(fileInputStream);
publicKey = cert.getPublicKey();
Log.d("TAG", "Public key of the certificate:" + publicKey);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Could not intialize encryption module",
e);
} finally {
if (keyStream != null) {
try {
keyStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Hope it will help you...Thanks...
well, last time it worked for me (I used bouncyCastle library..), you might need to modify it if it doesn't suit your need..
KeyPairGenerator keyGen = null;
KeyPair kp = null;
keyGen = KeyPairGenerator.getInstance("ECDSA", "BC");
ECGenParameterSpec ecSpec = new ECGenParameterSpec("brainpoolp160r1");
keyGen.initialize(ecSpec, new SecureRandom());
kp = keyGen.generateKeyPair();
EDIT:
(oops my bad, that's for initial generation..)
at that time I stored them as one..
and I need to convert the Base64 string back to array of byte first, and split them into part 1 and part 2..
private void splitKeyPair (byte[] thekeypair, byte[] part1, byte[] part2)
{
System.arraycopy(thekeypair, 0, part1, 0, 68);
System.arraycopy(thekeypair, 68, part2, 0, 115);
}
byte[] part1 = new byte[68];
byte[] part2 = new byte[115];
splitKeyPair(inputBuffer, part1, part2);
fact = KeyFactory.getInstance("ECDSA", "BC");
kp = new KeyPair(fact.generatePublic(new X509EncodedKeySpec(part1)),
fact.generatePrivate(new PKCS8EncodedKeySpec(part2)));
hope it helps..
*note: the size might vary, depending on the spec..
I encrypt data in Android application and encode it to send over to php webservice.
Then I decode it and decrypt it using $rsa->decrypt(base64_decode($data));
$rsa->decrypt return false. Why is that so?
This is the code in android
//get private key
String privateKeyString = "MIICWwIBAAKBgQDVIJ8H3Oszc5fWdgpwymWksF1WxkXJHIfdS6Ta1bHeqwEzPIkN f3iVk14LfaoSZpRb9Yvi/jvkXxIzJbHq6aKfnQOC6tKIiixvVvpCfxr1eV4urDdz H9RNy9bqGdXzTQdgQi+KRx0Dcy9RNsl7ZGLAGrUFRnPI4GTdH+7wm4QogQIDAQAB AoGAcUcKX7KC7HDm5h0NRY+94H/AzItLsi3Q5MT81Tc5d+EqHSJysdLrs4yFMtRS 3b7Z4dqrxDVefe4uDTNe0j3lqboKz8oKwAU+paKx3wubHb7aeQnfzwM9mPQJHgEO zBjlvbL4oEa/gklu3VohZAc1daqpPajdWuOQQp4S+jUllrECQQDrITlSjvkxt8ud /vYIcEXHew3iW4nzaAH3z4PRAGZofRpk/OusGZ6cdZoYMTZcdxYTCCbZ5eeyGukW 5QCadie1AkEA6Atx8Z0F7WhLI2lGvCGy+vIOL0vBDZSma0cvLYLAXMx8duoWQ9J2 LwT7SsnRXMeq/8wlNHL7mFEf+YFZBKKlHQJAO78kfrr/zUdjwREBWaGVyZuWKpeS FTyvi1W6rAgK/bAUXeb6x69241DqyAzxQEuuW0WuAZ5u4o39/qhQH++4JQJAAepe RW1TaDNNM3yh/dmVXabz4QYSEOeiPA55YDnNFrcFbAHgryyklxzGakaiOM7ZJYVs 5TLxyr8YsXmU34nsLQJALzC8CaFXJcnU0+6+KoKX7iq1aP3X4LgP4Gianix6pfRo aV8UHnfFLRSgPdn1ZYmKtJfnsJXJYoE+o9xEErb5EQ==";
// converts the String to a PublicKey instance
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey key = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(Base64.decode(privateKeyString.toString(), Base64.DEFAULT)));
// encrypts the message
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encrpytedText = cipher.doFinal(Base64.encode(phoneUid.getBytes("CP1252"), Base64.DEFAULT));
data = new String(encrpytedText, "CP1252");
This is the code in php
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
//Set the encryption mode
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
//check for required fields
if (isset($_POST['data']) {
$data= $_POST['data'];
$key = '-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVIJ8H3Oszc5fWdgpwymWksF1W xkXJHIfdS6Ta1bHeqwEzPIkNf3iVk14LfaoSZpRb9Yvi/jvkXxIzJbHq6aKfnQOC 6tKIiixvVvpCfxr1eV4urDdzH9RNy9bqGdXzTQdgQi+KRx0Dcy9RNsl7ZGLAGrUF RnPI4GTdH+7wm4QogQIDAQAB
-----END PUBLIC KEY-----';
$rsa->loadKey($key );
$decrypted = $rsa->decrypt(base64_decode($data));
I solved my problem. Here is a reference for those who are doing similar thing to me. Hope that this will help other people.
In android (RSA encrypt with private key)
String encoded = null;
byte[] encrypted = null;
String plaintext = "...";
try {
String privKeyPEM = "...";
byte[] decoded = Base64.decode(privKeyPEM, Base64.DEFAULT);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decoded);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privKey = kf.generatePrivate(spec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, privKey);
encrypted = cipher.doFinal(plaintext.getBytes());
encoded = Base64.encodeToString(encrypted, Base64.DEFAULT);
}
catch (Exception e) {
e.printStackTrace();
}
In PHP (decrypt with public key) (using phpseclib)
$publickey = '...';
$rsa = new Crypt_RSA();
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
//decode and decrypt
$decoded = base64_decode($encrypted);
$rsa->loadKey($publickey);
$decrypted = $rsa->decrypt($decoded);
Are you passing the right parameters to cipher.doFinal?
Quoting the javadoc entry:
doFinal(byte[] inBuff, short inOffset, short inLength, byte[] outBuff, short outOffset)
Also, it looks like you're base64-encoding the plaintext before encryption when you should be encrypting the ciphertext after encryption?
I am using this (Android: decrypt RSA text using a Public key stored in a file) as a guideline to encrypt a "string" using a public key and then decrypting with private key in ruby.
However, I am having difficulty. Part of the reason is that I am encrypting the bytes in Java and then when I am decrypting in Ruby I am not translating it.
I am attaching the Android snippet below:
// reads the public key stored in a file
AssetManager am = mContext.getAssets();
InputStream is = am.open("public_key.pem");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
List<String> lines = new ArrayList<String>();
String line = null;
while ((line = br.readLine()) != null)
lines.add(line);
// removes the first and last lines of the file (comments)
if (lines.size() > 1 && lines.get(0).startsWith("-----") && lines.get(lines.size()-1).startsWith("-----")) {
lines.remove(0);
lines.remove(lines.size()-1);
}
// concats the remaining lines to a single String
StringBuilder sb = new StringBuilder();
for (String aLine: lines)
sb.append(aLine);
String keyString = sb.toString();
// converts the String to a PublicKey instance
byte[] keyBytes = Base64.decode(keyString.getBytes("utf-8"), 0);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey key = keyFactory.generatePublic(spec);
//byte[] encryptedText = null;
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
String encryptedText = Base64.encodeToString(cipher.doFinal(message), 0);
return encryptedText;
I am using following code in ruby to try and decode the encrypted data
pkey = OpenSSL::PKey::RSA.new private_key
print pkey.private_decrypt(Base64.decode64(android_encrypted_value))
I noticed a problem right away when testing that the base64 values generated in Java doesnt match the ones I generated in another code in ruby.
Any idea?
The following change worked for me:
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
cipher.init(Cipher.ENCRYPT_MODE, key);
String encryptedText = Base64.encodeToString(cipher.doFinal(message), Base64.DEFAULT);
I was able to apply this to my Ruby code and make it work.
So I've seen a lot of examples, and done a lot of googling, and looked at examples on Stack Overflow... and I need help. I've got an Android application and I'm storing username and passwords on the device, and I need to encrypt them AES 256. From looking at examples, this is what I have so far:
public class Security {
Cipher ecipher;
Cipher dcipher;
// 8-byte Salt
byte[] salt = {
(byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
(byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03
};
// Iteration count
int iterationCount = 19;
public Security (String passPhrase) {
try {
// Create the key
KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
SecretKey key = SecretKeyFactory.getInstance(
"PBEWithSHAAndAES").generateSecret(keySpec);
ecipher = Cipher.getInstance(key.getAlgorithm());
dcipher = Cipher.getInstance(key.getAlgorithm());
// Prepare the parameter to the ciphers
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
// Create the ciphers
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (Exception e) {
e.printStackTrace();
}
}
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 Base64.encodeToString(enc, Base64.DEFAULT);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public String decrypt(String str) {
try {
// Decode base64 to get bytes
byte[] dec = Base64.decode(str, Base64.DEFAULT);
// Decrypt
byte[] utf8 = dcipher.doFinal(dec);
// Decode using utf-8
return new String(utf8, "UTF8");
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
I'm trying to make it password based, so a user will create an account the first time using the username and password needed to communicate back to the server, and create a PIN that will be used as the key for these credentials stored in the database.
What I'm mainly concerned about is does this look secure? I know a fixed salt is bad, how do I fix that?
I know there's been like a billion questions about this, but I want someone to just come out and say "THIS IS SECURE" or "THIS IS NOT SECURE, CHANGE THIS"
Thanks!
EDIT:
So this is the code I have so far, and it seems to be working...
public class Security {
Cipher ecipher;
Cipher dcipher;
byte[] salt = new byte[8];
int iterationCount = 200;
public Security(String passPhrase) {
try {
// generate a random salt
SecureRandom random = new SecureRandom();
random.nextBytes(salt);
// Create the key
KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
SecretKey key = SecretKeyFactory.getInstance(
"PBEWithSHA256And256BitAES-CBC-BC").generateSecret(keySpec);
ecipher = Cipher.getInstance(key.getAlgorithm());
dcipher = Cipher.getInstance(key.getAlgorithm());
// Prepare the parameter to the ciphers
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
// Create the ciphers
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (Exception e) {
e.printStackTrace();
}
}
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 Base64.encodeToString(enc, Base64.DEFAULT);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public String decrypt(String str) {
try {
// Decode base64 to get bytes
byte[] dec = Base64.decode(str, Base64.DEFAULT);
// Decrypt
byte[] utf8 = dcipher.doFinal(dec);
// Decode using utf-8
return new String(utf8, "UTF8");
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public int getIterationCount() {
return iterationCount;
}
public String getSalt() {
return Base64.encodeToString(salt, Base64.DEFAULT);
}
}
I used this code to test it:
Security s = new Security(pinBox.getText().toString());
String encrypted = s.encrypt(passwordBox.getText().toString());
String decrypted = s.decrypt(encrypted);
builder.setMessage("pin: " + pinBox.getText().toString() + "\n" +
"password: " + passwordBox.getText().toString() + "\n" +
"encrypted: " + encrypted + "\n" +
"decrypted: " + decrypted + "\n" +
"salt: " + s.getSalt());
So I don't need to worry about an initialization vector? Or specifically hardcode a Cipher algorithm?
Thanks again!
EDIT: While the code below is correct, what you have is doing basically the same thing, with the IV derived from the password, so you don't have to store it separately.
Does your code work as expected? For the actual encryption/decryption you would want to use AES, most probably in CBC mode. Then you would need an IV, so it becomes something like this:
ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = new byte[IV_LENGTH];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
ecipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(iv));
byte[] enc = ecipher.doFinal(utf8);
Whether it is secure depends on what you are using this for. The purpose of the salt is to make it harder to brute force the passphrase: if it's random the attacker cannot use pre-generated passphrase tables (passphrase->key). If you are not too worried about this sort of attack, you might leave it fixed. If you decide to make it random, just store it with the encrypted data. Same with the IV.