def _FallbackHashes(self): fbh = [] #java uses the block sizes instead of keylength to produce hashes for aes if len(self.key_bytes) != 16: badjavahash = util.Hash(util.IntToBytes(16), self.key_bytes, self.hmac_key.key_bytes) fbh.append(util.Base64WSEncode(badjavahash[:constants.KEY_HASH_SIZE])) #old version of cpp stripped leading zeros of aes key if len(self.key_bytes) > 0 and self.key_bytes[0] == b'\x00'[0]: stripped_key_bytes = util.TrimBytes(self.key_bytes) badcpphash = util.Hash(util.IntToBytes(len(stripped_key_bytes)), stripped_key_bytes, self.hmac_key.key_bytes) fbh.append(util.Base64WSEncode(badcpphash[:constants.KEY_HASH_SIZE])) return fbh
def Sign(self, msg): """ Return raw byte string of signature on the message. @param msg: message to be signed @type msg: string @return: byte string formatted as an ASN.1 sequnce of r and s @rtype: string """ # Need to chose a random k per-message, SystemRandom() is available # since Python 2.4. k = random.SystemRandom().randint(2, self.key.q-1) (r, s) = self.key.sign(util.Hash(msg), k) return util.MakeDsaSig(r, s)
def __Decode(self, encoded_message, label=""): # See PKCS#1 v2.1: ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf if len(label) >= 2**61: # 2^61 = the input limit for SHA-1 raise errors.KeyczarError( "OAEP Decoding Error - label is too large %d" % len(label)) if len(encoded_message) < 2 * util.HLEN + 2: raise errors.KeyczarError( "OAEP Decoding Error - encoded_message is too small: %d" % len(encoded_message)) # Step 3b EM = Y || maskedSeed || maskedDB k = int(math.floor(math.log(self.key.n, 256)) + 1) # num bytes in n diff_len = k - len(encoded_message) # PyCrypto strips out leading zero bytes. # In OAEP, the first byte is expected to be a zero, so we can ignore it if diff_len > 1: # If more bytes were chopped by PyCrypto, add zero bytes back on encoded_message = '\x00' * (diff_len - 1) + encoded_message masked_seed = encoded_message[:util.HLEN] masked_datablock = encoded_message[util.HLEN:] # Step 3c,d seed_mask = util.MGF(masked_datablock, util.HLEN) seed = util.Xor(masked_seed, seed_mask) # Step 3e datablock_mask = util.MGF( seed, len(masked_datablock)) # encoded_message already stripped of 0 # Step 3f datablock = util.Xor(masked_datablock, datablock_mask) label_hash = datablock[:util.HLEN] expected_label_hash = util.Hash(label) # Debugging if label_hash != expected_label_hash: raise errors.KeyczarError( "OAEP Decoding Error - hash_id is invalid") delimited_message = datablock[util.HLEN:].lstrip('\x00') if delimited_message[0] != '\x01': raise errors.KeyczarError( "OAEP Decoding Error - expected a 1 value") return delimited_message[1:] # The message
def Verify(self, msg, sig): """ Return True if the signature corresponds to the message. @param msg: message that has been signed @type msg: string @param sig: raw byte string of the signature formatted as an ASN.1 sequence of r and s @type sig: string @return: True if signature is valid for message. False otherwise. @rtype: boolean """ try: (r, s) = util.ParseDsaSig(sig) return self.key.verify(util.Hash(msg), (r, s)) except errors.KeyczarError: # if signature is not in correct format return False
def __Encode(self, msg, label=b""): if len(label) >= 2**61: # the input limit for SHA-1 raise errors.KeyczarError("OAEP parameter string too long.") k = int(math.floor(math.log(self.key.n, 256)) + 1) # num bytes in n if len(msg) > k - 2 * util.HLEN - 2: raise errors.KeyczarError("Message too long to OAEP encode.") label_hash = util.Hash(label) pad_octets = (k - len(msg) - 2 * util.HLEN - 2) # Number of zeros to pad if pad_octets < 0: raise errors.KeyczarError("Message is too long: %d" % len(msg)) datablock = label_hash + util.RepeatByte(0x00, pad_octets) + b'\x01' + msg seed = util.RandBytes(util.HLEN) # Steps 2e, f datablock_mask = util.MGF(seed, k - util.HLEN - 1) masked_datablock = util.Xor(datablock, datablock_mask) # Steps 2g, h seed_mask = util.MGF(masked_datablock, util.HLEN) masked_seed = util.Xor(seed, seed_mask) # Step 2i: Construct the encoded message return b'\x00' + masked_seed + masked_datablock
def _Hash(self): fullhash = util.Hash(self.key_bytes) return util.Base64WSEncode(fullhash[:constants.KEY_HASH_SIZE])
def _Hash(self): fullhash = util.Hash(util.IntToBytes(len(self.key_bytes)), self.key_bytes, self.hmac_key.key_bytes) return util.Base64WSEncode(fullhash[:constants.KEY_HASH_SIZE])
def _Hash(self): """Compute and return the hash_id id of this key. Can override default hash_id.""" fullhash = util.Hash(util.IntToBytes(len(self.key_bytes)), self.key_bytes) return util.Base64WSEncode(fullhash[:keyczar.KEY_HASH_SIZE])