class CryptoToolchain::Tools::EcbInterpolateChosenPlaintextAttack
Constants
- PAD
Attributes
oracle[R]
Public Class Methods
new(oracle: CryptoToolchain::BlackBoxes::EcbInterpolateChosenPlaintextOracle.new)
click to toggle source
oracle must return an encrypted string via encrypt
# File lib/crypto_toolchain/tools/ecb_interpolate_chosen_plaintext_attack.rb, line 9 def initialize(oracle: CryptoToolchain::BlackBoxes::EcbInterpolateChosenPlaintextOracle.new) @oracle = oracle unless oracle.encrypt(PAD * blocksize * 10).is_ecb_encrypted?(@blocksize) raise ArgumentError.new("Oracle does not appear to encrypt with ECB") end end
Public Instance Methods
execute()
click to toggle source
# File lib/crypto_toolchain/tools/ecb_interpolate_chosen_plaintext_attack.rb, line 16 def execute (0..Float::INFINITY).each_with_object("") do |block_index, solved| from_block = (0...blocksize).each_with_object("") do |i, solved_in_block| padding_length = blocksize - (solved_in_block.bytes.length) - 1 padding = PAD * padding_length target = oracle_encrypt(padding).in_blocks(blocksize)[block_index + prefix_offset] dict = (0..255).map(&:chr).each_with_object({}) do |chr, memo| guess = padding + solved + solved_in_block + chr output = oracle_encrypt(guess).in_blocks(blocksize)[block_index + prefix_offset] memo[output] = chr break(memo) if output == target end if !dict.has_key?(target) return "#{solved}#{solved_in_block}" end solved_in_block << dict.fetch(target) end solved << from_block end end
Private Instance Methods
first_repeated_block()
click to toggle source
# File lib/crypto_toolchain/tools/ecb_interpolate_chosen_plaintext_attack.rb, line 53 def first_repeated_block @first_repeated_block ||= large_padding. group_by(&:itself). sort_by {|k, v| v.length }. last. first end
large_padding(large_pad_size = 1024)
click to toggle source
# File lib/crypto_toolchain/tools/ecb_interpolate_chosen_plaintext_attack.rb, line 49 def large_padding(large_pad_size = 1024) @large_padding ||= oracle.encrypt(PAD * large_pad_size).in_blocks(blocksize) end
oracle_encrypt(str)
click to toggle source
# File lib/crypto_toolchain/tools/ecb_interpolate_chosen_plaintext_attack.rb, line 41 def oracle_encrypt(str) oracle.encrypt(PAD * prefix_padding_length + str) end
prefix_offset()
click to toggle source
# File lib/crypto_toolchain/tools/ecb_interpolate_chosen_plaintext_attack.rb, line 45 def prefix_offset @prefix_offset ||= large_padding.index(first_repeated_block) end
prefix_padding_length()
click to toggle source
# File lib/crypto_toolchain/tools/ecb_interpolate_chosen_plaintext_attack.rb, line 61 def prefix_padding_length return @prefix_padding_length if defined?(@prefix_padding_length) (0..Float::INFINITY).each do |i| if oracle.encrypt(PAD * i).in_blocks(blocksize).include?(first_repeated_block) @prefix_padding_length = i - blocksize return @prefix_padding_length end end end