Last active
December 20, 2015 05:58
-
-
Save robvinson/6081872 to your computer and use it in GitHub Desktop.
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
#!/usr/bin/env ruby | |
require 'openssl' | |
SHA1 = OpenSSL::Digest::SHA1.new | |
# Verified functionality against | |
# Test Vector (http://tools.ietf.org/html/draft-josefsson-pbkdf2-test-vectors-06#page-3) | |
# Input: | |
# P = "password" (8 octets) | |
# S = "salt" (4 octets) | |
# c = 4096 | |
# dkLen = 20 | |
# | |
# Output: | |
# DK = 4b 00 79 01 b7 65 48 9a | |
# be ad 49 d9 26 f7 21 d0 | |
# 65 a4 29 c1 (20 octets) | |
# With a known salt and password and derived key, we can brute force the | |
# number of iterations it took to derive the key. | |
def bf_iteration(salt, password, derived_key, pbkdf2_dKeyLen) | |
(1..65536).each do |i| | |
try_iteration(salt, password, derived_key, pbkdf2_dKeyLen, i) | |
end | |
puts "Sorry, number of iterations not found" | |
end | |
def try_iteration(salt, password, hash, pbkdf2_dKeyLen, pbkdf2_num_iterations) | |
dk = OpenSSL::PKCS5.pbkdf2_hmac_sha1(password, salt, pbkdf2_num_iterations, pbkdf2_dKeyLen) | |
if dk == hash | |
puts "!!! Found, form of PBKDF2(salt, password, dKLen:#{pbkdf2_dKeyLen}, Iterations:#{pbkdf2_num_iterations})" | |
puts "input hash:#{hash.unpack('H*')[0]} generated hash:#{dk.unpack('H*')[0]}" | |
exit | |
elsif ((hash.length == 20) and (SHA1.digest(dk) == hash)) | |
puts "!!! Found, form of SHA1(PBKDF2(salt, password, dKlen:#{pbkdf2_dKeyLen}, Iterations:#{pbkdf2_num_iterations}))" | |
puts "input hash:#{hash.unpack('H*')[0]} generated hash:#{SHA1.digest(dk).unpack('H*')[0]}" | |
exit | |
end | |
end | |
if ARGV.length != 3 | |
puts "Usage: #{$0} password salt hash\n" | |
puts "Password: The password" | |
puts "Salt: salt bytes as a hex string" | |
puts "Hash: hash bytes as a hex string" | |
exit | |
end | |
password = ARGV[0] | |
salt_hex = ARGV[1] | |
hash_hex = ARGV[2] | |
unless ((salt_hex =~ /[0-9a-zA-z]/) and ((salt_hex.length % 2) == 0)) | |
puts "Error: Invalid salt, try again" | |
exit | |
end | |
unless ((hash_hex =~ /[0-9a-zA-z]/) and ((hash_hex.length % 2) == 0)) | |
puts "Error: Invalid key, try again" | |
exit | |
end | |
salt = [salt_hex].pack('H*') | |
hash = [hash_hex].pack('H*') | |
#bf_iteration(salt, password, hash, 20) | |
#[20, 24].each do |dklen| | |
(1..1024).each do |dklen| | |
puts "12,345 iterations: trying with derived key length of #{dklen}(#{dklen*8}bits)" | |
try_iteration(salt, password, hash, dklen, 12345) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment