Created
March 26, 2022 07:56
-
-
Save knugie/0637a1bcfd38302a64358b88c4b3b70f to your computer and use it in GitHub Desktop.
WIP: Ruby AES Encryption using AES-256-GCM
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'openssl' | |
################ | |
# Public Input # | |
################ | |
hex_message = 'a9a08f273d9e96d567ccc3db8f6a6634c895973a260e2b7cb36c1dde457293102163900cc12ffe4ec51aa02db70a0979b510911fa99d50aeadd67f7ff0c37a8ab82e5e45cb4b7d713e8365b1f0e67e188e2807fa31f674f25318de6de122517a06cfa018e0edf308eeaa87530720ecdcac42' | |
auth_data = 'something' | |
################ | |
# Secret Input # | |
################ | |
password = 'Pa$$w0rd!' | |
################################################################################ | |
message = [hex_message].pack('H*') | |
cipher_text = message[0..-29] | |
iv = message[-28..-17] | |
auth_tag = message[-16..-1] | |
alg = 'aes-256-gcm' | |
cipher = OpenSSL::Cipher.new(alg) | |
cipher.decrypt | |
cipher.iv = iv | |
cipher.key = Digest::SHA256.new.update(password).digest | |
cipher.auth_data = auth_data | |
cipher.auth_tag = auth_tag | |
plain_text = cipher.update(cipher_text) + cipher.final | |
################# | |
# Secret Output # | |
################# | |
puts plain_text |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'openssl' | |
# We use the AES 256 bit Galois/Counter Mode (GCM) symetric encryption. | |
# AES 256 is virtually impenetrable using brute-force methods. | |
# However, CBC introduces a data integrity vulnerability (stream cipher attacks). | |
# We use GCM to mitigate the issue. This mode of operation is an authenticated | |
# encryption algorithm designed to provide both data authenticity (integrity) and confidentiality. | |
alg = 'aes-256-gcm' | |
cipher = OpenSSL::Cipher.new(alg) | |
cipher.encrypt | |
cipher.auth_tag_len = 128 | |
# => OpenSSL::Cipher::CipherError: unable to set authentication tag length | |
# :-( Ferguson and Saarinen: If the tag length t is shorter than 128, then each successful forgery in this attack increases the probability that subsequent targeted forgeries will succeed | |
################ | |
# Secret Input # | |
################ | |
plain_text = 'All the non-obvious zeros of the zeta function are complex numbers with real part 1/2.' | |
password = 'Pa$$w0rd!' # Please choose a strong password! Hackers don't break in – they log in ;-) | |
################ | |
# Public Input # | |
################ | |
# For security as part of the encryption algorithm, we create a random | |
# initialization vector. An initialization vector (iv) is used to prevent | |
# a sequence of text that is identical to a previous sequence from producing | |
# the same exact ciphertext when encrypted. It does not need to be kept secret. | |
iv = cipher.random_iv | |
# For security as part of the encryption algorithm, we set any additional | |
# authenticated data (AAD) in order to generate a suitable authentication tag. | |
# The authentication strength depends on the length of the authentication tag, | |
# like with all symmetric message authentication codes. The use of shorter authentication | |
# tags with GCM is discouraged. The bit-length of the tag, denoted t, is a security parameter. | |
auth_data = 'something' | |
################################################################################ | |
# We use SHA256 as a key derivation function to get a 256 bit key from the initial password | |
key = Digest::SHA256.new.update(password).digest | |
raise 'iv must have length 12' unless iv.length == 12 | |
cipher.iv = iv | |
raise 'key must have length 32' unless key.length == 32 | |
cipher.key = key | |
cipher.auth_data = auth_data | |
cipher_text = cipher.update(plain_text) + cipher.final | |
cipher.auth_tag_len=128 | |
auth_tag = cipher.auth_tag | |
raise 'auth_tag must have length 16' unless auth_tag.length == 16 | |
message = cipher_text + iv + auth_tag | |
hex_message = (message).unpack('H*').first | |
################# | |
# Public Output # | |
################# | |
puts hex_message |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment