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
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
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)
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)