So, I saw a lot of examples and did a lot to search on Google, and looked at the examples on Stack Overflow ... and I need help. I have an Android app and I store the username and passwords on the device and I need to encrypt them with AES 256. From a look at the examples, this is what I still have:
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 am trying to do this based on a password, so the user will first create an account using the username and password required to communicate with the server and create a PIN code that will be used as a key for these credentials stored in the database.
What I'm mostly worried about is it looking safe? I know that fixed salt is bad, how can I fix it?
I know that it was like a billion questions, but I want someone to just go out and say, “THIS IS SAFE” or “THIS IS NOT SAFE, CHANGE THIS”
Thanks!
EDIT:
So this is the code that I still have, and it seems to work ...
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 do not need to worry about the initialization vector? Or, in particular, the hardcode encryption algorithm?
Thanks again!