Most web applications connect to a database, which means that they need to store the database password in a file. While that file should only be readable by the user running the application server, security can be further improved by encrypting the password in the file. The encryption passphrase is then stored in the code of your application. This means that an attacker would not only have to get access to the password file, but also to the application code to decrypt the password. Here's a simple implementation of AES 256 encryption/decryption in Ruby. I've run it in JRuby using Java 1.7, and it requires you to install "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" for your JRE. On Mac OS, after extracting the zip file I had to copy
Then, you can encrypt
And decrypt it back like this:
US_export_policy.jar
and local_policy.jar
to /Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/jre/lib/security/
.# file_crypto.rb require 'openssl' class FileCrypto def initialize(passphrase, iv_passphrase, salt) @key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(passphrase, salt, 2000, 32) @iv = OpenSSL::PKCS5.pbkdf2_hmac_sha1(iv_passphrase, salt, 2000, 16) end def read(filepath) decrypt(IO.read(filepath)) end def write(filepath, plaintext) IO.write(filepath, encrypt(plaintext)) end def encrypt(data) cipher = OpenSSL::Cipher::AES256.new(:CBC) cipher.encrypt cipher.key = @key cipher.iv = @iv cipher.update(data) + cipher.final end def decrypt(data) cipher = OpenSSL::Cipher::AES256.new(:CBC) cipher.decrypt cipher.key = @key cipher.iv = @iv cipher.update(data) + cipher.final end end
Then, you can encrypt
test password
like this:require_relative 'file_crypto' fc = FileCrypto.new( 'j7U2 k92M%qc mw}f;T@6cAlH', 'cZd !W7Xf2PMQY#Xprt)n', '28Ca kDl^vYuO' ) fc.write('/tmp/encpassword', 'test password')
And decrypt it back like this:
require_relative 'file_crypto' fc = FileCrypto.new( 'j7U2 k92M%qc mw}f;T@6cAlH', 'cZd !W7Xf2PMQY#Xprt)n', '28Ca kDl^vYuO' ) puts fc.read('/tmp/encpassword')