Subversion Repositories pub

Compare Revisions

Ignore whitespace Rev 181 → Rev 182

/relevation/ext/cryptopy-1.2.5.orig/crypto/keyedHash/hmacHash.py
0,0 → 1,83
""" hmacHash.py
 
Implemention of Request for Comments: 2104
HMAC: Keyed-Hashing for Message Authentication
 
HMAC is a mechanism for message authentication
using cryptographic hash functions. HMAC can be used with any
iterative cryptographic hash function, e.g., MD5, SHA-1, in
combination with a secret shared key. The cryptographic strength of
HMAC depends on the properties of the underlying hash function.
 
This implementation of HMAC uses a generic cryptographic 'hashFunction'
(self.H). Hash functions must conform to the crypto.hash method
conventions and are not directly compatible with the Python sha1 or md5 algorithms.
 
[IETF] RFC 2104 "HMAC: Keyed-Hashing for Message Authentication"
>>>key = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>>keyedHashAlg = HMAC(SHA1, key)
>>>result = keyedHashAlg(data)
"""
from crypto.hash.hash import Hash
 
class HMAC(Hash):
""" To compute HMAC over the data `text' we perform
H(K XOR opad, H(K XOR ipad, text))
"""
def __init__(self, hashFunction, key = None):
""" initialize HMAC with hashfunction and optionally the key """
# should check for right type of function
self.H = hashFunction() # a new instance for inner hash
self.H_outer = hashFunction() # separate outer context to allow intermediate digests
self.B = self.H.raw_block_size # in bytes, note - hash block size typically 1
# and raw_block_size much larger
# e.g. raw_block_size is 64 bytes for SHA1 and MD5
self.name = 'HMAC_'+self.H.name
self.blocksize = 1 # single octets can be hashed by padding to raw block size
self.raw_block_size = self.H.raw_block_size
self.digest_size = self.H.digest_size
if key != None:
self.setKey(key)
else:
self.keyed = None
 
def setKey(self,key):
""" setKey(key) ... key is binary string """
if len(key) > self.B: # if key is too long then hash it
key = self.H(key) # humm... this is odd, hash can be smaller than B
else: # should raise error on short key, but breaks tests :-(
key =key + (self.B-len(key)) * chr(0)
self.k_xor_ipad = ''.join([chr(ord(bchar)^0x36) for bchar in key])
self.k_xor_opad = ''.join([chr(ord(bchar)^0x5C) for bchar in key])
self.keyed = 1
self.reset()
 
def reset(self):
self.H.reset()
if self.keyed == None :
raise 'no key defined'
self.H.update(self.k_xor_ipad) # start inner hash with key xored with ipad
# outer hash always called as one full pass (no updates)
def update(self,data):
if self.keyed == None :
raise 'no key defined'
self.H.update(data)
def digest(self):
if self.keyed == None :
raise 'no key defined'
return self.H_outer(self.k_xor_opad+self.H.digest())
 
from crypto.hash.sha1Hash import SHA1
class HMAC_SHA1(HMAC):
""" Predefined HMAC built on SHA1 """
def __init__(self, key = None):
""" optionally initialize with key """
HMAC.__init__(self,SHA1,key)
 
from crypto.hash.md5Hash import MD5
class HMAC_MD5(HMAC):
""" Predefined HMAC built on SHA1 """
def __init__(self, key = None):
""" optionally initialize with key """
HMAC.__init__(self,MD5,key)