def test_short(self): pt = urandom(MESH_MAX_DATA - 1) ct = cfb_encrypt(self.key, pt, mesh=True) dec = cfb_decrypt(self.key, ct, mesh=True) dec_plain = cfb_decrypt(self.key, ct) self.assertSequenceEqual(pt, dec) self.assertSequenceEqual(pt, dec_plain)
def test_longer_iv(self): pt = urandom(MESH_MAX_DATA * 3) ct = cfb_encrypt(self.key, pt, iv=self.iv, mesh=True) dec = cfb_decrypt(self.key, ct, iv=self.iv, mesh=True) dec_plain = cfb_decrypt(self.key, ct, iv=self.iv) self.assertSequenceEqual(pt, dec) self.assertNotEqual(pt, dec_plain)
def test_short_iv(self): pt = urandom(MESH_MAX_DATA - 1) ct = cfb_encrypt(self.key, pt, iv=self.iv, mesh=True) dec = cfb_decrypt(self.key, ct, iv=self.iv, mesh=True) dec_plain = cfb_decrypt(self.key, ct, iv=self.iv) self.assertEqual(pt, dec) self.assertEqual(pt, dec_plain)
def test_encrypted_data(self): cert_bag_expected = b64decode(b""" MIIDSjCCA0YGCyqGSIb3DQEMCgEDoIIDHjCCAxoGCiqGSIb3DQEJFgGgggMKBIIDBjCCAwIwggKt oAMCAQICEAHQaF8xH5bAAAAACycJAAEwDAYIKoUDBwEBAwIFADBgMQswCQYDVQQGEwJSVTEVMBMG A1UEBwwM0JzQvtGB0LrQstCwMQ8wDQYDVQQKDAbQotCaMjYxKTAnBgNVBAMMIENBIGNlcnRpZmlj YXRlIChQS0NTIzEyIGV4YW1wbGUpMB4XDTE1MDMyNzA3MjUwMFoXDTIwMDMyNzA3MjMwMFowZDEL MAkGA1UEBhMCUlUxFTATBgNVBAcMDNCc0L7RgdC60LLQsDEPMA0GA1UECgwG0KLQmjI2MS0wKwYD VQQDDCRUZXN0IGNlcnRpZmljYXRlIDEgKFBLQ1MjMTIgZXhhbXBsZSkwZjAfBggqhQMHAQEBATAT BgcqhQMCAiMBBggqhQMHAQECAgNDAARA1xzymkpvr2dYJT8WTOX3Dt96/+hGsXNytUQpkWB5ImJM 4tg9AsC4RIUwV5H41MhG0uBRFweTzN6AsAdBvhTClYEJADI3MDkwMDAxo4IBKTCCASUwKwYDVR0Q BCQwIoAPMjAxNTAzMjcwNzI1MDBagQ8yMDE2MDMyNzA3MjUwMFowDgYDVR0PAQH/BAQDAgTwMB0G A1UdDgQWBBQhWOsRQ68yYN2Utg/owHoWcqsVbTAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH AwQwDAYDVR0TAQH/BAIwADCBmQYDVR0jBIGRMIGOgBQmnc7Xh5ykb5t/BMwOkxA4drfEmqFkpGIw YDELMAkGA1UEBhMCUlUxFTATBgNVBAcMDNCc0L7RgdC60LLQsDEPMA0GA1UECgwG0KLQmjI2MSkw JwYDVQQDDCBDQSBjZXJ0aWZpY2F0ZSAoUEtDUyMxMiBleGFtcGxlKYIQAdBoXvL8TSAAAAALJwkA ATAMBggqhQMHAQEDAgUAA0EA9oq0Vvk8kkgIwkp0x0J5eKtia4MNTiwKAm7jgnCZIx3O98BThaTX 3ZQhEo2RL9pTCPr6wFMheeJ+YdGMReXvsjEVMBMGCSqGSIb3DQEJFTEGBAQBAAAA """) pfx, tail = PFX().decode(self.pfx_raw) self.assertSequenceEqual(tail, b"") octet_string_safe_contents, tail = OctetStringSafeContents().decode( bytes(pfx["authSafe"]["content"]), ) self.assertSequenceEqual(tail, b"") outer_safe_contents = octet_string_safe_contents["safeContents"] encrypted_data, tail = EncryptedData().decode( bytes(outer_safe_contents[1]["bagValue"]), ) self.assertSequenceEqual(tail, b"") pbes2_params, _ = PBES2Params().decode( bytes(encrypted_data["encryptedContentInfo"] ["contentEncryptionAlgorithm"]["parameters"]), ) self.assertSequenceEqual(tail, b"") pbkdf2_params, tail = PBKDF2Params().decode( bytes(pbes2_params["keyDerivationFunc"]["parameters"]), ) self.assertSequenceEqual(tail, b"") enc_scheme_params, tail = Gost2814789Parameters().decode( bytes(pbes2_params["encryptionScheme"]["parameters"]), ) self.assertSequenceEqual(tail, b"") key = gost34112012_pbkdf2( password=self.password.encode("utf-8"), salt=bytes(pbkdf2_params["salt"]["specified"]), iterations=int(pbkdf2_params["iterationCount"]), dklen=32, ) # key = hexdec("0e93d71339e7f53b79a0bc41f9109dd4fb60b30ae10736c1bb77b84c07681cfc") self.assertSequenceEqual( cfb_decrypt( key, bytes(encrypted_data["encryptedContentInfo"] ["encryptedContent"]), iv=bytes(enc_scheme_params["iv"]), sbox="Gost28147_tc26_ParamZ", ), cert_bag_expected, )
def test_random(self): """ Random data with various sizes """ key = urandom(32) iv = urandom(8) for size in (5, 8, 16, 120): pt = urandom(size) self.assertEqual( cfb_decrypt(key, cfb_encrypt(key, pt, iv), iv), pt, )
def decrypt(encrypted_text, mode, key, iv): encrypted_data = b64decode(encrypted_text.encode('utf-8')) decrypted_data = None if mode == 'ECB': decrypted_data = GOST.remove_padding( ecb_decrypt(key, encrypted_data)) elif mode == 'CBC': decrypted_data = GOST.remove_padding( cbc_decrypt(key, encrypted_data)) elif mode == 'CFB': decrypted_data = GOST.remove_padding( cfb_decrypt(key, encrypted_data, bytes.fromhex(iv))) return decrypted_data.decode('utf-8')
def test_shrouded_key_bag(self): private_key_info_expected = b64decode(b""" MGYCAQAwHwYIKoUDBwEBAQEwEwYHKoUDAgIjAQYIKoUDBwEBAgIEQEYbRu86z+1JFKDcPDN9UbTG G2ki9enTqos4KpUU0j9IDpl1UXiaA1YDIwUjlAp+81GkLmyt8Fw6Gt/X5JZySAY= """) pfx, tail = PFX().decode(self.pfx_raw) self.assertSequenceEqual(tail, b"") octet_string_safe_contents, tail = OctetStringSafeContents().decode( bytes(pfx["authSafe"]["content"]), ) self.assertSequenceEqual(tail, b"") outer_safe_contents = octet_string_safe_contents["safeContents"] octet_string_safe_contents, tail = OctetStringSafeContents().decode( bytes(outer_safe_contents[0]["bagValue"]), ) self.assertSequenceEqual(tail, b"") safe_bag = octet_string_safe_contents["safeContents"][0] shrouded_key_bag, tail = PKCS8ShroudedKeyBag().decode( bytes(safe_bag["bagValue"]), ) self.assertSequenceEqual(tail, b"") pbes2_params, tail = PBES2Params().decode( bytes(shrouded_key_bag["encryptionAlgorithm"]["parameters"]), ) self.assertSequenceEqual(tail, b"") pbkdf2_params, tail = PBKDF2Params().decode( bytes(pbes2_params["keyDerivationFunc"]["parameters"]), ) self.assertSequenceEqual(tail, b"") enc_scheme_params, tail = Gost2814789Parameters().decode( bytes(pbes2_params["encryptionScheme"]["parameters"]), ) self.assertSequenceEqual(tail, b"") key = gost34112012_pbkdf2( password=self.password.encode("utf-8"), salt=bytes(pbkdf2_params["salt"]["specified"]), iterations=int(pbkdf2_params["iterationCount"]), dklen=32, ) # key = hexdec("309dd0354c5603739403f2335e9e2055138f8b5c98b63009de0635eea1fd7ba8") self.assertSequenceEqual( cfb_decrypt( key, bytes(shrouded_key_bag["encryptedData"]), iv=bytes(enc_scheme_params["iv"]), sbox="Gost28147_tc26_ParamZ", ), private_key_info_expected, )
def process_cms( self, content_info_raw, prv_key_our, curve_name, keker, plaintext_expected, ): sbox = "Gost28147_tc26_ParamZ" content_info, tail = ContentInfo().decode(content_info_raw) self.assertSequenceEqual(tail, b"") enveloped_data, tail = EnvelopedData().decode( bytes(content_info["content"])) self.assertSequenceEqual(tail, b"") eci = enveloped_data["encryptedContentInfo"] ri = enveloped_data["recipientInfos"][0] encrypted_key, tail = GostR3410KeyTransport().decode( bytes(ri["ktri"]["encryptedKey"])) self.assertSequenceEqual(tail, b"") ukm = bytes(encrypted_key["transportParameters"]["ukm"]) spk = bytes(encrypted_key["transportParameters"]["ephemeralPublicKey"] ["subjectPublicKey"]) pub_key_their, tail = OctetString().decode(spk) self.assertSequenceEqual(tail, b"") curve = GOST3410Curve(*CURVE_PARAMS[curve_name]) kek = keker(curve, prv_key_our, bytes(pub_key_their), ukm) key_wrapped = bytes( encrypted_key["sessionEncryptedKey"]["encryptedKey"]) mac = bytes(encrypted_key["sessionEncryptedKey"]["macKey"]) cek = unwrap_cryptopro(kek, ukm + key_wrapped + mac, sbox=sbox) ciphertext = bytes(eci["encryptedContent"]) encryption_params, tail = Gost2814789Parameters().decode( bytes(eci["contentEncryptionAlgorithm"]["parameters"])) self.assertSequenceEqual(tail, b"") iv = bytes(encryption_params["iv"]) self.assertSequenceEqual( cfb_decrypt(cek, ciphertext, iv, sbox=sbox, mesh=True), plaintext_expected, )
def process_cms( self, content_info_raw, prv_key_our, curve_name, keker, plaintext_expected, ): sbox = "Gost28147_tc26_ParamZ" content_info, tail = ContentInfo().decode(content_info_raw) self.assertSequenceEqual(tail, b"") enveloped_data, tail = EnvelopedData().decode( bytes(content_info["content"])) self.assertSequenceEqual(tail, b"") eci = enveloped_data["encryptedContentInfo"] kari = enveloped_data["recipientInfos"][0]["kari"] pub_key_their, tail = OctetString().decode( bytes(kari["originator"]["originatorKey"]["publicKey"]), ) self.assertSequenceEqual(tail, b"") ukm = bytes(kari["ukm"]) rek = kari["recipientEncryptedKeys"][0] curve = GOST3410Curve(*CURVE_PARAMS[curve_name]) kek = keker(curve, prv_key_our, bytes(pub_key_their), ukm) encrypted_key, tail = Gost2814789EncryptedKey().decode( bytes(rek["encryptedKey"]), ) self.assertSequenceEqual(tail, b"") key_wrapped = bytes(encrypted_key["encryptedKey"]) mac = bytes(encrypted_key["macKey"]) cek = unwrap_gost(kek, ukm + key_wrapped + mac, sbox=sbox) ciphertext = bytes(eci["encryptedContent"]) encryption_params, tail = Gost2814789Parameters().decode( bytes(eci["contentEncryptionAlgorithm"]["parameters"])) self.assertSequenceEqual(tail, b"") iv = bytes(encryption_params["iv"]) self.assertSequenceEqual( cfb_decrypt(cek, ciphertext, iv, sbox=sbox, mesh=True), plaintext_expected, )
def test_cryptomanager(self): """ Test vector from http://cryptomanager.com/tv.html """ key = hexdec(b"75713134B60FEC45A607BB83AA3746AF4FF99DA6D1B53B5B1B402A1BAA030D1B") sbox = "id-GostR3411-94-TestParamSet" self.assertSequenceEqual( cfb_encrypt( key, hexdec(b"112233445566778899AABBCCDD800000"), iv=hexdec(b"0102030405060708"), sbox=sbox, ), hexdec(b"6EE84586DD2BCA0CAD3616940E164242"), ) self.assertSequenceEqual( cfb_decrypt( key, hexdec(b"6EE84586DD2BCA0CAD3616940E164242"), iv=hexdec(b"0102030405060708"), sbox=sbox, ), hexdec(b"112233445566778899AABBCCDD800000"), )
def test_single(self): pt = b"\x00" ct = cfb_encrypt(self.key, pt, mesh=True) dec = cfb_decrypt(self.key, ct, mesh=True) self.assertSequenceEqual(pt, dec)
def process_cms( self, content_info_raw, prv_key_our, curve_name, keker, plaintext_expected, ): sbox = "id-tc26-gost-28147-param-Z" content_info, tail = ContentInfo().decode( content_info_raw, ctx={ "defines_by_path": [( ( "content", DecodePathDefBy(id_envelopedData), "recipientInfos", any, "kari", "originator", "originatorKey", "algorithm", "algorithm", ), (( ("..", "publicKey"), { id_tc26_gost3410_2012_256: OctetString(), id_tc26_gost3410_2012_512: OctetString(), }, ), ), ) for _ in ( id_tc26_gost3410_2012_256, id_tc26_gost3410_2012_512, )], }) self.assertSequenceEqual(tail, b"") self.assertIsNotNone(content_info["content"].defined) _, enveloped_data = content_info["content"].defined eci = enveloped_data["encryptedContentInfo"] kari = enveloped_data["recipientInfos"][0]["kari"] self.assertIsNotNone( kari["originator"]["originatorKey"]["publicKey"].defined) _, pub_key_their = kari["originator"]["originatorKey"][ "publicKey"].defined ukm = bytes(kari["ukm"]) rek = kari["recipientEncryptedKeys"][0] curve = CURVES[curve_name] kek = keker(curve, prv_key_our, bytes(pub_key_their), ukm) self.assertIsNotNone(rek["encryptedKey"].defined) _, encrypted_key = rek["encryptedKey"].defined key_wrapped = bytes(encrypted_key["encryptedKey"]) mac = bytes(encrypted_key["macKey"]) cek = unwrap_gost(kek, ukm + key_wrapped + mac, sbox=sbox) ciphertext = bytes(eci["encryptedContent"]) self.assertIsNotNone( eci["contentEncryptionAlgorithm"]["parameters"].defined) _, encryption_params = eci["contentEncryptionAlgorithm"][ "parameters"].defined iv = bytes(encryption_params["iv"]) self.assertSequenceEqual( cfb_decrypt(cek, ciphertext, iv, sbox=sbox, mesh=True), plaintext_expected, )
def test_single(self): pt = b'\x00' ct = cfb_encrypt(self.key, pt, mesh=True) dec = cfb_decrypt(self.key, ct, mesh=True) self.assertEqual(pt, dec)