We are living as nomad in Georgia !!

[Ruby] Implement encryption / decryption by AES GCM mode

Contents

Requirement

Need to load OpenSSL library.

Ruby

require 'openssl'

Encryption

1. Initialize a cipher for AES GCM.

Ruby

# For AES-256-GCM
cipher = OpenSSL::Cipher.new('aes-256-gcm')

# For AES-128-GCM
cipher = OpenSSL::Cipher.new('aes-128-gcm')

2. Start to encrypt.

Ruby

cipher.encrypt

3. Set iv (initialization vector)

iv must be 12 bytes.

Ruby

# When setting random iv from library.
iv = cipher.random_iv

# When setting iv yourself.
iv = '000000000000'
cipher.iv = iv

4. Set a secret key.

key must be 16 bytes.

Ruby

# When setting random key from library.
key = cipher.random_key

# When setting key yourself.
key = '0000000000000000'
cipher.key = key

5. Set an authentication data.

auth data can be allowed empty string but it would be better to set something value.

Ruby

authData = 'authentication'
cipher.auth_data = authData

6. Finish to encrypt.

Ruby

plainText = 'noknow'
cipherText = cipher.update(plainText) + cipher.final

# Will be output like "xBFxF4xF0xC9~x94".

7. Get the authentication tag.

Ruby

authTag = cipher.auth_tag

# Will be output like "OxA6xECxCEpxF8xCExD20xCBxC8xCAxDxAC/".

How to use

You need to memorize all cipherText, iv, key, authData and authTag to decrypt it.

The method 1

When you have key and authData in environment variable, you need to memorize cipherText, iv and authTag. And also you want to convert all cipherText, iv and authTag together to hex string.

Ruby

hexString = (cipherText + iv + authTag).unpack('H*').first

# Will be output like "bff4f0c97e943030303030303030303030304fa6ecce70f8ced230cbc8cade08ac2f".

The method 2

When converting all tof them to base64 string.

Ruby

base64Str = Base64.strict_encode64(cipherText + iv + key + authData + authTag)

# Will be output like "v/TwyX6UMDAwMDAwMDAwMDAwc8iyduA6VGwlJ/4aV+p372F1dGhlbnRpY2F0aW9uT6bsznD4ztIwy8jK3gisLw==".

Decryption

1. Initialize a cipher for AES GCM.

Ruby

# For AES-256-GCM
cipher = OpenSSL::Cipher.new('aes-256-gcm')

# For AES-128-GCM
cipher = OpenSSL::Cipher.new('aes-128-gcm')

2. Start to decrypt.

Ruby

cipher.decrypt

3. Set iv (initialization vector)

iv must be 12 bytes and the value you set when encrypted.

Ruby

cipher.iv = iv

4. Set a secret key.

key must be 16 bytes and the value you set when encrypted.

Ruby

cipher.key = key

5. Set the authentication data.

auth data must be the value you set when encrypted.

Ruby

cipher.auth_data = authData

6. Set the authentication tag.

auth tag must be the value you set when encrypted.

Ruby

cipher.auth_tag = authTag

7. Finish to decrypt.

Ruby

plainText = cipher.update(cipherText) + cipher.final

# Will be output like "noknow".

How to use

When decrypted, The data when encrypted is required.

The method 1

This is related to Encryption -> How to use -> The method 1 section.

So hex string would be included cipherText, iv and authTag. You need to convert from hex string to raw data at first.

Ruby

# hexString = (cipherText + iv + authTag).unpack('H*').first
# hexString would be like "bff4f0c97e943030303030303030303030304fa6ecce70f8ced230cbc8cade08ac2f".
rawData = [hexString].pack('H*')

# Get cipherText, iv and authTag.
cipherText = rawData.slice(0, rawData.length - 28)
iv = rawData.slice(rawData.length - 28, 12)
authTag = rawData.slice(rawData.length - 16, 16)

Related articles