Beispiel #1
0
    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
Beispiel #2
0
  def __Encode(self, msg, label=""):
    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 + ('\x00' * pad_octets) + '\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 '\x00' + masked_seed + masked_datablock