Skip to content

Instantly share code, notes, and snippets.

@trevor-vaughan
Created February 3, 2016 21:02
Show Gist options
  • Save trevor-vaughan/c9a9f8b0a045f6a7cc1e to your computer and use it in GitHub Desktop.
Save trevor-vaughan/c9a9f8b0a045f6a7cc1e to your computer and use it in GitHub Desktop.
Generate and validate GRUB2 compatible Password Hashes in Ruby
#!/usr/bin/env ruby
require 'openssl'
def pack_salt(salt)
return salt.scan(/../).map{|x| x.hex }.pack('c*')
end
def unpack_salt(salt)
return salt.unpack('H*').first.upcase
end
def grub2_mkpasswd_pbkdf2(password, salt, rounds=10000)
salt ||= (0...63).map{|x| x = (65 + rand(26)).chr }.join
digest = OpenSSL::Digest::SHA512.new
hashed_password = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, rounds, digest.digest_length, digest).unpack('H*').first.upcase
return "grub.pbkdf2.sha512.#{rounds}.#{unpack_salt(salt)}.#{hashed_password}"
end
def grub2_validate_pbkdf2(password, pbkdf2_hash)
if pbkdf2_hash =~ /(grub\.pbkdf2.*)/
pbkdf2_hash = $1
else
raise "Error: No valid GRUB2 PBKDF2 password hash found"
end
id, type, algorithm, rounds, hashed_salt, hashed_password = pbkdf2_hash.split('.')
rounds = rounds.to_i
salt = pack_salt(hashed_salt)
return "grub.pbkdf2.sha512.#{rounds}.#{hashed_salt}.#{hashed_password}" == grub2_mkpasswd_pbkdf2(password, salt, rounds)
end
## Quick Validation ##
hash = grub2_mkpasswd_pbkdf2('foo',nil)
puts "Generated Hash is: " + hash
puts "Self-generated hash validates: " + grub2_validate_pbkdf2('foo',hash).to_s
testval = 'PBKDF2 hash of your password is grub.pbkdf2.sha512.10000.8C1DE0B1F01975BBF3BD4CC8767B0D22C36675F59956F36A227AF7AAF5A1966320FE2D0ED6A49F7361D345037F20B4FBBC7244440D7C80015F13CE4555606E10.13231A7E06A823FBB95625111A9E9C2E9D84219F65C771DE062B329D2E977ADA832E43537D8136063916D594C4B57533447897D48132C6C5FBCD68CB547DA488'
puts "grub-mkpasswd-pbkdf2 generated hash validates: " + grub2_validate_pbkdf2('foo',testval).to_s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment