Monday, May 14, 2018

MySQL AES Encryption in Ruby

I was asked to find a way to encrypt strings in Ruby that would be compatible with MySQL's AES_ENCRYPT and AES_DECRYPT functions. I found several solutions online, but none of them worked the way I expected. After cobbling together several examples, I finally came up with a solution that proved to be compatible with the MySQL version. This was written for use with Ruby 2.3.5.
require 'openssl'
# This module provides AES encryption compatible with MySQL AES_ENCRYPT
# and AES_DECRYPT functions.
module MySQLEncryption
# Takes an unencrypted text string, encrypts it with the password,
# and encodes the results to a hexadecimal string
def self.mysql_encrypt(unencrypted_text, password)
encrypt(unencrypted_text, mysql_key(password))
end
# Takes an encrypted, hex-encoded text string
# and decrypts it with the password
def self.mysql_decrypt(encrypted_hex, password)
decrypt(encrypted_hex, mysql_key(password))
end
# Encode a binary value to hexadecimal
def self.bin_to_hex(binary)
binary.unpack('H*').first
end
# Decode a hex value into a binary
def self.hex_to_bin(hex)
hex.scan(/../).map {|digit| digit.hex}.pack('c*')
end
protected
def self.aes(method, mysql_key, text)
aes = OpenSSL::Cipher::Cipher.new('aes-128-ecb')
aes.send(method)
aes.key = mysql_key
aes.update(text) << aes.final
end
def self.encrypt(unencrypted_text, mysql_key)
bin_to_hex(aes(:encrypt, mysql_key, unencrypted_text))
end
def self.decrypt(encrypted_hex, mysql_key)
aes(:decrypt, mysql_key, hex_to_bin(encrypted_hex))
end
def self.mysql_key(key)
final_key = "\0" * 16
key.length.times do |i|
final_key[i % 16] = (final_key[i % 16].ord ^ key[i].ord).chr
end
final_key
end
end
This module can be used as follows:
require 'my_sql_encryption'
text = 'Sensitive data'
encrypted = MySQLEncryption.mysql_encrypt(text, @password)
decrypted = MySQLEncryption.mysql_decrypt(encrypted, @password)
log.info("Encrypted: #{encrypted}")
log.info("Decrypted: #{decrypted}")
expect(decrypted).to eq(text)

Tuesday, May 01, 2018

Running a Tomcat-based Spring Boot application in Docker

In one of the projects I am working on, I was tasked from taking a Tomcat application that ran on an EC2 server, and get it running with the Spring Boot framework in a Docker container. The twist is that the application needed read-write access to the resources folder within the project. In order to do that, the application needed to be run as an "exploded" WAR file (It had been run that way on the old server as well).

I accomplished this with this Docker file:

FROM openjdk:8-alpine
ENV TZ America/New_York
RUN ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime
RUN echo "${TZ}" > /etc/timezone
# Declare the working directory
WORKDIR /microservice
# Copy and explode the WAR to the working directory
COPY my-application/target/*-exec.war /microservice.war
RUN jar xvf /microservice.war
RUN rm /microservice.war
# RUN the microservice
ENTRYPOINT ["java", "org.springframework.boot.loader.WarLauncher"]

The WAR file is compiled with the "spring-boot-maven-plugin", and includes all the dependency JARs, so the application can be run stand-alone.

That entry in the POM is:

...
<packaging>war</packaging>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
...
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
...
view raw pom.xml hosted with ❤ by GitHub

And the "org.springframework.boot.loader.WarLauncher" Class is what Spring Boot uses to bootstrap the applicatiton on the embedded Tomcat.