def decrypt_message(encrypted_data, decryption_key): """Function parses an ASN.1 encrypted message and extracts/decrypts the original message. :param encrypted_data: A CMS ASN.1 byte string containing the encrypted data. :param decryption_key: The key to be used for decrypting the data. :return: A byte string containing the decrypted original message. """ cms_content = cms.ContentInfo.load(encrypted_data) cipher, decrypted_content = None, None if cms_content["content_type"].native == "enveloped_data": recipient_info = cms_content["content"]["recipient_infos"][0].parse() key_enc_alg = recipient_info["key_encryption_algorithm"][ "algorithm"].native encrypted_key = recipient_info["encrypted_key"].native if cms.KeyEncryptionAlgorithmId( key_enc_alg) == cms.KeyEncryptionAlgorithmId("rsa"): try: key = asymmetric.rsa_pkcs1v15_decrypt(decryption_key[0], encrypted_key) except Exception: raise DecryptionError( "Failed to decrypt the payload: Could not extract decryption key." ) alg = cms_content["content"]["encrypted_content_info"][ "content_encryption_algorithm"] encapsulated_data = cms_content["content"][ "encrypted_content_info"]["encrypted_content"].native try: if alg["algorithm"].native == "rc4": decrypted_content = symmetric.rc4_decrypt( key, encapsulated_data) elif alg.encryption_cipher == "tripledes": cipher = "tripledes_192_cbc" decrypted_content = symmetric.tripledes_cbc_pkcs5_decrypt( key, encapsulated_data, alg.encryption_iv) elif alg.encryption_cipher == "aes": decrypted_content = symmetric.aes_cbc_pkcs7_decrypt( key, encapsulated_data, alg.encryption_iv) elif alg.encryption_cipher == "rc2": decrypted_content = symmetric.rc2_cbc_pkcs5_decrypt( key, encapsulated_data, alg["parameters"]["iv"].native) else: raise AS2Exception("Unsupported Encryption Algorithm") except Exception as e: raise DecryptionError( "Failed to decrypt the payload: {}".format(e)) else: raise AS2Exception("Unsupported Encryption Algorithm") else: raise DecryptionError("Encrypted data not found in ASN.1 ") return cipher, decrypted_content
def recipient_info(self, cert, session_key, oaep): public_key = cert.public_key() cert = signer.cert2asn(cert) tbs_cert = cert['tbs_certificate'] # TODO: use subject_key_identifier when available if oaep: encrypted_key = public_key.encrypt( session_key, padding.OAEP(mgf=padding.MGF1(hashes.SHA512()), algorithm=hashes.SHA512(), label=None)) kea = cms.KeyEncryptionAlgorithm({ 'algorithm': cms.KeyEncryptionAlgorithmId('rsaes_oaep'), 'parameters': algos.RSAESOAEPParams({ 'hash_algorithm': algos.DigestAlgorithm({'algorithm': 'sha512'}), 'mask_gen_algorithm': algos.MaskGenAlgorithm({ 'algorithm': algos.MaskGenAlgorithmId('mgf1'), 'parameters': { 'algorithm': algos.DigestAlgorithmId('sha512'), } }), 'p_source_algorithm': algos.PSourceAlgorithm({ 'algorithm': algos.PSourceAlgorithmId('p_specified'), 'parameters': b'', }) }) }) else: kea = {'algorithm': 'rsa'} encrypted_key = public_key.encrypt(session_key, padding.PKCS1v15()) result = cms.RecipientInfo(name='ktri', value={ 'version': 'v0', 'rid': cms.RecipientIdentifier( name='issuer_and_serial_number', value={ 'issuer': tbs_cert['issuer'], 'serial_number': tbs_cert['serial_number'] }), 'key_encryption_algorithm': kea, 'encrypted_key': core.OctetString(encrypted_key) }) return result
def encrypt_message(data_to_encrypt, enc_alg, encryption_cert): """Function encrypts data and returns the generated ASN.1 :param data_to_encrypt: A byte string of the data to be encrypted :param enc_alg: The algorithm to be used for encrypting the data :param encryption_cert: The certificate to be used for encrypting the data :return: A CMS ASN.1 byte string of the encrypted data. """ enc_alg_list = enc_alg.split('_') cipher, key_length, mode = enc_alg_list[0], enc_alg_list[1], enc_alg_list[ 2] enc_alg_asn1, encrypted_content = None, None # Generate the symmetric encryption key and encrypt the message key = util.rand_bytes(int(key_length) // 8) if cipher == 'tripledes': algorithm_id = '1.2.840.113549.3.7' iv, encrypted_content = symmetric.tripledes_cbc_pkcs5_encrypt( key, data_to_encrypt, None) enc_alg_asn1 = algos.EncryptionAlgorithm({ 'algorithm': algorithm_id, 'parameters': cms.OctetString(iv) }) elif cipher == 'rc2': algorithm_id = '1.2.840.113549.3.2' iv, encrypted_content = symmetric.rc2_cbc_pkcs5_encrypt( key, data_to_encrypt, None) enc_alg_asn1 = algos.EncryptionAlgorithm({ 'algorithm': algorithm_id, 'parameters': algos.Rc2Params({'iv': cms.OctetString(iv)}) }) elif cipher == 'rc4': algorithm_id = '1.2.840.113549.3.4' encrypted_content = symmetric.rc4_encrypt(key, data_to_encrypt) enc_alg_asn1 = algos.EncryptionAlgorithm({ 'algorithm': algorithm_id, }) elif cipher == 'aes': if key_length == '128': algorithm_id = '2.16.840.1.101.3.4.1.2' elif key_length == '192': algorithm_id = '2.16.840.1.101.3.4.1.22' else: algorithm_id = '2.16.840.1.101.3.4.1.42' iv, encrypted_content = symmetric.aes_cbc_pkcs7_encrypt( key, data_to_encrypt, None) enc_alg_asn1 = algos.EncryptionAlgorithm({ 'algorithm': algorithm_id, 'parameters': cms.OctetString(iv) }) # Encrypt the key and build the ASN.1 message encrypted_key = asymmetric.rsa_pkcs1v15_encrypt(encryption_cert, key) return cms.ContentInfo({ 'content_type': cms.ContentType('enveloped_data'), 'content': cms.EnvelopedData({ 'version': cms.CMSVersion('v0'), 'recipient_infos': [ cms.KeyTransRecipientInfo({ 'version': cms.CMSVersion('v0'), 'rid': cms.RecipientIdentifier({ 'issuer_and_serial_number': cms.IssuerAndSerialNumber({ 'issuer': encryption_cert.asn1['tbs_certificate']['issuer'], 'serial_number': encryption_cert.asn1['tbs_certificate'] ['serial_number'] }) }), 'key_encryption_algorithm': cms.KeyEncryptionAlgorithm( {'algorithm': cms.KeyEncryptionAlgorithmId('rsa')}), 'encrypted_key': cms.OctetString(encrypted_key) }) ], 'encrypted_content_info': cms.EncryptedContentInfo({ 'content_type': cms.ContentType('data'), 'content_encryption_algorithm': enc_alg_asn1, 'encrypted_content': encrypted_content }) }) }).dump()
def encrypt_message(data_to_encrypt, enc_alg, encryption_cert): """Function encrypts data and returns the generated ASN.1 :param data_to_encrypt: A byte string of the data to be encrypted :param enc_alg: The algorithm to be used for encrypting the data :param encryption_cert: The certificate to be used for encrypting the data :return: A CMS ASN.1 byte string of the encrypted data. """ enc_alg_list = enc_alg.split("_") cipher, key_length, _ = enc_alg_list[0], enc_alg_list[1], enc_alg_list[2] # Generate the symmetric encryption key and encrypt the message key = util.rand_bytes(int(key_length) // 8) if cipher == "tripledes": algorithm_id = "1.2.840.113549.3.7" iv, encrypted_content = symmetric.tripledes_cbc_pkcs5_encrypt( key, data_to_encrypt, None) enc_alg_asn1 = algos.EncryptionAlgorithm({ "algorithm": algorithm_id, "parameters": cms.OctetString(iv) }) elif cipher == "rc2": algorithm_id = "1.2.840.113549.3.2" iv, encrypted_content = symmetric.rc2_cbc_pkcs5_encrypt( key, data_to_encrypt, None) enc_alg_asn1 = algos.EncryptionAlgorithm({ "algorithm": algorithm_id, "parameters": algos.Rc2Params({"iv": cms.OctetString(iv)}), }) elif cipher == "rc4": algorithm_id = "1.2.840.113549.3.4" encrypted_content = symmetric.rc4_encrypt(key, data_to_encrypt) enc_alg_asn1 = algos.EncryptionAlgorithm({ "algorithm": algorithm_id, }) elif cipher == "aes": if key_length == "128": algorithm_id = "2.16.840.1.101.3.4.1.2" elif key_length == "192": algorithm_id = "2.16.840.1.101.3.4.1.22" else: algorithm_id = "2.16.840.1.101.3.4.1.42" iv, encrypted_content = symmetric.aes_cbc_pkcs7_encrypt( key, data_to_encrypt, None) enc_alg_asn1 = algos.EncryptionAlgorithm({ "algorithm": algorithm_id, "parameters": cms.OctetString(iv) }) elif cipher == "des": algorithm_id = "1.3.14.3.2.7" iv, encrypted_content = symmetric.des_cbc_pkcs5_encrypt( key, data_to_encrypt, None) enc_alg_asn1 = algos.EncryptionAlgorithm({ "algorithm": algorithm_id, "parameters": cms.OctetString(iv) }) else: raise AS2Exception("Unsupported Encryption Algorithm") # Encrypt the key and build the ASN.1 message encrypted_key = asymmetric.rsa_pkcs1v15_encrypt(encryption_cert, key) return cms.ContentInfo({ "content_type": cms.ContentType("enveloped_data"), "content": cms.EnvelopedData({ "version": cms.CMSVersion("v0"), "recipient_infos": [ cms.KeyTransRecipientInfo({ "version": cms.CMSVersion("v0"), "rid": cms.RecipientIdentifier({ "issuer_and_serial_number": cms.IssuerAndSerialNumber({ "issuer": encryption_cert.asn1["tbs_certificate"]["issuer"], "serial_number": encryption_cert.asn1["tbs_certificate"] ["serial_number"], }) }), "key_encryption_algorithm": cms.KeyEncryptionAlgorithm( {"algorithm": cms.KeyEncryptionAlgorithmId("rsa")}), "encrypted_key": cms.OctetString(encrypted_key), }) ], "encrypted_content_info": cms.EncryptedContentInfo({ "content_type": cms.ContentType("data"), "content_encryption_algorithm": enc_alg_asn1, "encrypted_content": encrypted_content, }), }), }).dump()