From d2c5ced57a6b9b33b8a6419d521ea887b7ef23da Mon Sep 17 00:00:00 2001 From: Stephen Waits Date: Thu, 30 Sep 2010 22:37:29 -0700 Subject: [PATCH] update to ruby 1.9. add command line version (passyquick.rb). --- hmac.rb | 13 ++++-- passy => passy.rb | 18 ++++++-- passyquick.rb | 102 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+), 7 deletions(-) rename passy => passy.rb (92%) create mode 100755 passyquick.rb diff --git a/hmac.rb b/hmac.rb index 333dae6..dfa74d2 100644 --- a/hmac.rb +++ b/hmac.rb @@ -32,6 +32,11 @@ def byte_string(byte, length) ([byte]*length).pack('C*') end +# helper to make a 'length' long string filled with 'byte' +def byte_array(byte, length) + ([byte]*length) +end + # hmac algorithm - returns text version of hmac def hmac(key, data, digest_object, blocksize) # if key is too long, hash it @@ -41,12 +46,12 @@ def hmac(key, data, digest_object, blocksize) key += byte_string(0,blocksize - key.size) if key.size < blocksize # create pads - ipad = byte_string(0x36,blocksize) - opad = byte_string(0x5c,blocksize) - blocksize.times { |i| ipad[i] ^= key[i]; opad[i] ^= key[i] } + ipad = byte_array(0x36,blocksize) + opad = byte_array(0x5c,blocksize) + blocksize.times { |i| ipad[i] ^= key[i].ord; opad[i] ^= key[i].ord } # do the HMAC and return - digest_object.hexdigest( opad + digest_object.digest( ipad + data ) ) + digest_object.hexdigest( opad.pack('C*') + digest_object.digest( ipad.pack('C*') + data ) ) end # hmac-md5 diff --git a/passy b/passy.rb similarity index 92% rename from passy rename to passy.rb index cbc7dec..241755d 100755 --- a/passy +++ b/passy.rb @@ -22,15 +22,27 @@ # THE SOFTWARE. # -require 'hmac' +require_relative 'hmac' # list of sites we visit Sites = %w( - paypal.com + apple.com + thawte.com + adp.com + amazon.com + apmex.com boardgamegeek.com + bulkregister.com + directv.com + facebook.com google.com - mahaenergy.com + intrade.com + lendingclub.com ma.gnolia.com + mahaenergy.com + mint.com + netflix.com + paypal.com ) # make sure our hmac is working properly diff --git a/passyquick.rb b/passyquick.rb new file mode 100755 index 0000000..95b4878 --- /dev/null +++ b/passyquick.rb @@ -0,0 +1,102 @@ +#!/usr/bin/env ruby + +# +# Copyright (c) 2008 Stephen Waits +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + +require 'digest/sha1' + +# helper to make a 'length' long string filled with 'byte' +def byte_string(byte, length) + ([byte]*length).pack('C*') +end + +# helper to make a 'length' long string filled with 'byte' +def byte_array(byte, length) + ([byte]*length) +end + +# hmac algorithm - returns text version of hmac +def hmac(key, data, digest_object, blocksize) + # if key is too long, hash it + key = digest_object.digest(key) if key.size > blocksize + + # pad key out to blocksize + key += byte_string(0,blocksize - key.size) if key.size < blocksize + + # create pads + ipad = byte_array(0x36,blocksize) + opad = byte_array(0x5c,blocksize) + blocksize.times { |i| ipad[i] ^= key[i].ord; opad[i] ^= key[i].ord } + + # do the HMAC and return + digest_object.hexdigest( opad.pack('C*') + digest_object.digest( ipad.pack('C*') + data ) ) +end + +# hmac-sha1 +def hmac_sha1(key, data) + hmac(key, data, Digest::SHA1, 64) +end + +# test vectors courtesy of RFC2202 +TestVectorsHMACSHA1 = [ + [ byte_string(0xb,20),'Hi There','b617318655057264e28bc0b6fb378c8ef146be00' ], + [ 'Jefe','what do ya want for nothing?', 'effcdf6ae5eb2fa2d27416d5f184df9c259a7c79' ], + [ byte_string(0xaa,20),byte_string(0xdd,50), '125d7342b9ac11cd91a39af48aa17b4f63f175d3' ], + [ [1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19].pack('C*'),byte_string(0xcd,50),'4c9007f4026250c6bc8414f9bf50c86c2d7235da' ], + [ byte_string(0xc,20),'Test With Truncation','4c1a03424b55e07fe7f27be1d58bb9324a9a5a04' ], + [ byte_string(0xaa,80),'Test Using Larger Than Block-Size Key - Hash Key First','aa4ae5e15272d00e95705637ce8a3b55ed402112' ], + [ byte_string(0xaa,80),'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data','e8e99d0f45237d786d6bbaa7965c7808bbff1a91' ], +] + +# test all of the above vectors +def hmac_test + TestVectorsHMACSHA1.each do |t| + key,data,result = t + return false if hmac_sha1(key,data) != result + end + return true +end + + +# make sure our hmac is working properly +if !hmac_test + puts 'ERROR: HMAC test failed!' + exit 1 +end + +# verify arguments +if ARGV.size != 2 + puts 'ERROR: Please specify password and site' + exit 1 +end + +# get arguments +key,site = ARGV + +# helper to split an HMAC-SHA1 into four 10-character keys +def make_passwords(key,site) + hmac_sha1(key,site.downcase).unpack('A10A10A10A10') +end + +# output +puts make_passwords(key,site)[0] +