Files
hsmr/lib/hsmr.rb
2011-03-30 21:54:22 +11:00

117 lines
3.2 KiB
Ruby

require 'openssl'
module HSMR
VERSION = '0.0.1'
# Key Lengths
SINGLE=64
DOUBLE=128
TRIPLE=192
def self.encrypt_pin(key, pin)
@pin = pin.unpack('a2'*(pin.length/2)).map{|x| x.hex}.pack('c'*(pin.length/2))
des = OpenSSL::Cipher::Cipher.new("des-ede")
des.encrypt
des.key=key.key
return des.update(@pin).unpack('H*').first.upcase
end
def self.decrypt_pin(key, pinblock)
@pinblock = pinblock.unpack('a2'*(pinblock.length/2)).map{|x| x.hex}.pack('c'*(pinblock.length/2))
des = OpenSSL::Cipher::Cipher.new("des-ede")
des.decrypt
des.padding=0
des.key=key.key
result = des.update(@pinblock)
result << des.final
result.unpack('H*').first.upcase
end
def self.ibm3624(key, account, plength=4, dtable="0123456789012345" )
validation_data = account.unpack('a2'*(account.length/2)).map{|x| x.hex}.pack('c'*(account.length/2))
#des = OpenSSL::Cipher::Cipher.new("des-ede-cbc")
des = OpenSSL::Cipher::Cipher.new("des-cbc")
des.encrypt
des.key=key.key
return HSMR::decimalise(des.update(validation_data).unpack('H*').first, :ibm, dtable)[0...plength]
end
def self.decimalise(value, method=:visa, dtable="0123456789012345" )
result = []
if method == :ibm
##
# The IBM method
##
value.each_char do |c|
result << dtable[c.to_i(16),1].to_i
end
elsif method == :visa
value.each_char do |c|
result << c.to_i if numeric?(c)
end
value.upcase.each_char do |c|
result << dtable[c.to_i(16),1].to_i unless numeric?(c)
end
end
return result
end
def self.pvv(key, account, pvki, pin)
tsp = account.to_s[4,11] + pvki.to_s + pin.to_s
@tsp = tsp.unpack('a2'*(tsp.length/2)).map{|x| x.hex}.pack('c'*(tsp.length/2))
des = OpenSSL::Cipher::Cipher.new("des-ede")
des.encrypt
des.key=key.key
result = des.update(@tsp).unpack('H*').first.upcase
decimalise(result, :visa)[0..3].join
end
def self.xor(component1, *rest)
return if rest.length == 0
component1 = Component.new(component1) unless component1.is_a? Component
raise TypeError, "Component argument expected" unless component1.is_a? Component
#@components=[]
#rest.each {|c| components << ((c.is_a? HSMR::Component) ? c : HSMR::Component.new(c) ) }
#components.each {|c| raise TypeError, "Component argument expected" unless c.is_a? Component }
#resultant = component1.xor(components.pop)
#components.each {|c| resultant.xor!(c) }
rest.collect! {|c| ( (c.is_a? HSMR::Component) ? c : HSMR::Component.new(c) ) }
rest.each {|c| raise TypeError, "Component argument expected" unless c.is_a? HSMR::Component }
resultant = component1.xor(rest.pop)
rest.each {|c| resultant.xor!(c) }
return(resultant)
end
def self.numeric?(object)
## Method to determine if an object is a numeric type.
true if Float(object) rescue false
end
end
class String
def xor(other)
if other.empty?
self
else
a1 = self.unpack("c*")
a2 = other.unpack("c*")
a2 *= 2 while a2.length < a1.length
a1.zip(a2).collect{|c1,c2| c1^c2}.pack("c*")
end
end
end