title: Mimic AES_ENCRYPT and AES_DECRYPT functions in Ruby
body: <p>I need to mimic what MySQL does when encrypting and decrypting strings using built-in functions AES_ENCRYPT() and AES_DECRYPT().</p>
  
  <p>I have read a couple of blog posts and apparently MySQL uses AES 128-bit encryption for those functions. On top of that, since this encryption requires a 16-bit key, MySQL pads the string with x0 chars (\0s) until it's 16-bit in size.</p>
  
  <p>The algorithm in C from MySQL source code is spotted <a href="http://gtowey.blogspot.com/2009/01/mysql-aes-encryption-compatability.html" rel="nofollow noreferrer">here</a>.</p>
  
  <p>Now I need to replicate what MySQL does in a Rails application, but every single thing I tried, doesn't work. </p>
  
  <p>Here's a way to replicate the behavior I am getting:</p>
  
  <p>1) Create a new Rails app</p>
  
  <pre><code>rails encryption-test
  cd encryption-test
  </code></pre>
  
  <p>2) Create a new scaffolding</p>
  
  <pre><code>script/generate scaffold user name:string password:binary
  </code></pre>
  
  <p>3) Edit your config/database.yml and add a test MySQL database</p>
  
  <pre><code>development:
      adapter: mysql
      host: localhost
      database: test
      user: &lt;&lt;user&gt;&gt;
      password: &lt;&lt;password&gt;&gt;
  </code></pre>
  
  <p>4) Run the migration</p>
  
  <pre><code>rake db:migrate
  </code></pre>
  
  <p>5) Enter console, create an user and update its password from MySQL query</p>
  
  <pre><code>script/console
  Loading development environment (Rails 2.2.2)
  &gt;&gt; User.create(:name =&gt; "John Doe")
  &gt;&gt; key = "82pjd12398JKBSDIGUSisahdoahOUASDHsdapdjqwjeASIduAsdh078asdASD087asdADSsdjhA7809asdajhADSs"
  &gt;&gt; ActiveRecord::Base.connection.execute("UPDATE users SET password = AES_ENCRYPT('password', '#{key}') WHERE name='John Doe'")
  </code></pre>
  
  <p>That's where I got stuck. If I attempt to decrypt it, using MySQL it works:</p>
  
  <pre><code>&gt;&gt; loaded_user = User.find_by_sql("SELECT AES_DECRYPT(password, '#{key}') AS password FROM users WHERE id=1").first
  &gt;&gt; loaded_user['password']
  =&gt; "password"
  </code></pre>
  
  <p>However if I attempt to use OpenSSL library, there's no way I can make it work:</p>
  
  <pre><code>cipher = OpenSSL::Cipher::Cipher.new("AES-128-ECB") 
  cipher.padding = 0
  cipher.key = key
  cipher.decrypt 
  
  user = User.find(1)
  cipher.update(user.password) &lt;&lt; cipher.final #=&gt; "########gf####\027\227"
  </code></pre>
  
  <p>I have tried padding the key:</p>
  
  <pre><code>desired_length = 16 * ((key.length / 16) + 1)
  padded_key = key + "\0" * (desired_length - key.length)
  
  cipher = OpenSSL::Cipher::Cipher.new("AES-128-ECB") 
  cipher.key = key
  cipher.decrypt 
  
  user = User.find(1)
  cipher.update(user.password) &lt;&lt; cipher.final #=&gt; ""|\e\261\205:\032s\273\242\030\261\272P##"
  </code></pre>
  
  <p>But it really doesn't work.</p>
  
  <p>Does anyone have a clue on how can I mimic the MySQL AES_ENCRYPT() and AES_DECRYPT() functions behavior in Ruby?</p>
  
  <p>Thanks! </p>