Class: CryptoToolchain::Tools::EcbInterpolateChosenPlaintextAttack
- Includes:
- DetermineBlocksize
- Defined in:
- lib/crypto_toolchain/tools/ecb_interpolate_chosen_plaintext_attack.rb
Constant Summary collapse
- PAD =
"A".freeze
Instance Method Summary collapse
- #execute ⇒ Object
-
#initialize(oracle: CryptoToolchain::BlackBoxes::EcbInterpolateChosenPlaintextOracle.new) ⇒ EcbInterpolateChosenPlaintextAttack
constructor
oracle must return an encrypted string via #encrypt.
Methods included from DetermineBlocksize
Constructor Details
#initialize(oracle: CryptoToolchain::BlackBoxes::EcbInterpolateChosenPlaintextOracle.new) ⇒ EcbInterpolateChosenPlaintextAttack
oracle must return an encrypted string via #encrypt
9 10 11 12 13 14 |
# 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 |
Instance Method Details
#execute ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# 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 |