Adding Encryption to Groovy Configuration Files
¾È¿µÇϼ¼¿ä. Last post, I explained how groovy could be used for configuration. Like any good programmer, I like to stick my code in VCS which includes my configurations. You may remember from my last post that passwords were in my configuration files. Now, it's just stupid to stick passwords in your VCS. We all would rather not do it. It's the easiest thing to do though. The only way to get away with it is to encrypt your passwords when you put them into VCS. The question becomes, "How do you decrypt them then?" I encrypted my passwords with RSA public/private key encryption. I then base64 encode the encrypted result for adding to VCS.
Here is an example
cfg = new NodeBuilder().cfg {
db {
url 'jdbc:oracle:thin:@localhost:1521:UAZKFCFG'
ua {
name 'ua'
password decrypt('cfg', 'GHp6V73vu5Q4D9OR8SEoOFkstv0rqhJ97yTfgMAPnIjkbDIDZT9NBQIIvsy4sdRrXWju6ZFeG12tB3qVLdJOl3PlefeTq/KactkUVGU5Yv0iKQW19Wto7YVWMJUfwmI+Te/Nd+snLkhQixFBXoncjMAJF652+UIhwUiDHASn6GJ8McuiwjOvkUSTl1VLbOeF8zZu0DNzBzADic8M/Y4mbBT9aFtmgXfM2RZ8WxpT+7s475JAgieqp+gCUvskrn238zMCXEJvJgmk+de4u2mmYF6O1FZN/LzSyoh2NRLaKv4IU2Zz+U58DSLYUScIqIskWIxIRVSdibOLVUJZd8wSoOO2+DbS1/23FE55RzVjOXW7bJMTsTFhwpm4SaFt2kdoPVHxjVRKvagOKgj48ciT7gf4houRPlhG4kxD/piRax1sr8OLHGlv6ZxPBB6zVSw9WXL7S3sj9UNO6NGd0CccJXgOu8EqZyqV8lIJV1axSLuCye83RAoGYqDX9+x8msMotpfyDv+W/RHwb9ssmjhr8iCRK/8oxrhZO7yXVU7QJyuwelaGPzW+kQXTIvgLecO93mcr57Bh20GUXCEr2o3uFYh18+JRnoliLKfpAm7QrFw3xbiAmfulhnBXbGDjsCKvqXFnZFAZFkjbI1CT8yiDchobh/c2DxwyytLeNc4aIj4=')
}
}
}
Notice I call a method called decrypt(). I pass in two values that are teh environment name and the encrypted password. I pass in the environment name because I have a separate public/private key for each environment entry. To distinguish them during decryption, I have to pass this value into my decryption method.
This is how the decrypt() method works
import java.io.DataInputStream
import java.io.File
import java.io.FileInputStream
import java.security.KeyFactory
import java.security.PrivateKey
import java.security.PublicKey
import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.X509EncodedKeySpec
import javax.crypto.Cipher;
DEFAULT_CIPHER = "RSA/ECB/PKCS1Padding";
KEY_FACTORY_TYPE = "RSA";
SSH_DIR_PATH = System.getProperty('user.home') + File.separator + '.ssh' + File.separator
...
...
String decrypt(String environment, String pw) {
def key = getPrivateKey(environment)
cipher = Cipher.getInstance(DEFAULT_CIPHER);
cipher.init(Cipher.DECRYPT_MODE, key);
return new String(cipher.doFinal(pw.decodeBase64()));
}
PrivateKey getPrivateKey(String environment) {
def keyBytes = new File(SSH_DIR_PATH + "kfs_$environment").readBytes()
def spec = new PKCS8EncodedKeySpec(keyBytes);
def keyFactory = KeyFactory.getInstance(KEY_FACTORY_TYPE);
return keyFactory.generatePrivate(spec);
}
There you go. Encryption of values in the configuration file. With this, you wouldn't just be able to encrypt passwords, but whatever you want to securely store in your VCS from your configuration. I feel like the guy from lifelock! Enjoy!