Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
require 'openssl'
encrypt_me = "what a fine day for coding" # Data to encrypt
@aes_key = (1..16).to_a.pack("C*") # Dummy bad key
@aes_iv = (17..32).to_a.pack("C*") # Dummy bad initialization vector
cipher = OpenSSL::Cipher::AES.new(128, :CBC)
cipher.encrypt # Put it in "encrypt" mode, doesn't actually encrypt
cipher.key = @aes_key
cipher.iv = @aes_iv
ciphertext = cipher.update(encrypt_me) + cipher.final
def decrypt(data)
cipher = OpenSSL::Cipher::AES.new(128, :CBC)
cipher.padding = 0
cipher.decrypt # Put it in "decrypt" mode, doesn't actually decrypt
cipher.key = @aes_key
cipher.iv = @aes_iv
plaintext = cipher.update(data)
last_octet = plaintext[-1].ord
padding = plaintext[-last_octet..-1]
is_padding_valid = padding.bytes.all? { |b| b == last_octet }
raise "BAD PADDING" unless is_padding_valid
return "Data processed"
end
ciphertext.freeze
decrypt_data = ciphertext.dup
recovered = {}
(1..16).each do |i|
position = 16-i
(0..255).each do |guess|
decrypt_data[position] = guess.chr
begin
decrypt(decrypt_data)
rescue
next
end
recovered[position] = ciphertext[position].ord ^ guess ^ i
(1..i).each do |j|
z = 16 - j
decrypt_data[z] = (ciphertext[z].ord ^ recovered[z] ^ (i+1)).chr
end
break
end
end
pp recovered.sort.map { |k, v| v }.pack("c*")
require 'openssl'
class PaddingError < StandardError
end
@aes_key = OpenSSL::Random.random_bytes(16)
def encrypt_data(plaintext)
new_iv = OpenSSL::Random.random_bytes(16)
cipher = OpenSSL::Cipher::AES.new(128, :CBC)
cipher.encrypt
cipher.key = @aes_key
cipher.iv = new_iv
ciphertext = cipher.update(plaintext) + cipher.final
[ciphertext.freeze, new_iv.freeze]
end
def process_data(iv, data)
cipher = OpenSSL::Cipher::AES.new(128, :CBC)
cipher.padding = 0
cipher.decrypt
cipher.key = @aes_key
cipher.iv = iv
plaintext = cipher.update(data)
last_octet = plaintext[-1].ord
raise PaddingError if plaintext.length - last_octet < 0
padding = plaintext[-last_octet..-1]
is_padding_valid = padding.bytes.inject(0) { |a, b|
a | (b ^ last_octet)
}.zero?
raise PaddingError unless is_padding_valid
# Process data
return true
end
ciphertext, iv = encrypt_data('what a fine day for coding')
decrypt_data = ciphertext.dup
recovered = {}
(1..16).each do |i|
position = 16-i
found = false
(0..255).each do |guess|
next if guess == ciphertext[position].ord && i == 1
decrypt_data[position] = guess.chr
begin
process_data(iv, decrypt_data)
rescue PaddingError
next
end
recovered[position] = ciphertext[position].ord ^ guess ^ i
(1..i).each do |j|
z = 16 - j
decrypt_data[z] = (ciphertext[z].ord ^ recovered[z] ^ (i+1)).chr
end
found = true
break
end
raise "Could not match padding." unless found
end
pp recovered.sort.map { |k, v| v }.pack("c*")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.