Exemple #1
0
    def decrypt_secret_key(self, passphrase):
        if hasattr(passphrase, 'encode'):
            passphrase = passphrase.encode('utf-8')

        packet = copy.copy(self._message or self._key) # Do not mutate original

        cipher, key_bytes, key_block_bytes = self.get_cipher(packet.symmetric_algorithm)
        cipher = cipher(packet.s2k.make_key(passphrase, key_bytes))
        cipher = cipher(packet.encrypted_data[:key_block_bytes]).decryptor()
        pad_amount = key_block_bytes - (len(packet.encrypted_data[key_block_bytes:]) % key_block_bytes)
        material = cipher.update(packet.encrypted_data[key_block_bytes:] + (pad_amount*b'\0'))
        material += cipher.finalize()
        material = material[:-pad_amount]

        if packet.s2k_useage == 254:
            chk = material[-20:]
            material = material[:-20]
            if(chk != hashlib.sha1(material)):
                return None
        else:
            chk = unpack('!H', material[-2:])[0]
            material = material[:-2]
            if chk != OpenPGP.checksum(material):
                return None

        packet.s2k_usage = 0
        packet.symmetric_alorithm = 0
        packet.encrypted_data = None
        packet.input = OpenPGP.PushbackGenerator(OpenPGP._gen_one(material))
        packet.length = len(material)
        packet.key_from_input()
        packet.input = None
        return packet
Exemple #2
0
    def decrypt_secret_key(self, passphrase):
        if hasattr(passphrase, 'encode'):
            passphrase = passphrase.encode('utf-8')

        packet = copy.copy(self._message or self._key) # Do not mutate original

        cipher, key_bytes, key_block_bytes = self.get_cipher(packet.symmetric_algorithm)
        cipher = cipher(packet.s2k.make_key(passphrase, key_bytes))
        cipher = cipher(packet.encrypted_data[:key_block_bytes])
        material = self._block_pad_unpad(key_block_bytes, packet.encrypted_data[key_block_bytes:], lambda x: cipher.decrypt(x))

        if packet.s2k_useage == 254:
            chk = material[-20:]
            material = material[:-20]
            if(chk != hashlib.sha1(material)):
                return None
        else:
            chk = unpack('!H', material[-2:])[0]
            material = material[:-2]
            if chk != OpenPGP.checksum(material):
                return None

        packet.s2k_usage = 0
        packet.symmetric_alorithm = 0
        packet.encrypted_data = None
        packet.input = OpenPGP.PushbackGenerator(OpenPGP._gen_one(material))
        packet.length = len(material)
        packet.key_from_input()
        packet.input = None
        return packet
    def decrypt_secret_key(self, passphrase):
        if hasattr(passphrase, "encode"):
            passphrase = passphrase.encode("utf-8")

        packet = copy.copy(self._message or self._key)  # Do not mutate original

        cipher, key_bytes, key_block_bytes = self.get_cipher(packet.symmetric_algorithm)
        cipher = cipher(packet.s2k.make_key(passphrase, key_bytes))
        cipher = cipher(packet.encrypted_data[:key_block_bytes]).decryptor()
        pad_amount = key_block_bytes - (len(packet.encrypted_data[key_block_bytes:]) % key_block_bytes)
        material = cipher.update(packet.encrypted_data[key_block_bytes:] + (pad_amount * b"\0"))
        material += cipher.finalize()
        material = material[:-pad_amount]

        if packet.s2k_useage == 254:
            chk = material[-20:]
            material = material[:-20]
            if chk != hashlib.sha1(material):
                return None
        else:
            chk = unpack("!H", material[-2:])[0]
            material = material[:-2]
            if chk != OpenPGP.checksum(material):
                return None

        packet.s2k_usage = 0
        packet.symmetric_alorithm = 0
        packet.encrypted_data = None
        packet.input = OpenPGP.PushbackGenerator(OpenPGP._gen_one(material))
        packet.length = len(material)
        packet.key_from_input()
        packet.input = None
        return packet
