Exemple #1
0
    def Decrypt(self, input_bytes):
        """
    Decrypts the given ciphertext.

    @param input_bytes: raw byte string formatted as Header|IV|Ciph|Sig where
      Sig is the signature over the entire payload (Header|IV|Ciph).
    @type input_bytes: string

    @return: plaintext message
    @rtype: string

    @raise ShortCiphertextError: if the ciphertext is too short to have IV & Sig
    @raise InvalidSignatureError: if the signature doesn't correspond to payload
    """
        data_bytes = input_bytes[keyczar.HEADER_SIZE:]  # remove header
        if len(data_bytes) < self.block_size + util.HLEN:  # IV + sig
            raise errors.ShortCiphertextError(len(data_bytes))

        iv_bytes = data_bytes[:self.
                              block_size]  # first block of bytes is the IV
        ciph_bytes = data_bytes[self.block_size:-util.HLEN]
        sig_bytes = data_bytes[-util.HLEN:]  # last 20 bytes are sig
        if not self.hmac_key.Verify(input_bytes[:-util.HLEN], sig_bytes):
            raise errors.InvalidSignatureError()

        plain = AES.new(self.key_bytes, AES.MODE_CBC,
                        iv_bytes).decrypt(ciph_bytes)
        return self._UnPad(plain)
Exemple #2
0
  def Decrypt(self, ciphertext, decoder=util.Base64WSDecode):
    """
    Decrypts the given ciphertext and returns the plaintext.

    @param ciphertext: ciphertext to be decrypted - by default is Base64 encoded
    @type ciphertext: string

    @param decoder: function to perform decoding. Defaults to Base64, use None
    for no decoding.
    @type encoder: function

    @return: plaintext message
    @rtype: string

    @raise ShortCiphertextError: if length is too short to have Header, IV, Sig
    @raise BadVersionError: if header specifies an illegal version
    @raise BadFormatError: if header specifies an illegal format
    @raise KeyNotFoundError: if key specified in header doesn't exist
    @raise InvalidSignatureError: if the signature can't be verified
    """
    data_bytes = decoder(ciphertext) if decoder else ciphertext
    if len(data_bytes) < HEADER_SIZE:
      raise errors.ShortCiphertextError(len(data_bytes))
    key = self._ParseHeader(data_bytes[:HEADER_SIZE])
    return key.Decrypt(data_bytes)
Exemple #3
0
    def Decrypt(self, ciphertext):
        """
    Decrypts the given ciphertext and returns the plaintext.

    @param ciphertext: Base64 encoded string ciphertext to be decrypted.
    @type ciphertext: string

    @return: plaintext message
    @rtype: string

    @raise ShortCiphertextError: if length is too short to have Header, IV, Sig
    @raise BadVersionError: if header specifies an illegal version
    @raise BadFormatError: if header specifies an illegal format
    @raise KeyNotFoundError: if key specified in header doesn't exist
    @raise InvalidSignatureError: if the signature can't be verified
    """
        data_bytes = util.Decode(ciphertext)
        if len(data_bytes) < HEADER_SIZE:
            raise errors.ShortCiphertextError(len(data_bytes))
        key = self._ParseHeader(data_bytes[:HEADER_SIZE])
        return key.Decrypt(data_bytes)
Exemple #4
0
    def read(self, chars=-1):
        """ 
    Decrypts data from the source stream and returns the resulting plaintext.
    NOTE: the signature validation is performed on the final read if sufficient
    data is available. Streaming => it isn't possible to validate up front as
    done by Decrypt().

    @param chars: indicates the number of characters to read from the stream.
    read() will never return more than chars characters, but it might return
    less, if there are not enough characters available.
    @type chars: integer

    @raise ShortCiphertextError: if the ciphertext is too short to have IV & Sig
    @raise InvalidSignatureError: if the signature doesn't correspond to payload
    @raise KeyNotFoundError: if key specified in header doesn't exist
    @raise ValueError: if stream closed
    """
        self.__CheckOpen('read')
        is_data_avail = True
        if not self.__key:
            is_data_avail = self.__CreateKey()

        if is_data_avail and self.__key and not self.__cipher:
            is_data_avail = self.__CreateCipher()

        if is_data_avail and self.__key and self.__cipher:
            data_to_decrypt = ''
            need_more_data = True
            while need_more_data:
                read_bytes, is_data_avail = self.__ReadBytes(
                    self.__key.block_size, block=False)
                if read_bytes:
                    self.__encrypted_buffer += read_bytes

                reserved_data_len = util.HLEN
                if is_data_avail:
                    reserved_data_len += self.__key.block_size

                available_data = self.__encrypted_buffer[:-reserved_data_len]

                if is_data_avail:
                    no_decrypt_len = len(
                        available_data) % self.__key.block_size
                else:
                    no_decrypt_len = 0
                # slicing with [:-0] does not work!
                if no_decrypt_len:
                    data_to_decrypt = available_data[:-no_decrypt_len]
                else:
                    data_to_decrypt = available_data

                need_more_data = (is_data_avail and not data_to_decrypt)

            if data_to_decrypt:
                self.__hmac_stream.Update(data_to_decrypt)
                self.__encrypted_buffer = self.__encrypted_buffer[
                    len(data_to_decrypt):]
                decrypted_data = self.__cipher.decrypt(data_to_decrypt)
                if not is_data_avail:
                    decrypted_data = self.__key._UnPad(decrypted_data)

                self.__decrypted_buffer += decrypted_data

                if not is_data_avail:
                    if len(self.__encrypted_buffer) != util.HLEN:
                        raise errors.ShortCiphertextError(
                            len(self.__encrypted_buffer))
                    current_sig_bytes = self.__hmac_stream.Sign()
                    msg_sig_bytes = self.__encrypted_buffer
                    self.__encrypted_buffer = ''
                    if not self.__key.hmac_key.VerifySignedData(
                            current_sig_bytes, msg_sig_bytes):
                        raise errors.InvalidSignatureError()

        if chars < 0:
            result = self.__decrypted_buffer
            self.__decrypted_buffer = ''
        else:
            result = self.__decrypted_buffer[:chars]
            self.__decrypted_buffer = self.__decrypted_buffer[chars:]

        if not result and is_data_avail:
            result = None

        return result