Search code examples
servletsencryptionpassword-encryption

Encrypt passwords in a WebApp


I'm developing a WebApp using JavaEE (Servlets + JSP).

I have found a problem when I want to write some passwords in my app, like a SMTP password. While I'm debugging I have write it in plain, inside the code or in properties file, but I would like to encrypt them somehow.

What I do in developing stage:

private static final String SMTP_PASS = "my_pass";

How could I do that? Any ideas/examples?


Solution

  • private static final String SMTP_PASS = "my_pass_identifier"; //here my_pass_identifier is not the actual password its just an identifier to identify the SMTP password
    

    Create a properties file for storing passwords in encrypted form in key/val pairs. Note you can encrypt the password using EncryptDecrypt class mentioned below and pass the encrypted password in the properties file

    SMTP_PASS = nPDHgg/DYzcL2+HsvYZruw==javaxMQyYxBZUsf7c0gh+vkisQA==javax0w+9tvuLzY04TA5FyTVSPw==
    

    Create a class CredentialUtilities which will decrypt the password by reading the password.properties file

    public class CredentialUtilities {
        static PasswordEncrypt pe = new PasswordEncrypt();
        public static String  getCredentials(String identifier) throws Exception{
    
            String credential = "";
            Properties prop = new Properties();
            InputStream input = null;
    
            try {
               String filename = "password.properties";
                input = CredentialUtilities.class.getClassLoader().getResourceAsStream(filename);
                prop.load(input);
                String property = prop.getProperty(identifier);
                credential = pe.decrypt(property); 
            } catch (IOException ex) {
                ex.printStackTrace();
            } finally{
                if(input!=null){
                    try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                }
            }
            return credential;
    
        }
    }
    

    Create a class that will Encrypt/Decrypt you password for you

    import java.security.NoSuchAlgorithmException;
    import java.util.Base64;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    
    public class EncryptDecrypt {
        public static String ALGORITHM = "AES";
        private static String AES_CBS_PADDING = "AES/CBC/PKCS5Padding";
        private static int AES_128 = 128;
    
    
        private static byte[] encryptDecrypt(final int mode, final byte[] key, final byte[] IV, final byte[] message)
                throws Exception {
            final Cipher cipher = Cipher.getInstance(AES_CBS_PADDING);
            final SecretKeySpec keySpec = new SecretKeySpec(key, ALGORITHM);
            final IvParameterSpec ivSpec = new IvParameterSpec(IV);
            cipher.init(mode, keySpec, ivSpec);
            return cipher.doFinal(message);
        }
    
        public static Map<String, SecretKey> keyGenerator() throws NoSuchAlgorithmException{
            Map<String, SecretKey> map = new HashMap<String, SecretKey>();
             KeyGenerator keyGenerator = KeyGenerator.getInstance(EncryptDecrypt.ALGORITHM);
             keyGenerator.init(AES_128);
             SecretKey key = keyGenerator.generateKey();
             map.put("key", key);
             SecretKey IV = keyGenerator.generateKey();
             map.put("iv", IV);
             return map;
    
        }
    
    
        public static String encrypt(String message) throws Exception{
            Map<String , SecretKey> map = keyGenerator();
            SecretKey key = map.get("key");
            SecretKey IV = map.get("iv");
            byte[] cipherText = encryptDecrypt(Cipher.ENCRYPT_MODE, key.getEncoded(), IV.getEncoded(), message.getBytes());
            String encrypted_message =  Base64.getEncoder().encodeToString(cipherText);
            String encodedKey = Base64.getEncoder().encodeToString(map.get("key").getEncoded());
            String encodedIV = Base64.getEncoder().encodeToString(map.get("iv").getEncoded());
    
            return encrypted_message+"javax"+encodedIV+"javax"+encodedKey;
    
    
    
        }
    
        public static String decrypt(String encryptedMessage) throws Exception{
            String[] result = encryptedMessage.split("javax");
            byte[] decodedIV = Base64.getDecoder().decode(result[1]);
            byte[] decodedKey = Base64.getDecoder().decode(result[2]);
            byte[] cipher_text = Base64.getDecoder().decode(result[0]);
            SecretKey IV = new SecretKeySpec(decodedIV, 0, decodedIV.length, "AES");
            SecretKey key = new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");    
            byte[] decryptedString = encryptDecrypt(Cipher.DECRYPT_MODE, key.getEncoded(), IV.getEncoded(), cipher_text);
            String decryptedMessage = new String(decryptedString);
            return decryptedMessage;
    
        }
    
    
        public static void main(String[] args) throws Exception {
            EncryptDecrypt cu = new EncryptDecrypt();
            String encryptedmessage =  cu.encrypt("usrpswd");
            System.out.println(encryptedmessage);
            String decryptedMessage = cu.decrypt(encryptedmessage);
            System.out.println(decryptedMessage);
        }
    
    }
    

    You can now get the decrypted password whereever you want using.

    String SMTP_PASSWORD = new CredentialUtilities().getCredentials(SMTP_PASS);