Exemple #4
0
    def encrypt(self, passphrases_and_keys, symmetric_algorithm=9):
        cipher, key_bytes, key_block_bytes = self.get_cipher(
            symmetric_algorithm)
        if not cipher:
            raise Exception("Unsupported cipher")
        prefix = Crypto.Random.new().read(key_block_bytes)
        prefix += prefix[-2:]

        key = Crypto.Random.new().read(key_bytes)
        session_cipher = cipher(key)(None)

        to_encrypt = prefix + self._message.to_bytes()
        mdc = OpenPGP.ModificationDetectionCodePacket(
            Crypto.Hash.SHA.new(to_encrypt + b'\xD3\x14').digest())
        to_encrypt += mdc.to_bytes()

        def doEncrypt(cipher):
            ctx = cipher.encryptor()
            return lambda x: ctx.update(x) + ctx.finalize()

        encrypted = [
            OpenPGP.IntegrityProtectedDataPacket(
                self._block_pad_unpad(key_block_bytes, to_encrypt,
                                      doEncrypt(session_cipher)))
        ]

        if not isinstance(passphrases_and_keys,
                          collections.Iterable) or hasattr(
                              passphrases_and_keys, 'encode'):
            passphrases_and_keys = [passphrases_and_keys]

        for psswd in passphrases_and_keys:
            if isinstance(psswd, OpenPGP.PublicKeyPacket):
                if not psswd.key_algorithm in [1, 2, 3]:
                    raise Exception("Only RSA keys are supported.")
                rsa = self.__class__(psswd).public_key()
                pkcs1 = Crypto.Cipher.PKCS1_v1_5.new(rsa)
                esk = pkcs1.encrypt(
                    pack('!B', symmetric_algorithm) + key +
                    pack('!H', OpenPGP.checksum(key)))
                esk = pack('!H', OpenPGP.bitlength(esk)) + esk
                encrypted = [
                    OpenPGP.AsymmetricSessionKeyPacket(
                        psswd.key_algorithm, psswd.fingerprint(), esk)
                ] + encrypted
            elif hasattr(psswd, 'encode'):
                psswd = psswd.encode('utf-8')
                s2k = OpenPGP.S2K(Crypto.Random.new().read(10))
                packet_cipher = cipher(s2k.make_key(psswd, key_bytes))(None)
                esk = self._block_pad_unpad(
                    key_block_bytes,
                    pack('!B', symmetric_algorithm) + key,
                    doEncrypt(packet_cipher))
                encrypted = [
                    OpenPGP.SymmetricSessionKeyPacket(s2k, esk,
                                                      symmetric_algorithm)
                ] + encrypted

        return OpenPGP.Message(encrypted)
Exemple #5
0
    def encrypt(self, passphrases_and_keys, symmetric_algorithm=9):
        cipher, key_bytes, key_block_bytes = self.get_cipher(symmetric_algorithm)
        if not cipher:
            raise Exception("Unsupported cipher")
        prefix = Crypto.Random.new().read(key_block_bytes)
        prefix += prefix[-2:]

        key = Crypto.Random.new().read(key_bytes)
        session_cipher = cipher(key)(None)

        to_encrypt = prefix + self._message.to_bytes()
        mdc = OpenPGP.ModificationDetectionCodePacket(Crypto.Hash.SHA.new(to_encrypt + b'\xD3\x14').digest())
        to_encrypt += mdc.to_bytes()

        encrypted = [OpenPGP.IntegrityProtectedDataPacket(self._block_pad_unpad(key_block_bytes, to_encrypt, lambda x: session_cipher.encrypt(x)))]

        if not isinstance(passphrases_and_keys, collections.Iterable) or hasattr(passphrases_and_keys, 'encode'):
            passphrases_and_keys = [passphrases_and_keys]

        for psswd in passphrases_and_keys:
          if isinstance(psswd, OpenPGP.PublicKeyPacket):
              if not psswd.key_algorithm in [1,2,3]:
                  raise Exception("Only RSA keys are supported.")
              rsa = self.__class__(psswd).public_key()
              pkcs1 = Crypto.Cipher.PKCS1_v1_5.new(rsa)
              esk = pkcs1.encrypt(pack('!B', symmetric_algorithm) + key + pack('!H', OpenPGP.checksum(key)))
              esk = pack('!H', OpenPGP.bitlength(esk)) + esk
              encrypted = [OpenPGP.AsymmetricSessionKeyPacket(psswd.key_algorithm, psswd.fingerprint(), esk)] + encrypted
          elif hasattr(psswd, 'encode'):
              psswd = psswd.encode('utf-8')
              s2k = OpenPGP.S2K(Crypto.Random.new().read(10))
              packet_cipher = cipher(s2k.make_key(psswd, key_bytes))(None)
              esk = self._block_pad_unpad(key_block_bytes, pack('!B', symmetric_algorithm) + key, lambda x: packet_cipher.encrypt(x))
              encrypted = [OpenPGP.SymmetricSessionKeyPacket(s2k, esk, symmetric_algorithm)] + encrypted

        return OpenPGP.Message(encrypted)