diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d89bfaaf..2c28f4c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: os: ubuntu-20.04 python-version: 3.6 - name: py3.7 - os: ubuntu-latest + os: ubuntu-22.04 python-version: 3.7 - name: py3.8 os: ubuntu-latest @@ -58,7 +58,7 @@ jobs: python-version: 3.6 opt-deps: ['m2crypto'] - name: py3.7 with m2crypto - os: ubuntu-latest + os: ubuntu-22.04 python-version: 3.7 opt-deps: ['m2crypto'] - name: py3.8 with m2crypto @@ -101,7 +101,7 @@ jobs: python-version: 3.6 opt-deps: ['gmpy'] - name: py3.7 with gmpy - os: ubuntu-latest + os: ubuntu-22.04 python-version: 3.7 opt-deps: ['gmpy'] - name: py3.8 with gmpy @@ -126,7 +126,7 @@ jobs: python-version: 3.6 opt-deps: ['gmpy2'] - name: py3.7 with gmpy2 - os: ubuntu-latest + os: ubuntu-22.04 python-version: 3.7 opt-deps: ['gmpy2'] - name: py3.8 with gmpy2 @@ -160,7 +160,7 @@ jobs: # zstandard is available for py3.8 and above opt-deps: ['brotli'] - name: py3.7 with brotli - os: ubuntu-latest + os: ubuntu-22.04 python-version: 3.7 # zstandard is available for py3.8 and above opt-deps: ['brotli'] @@ -210,7 +210,7 @@ jobs: python-version: 3.6 opt-deps: ['m2crypto', 'pycrypto', 'gmpy', 'gmpy2', 'brotli'] - name: py3.7 with m2crypto, gmpy, gmpy2, and brotli - os: ubuntu-latest + os: ubuntu-22.04 python-version: 3.7 opt-deps: ['m2crypto', 'gmpy', 'gmpy2', 'brotli'] - name: py3.8 with m2crypto, gmpy, gmpy2, and brotli diff --git a/unit_tests/test_tlslite_utils_rsakey.py b/unit_tests/test_tlslite_utils_rsakey.py index abbd5566..38a12f1c 100644 --- a/unit_tests/test_tlslite_utils_rsakey.py +++ b/unit_tests/test_tlslite_utils_rsakey.py @@ -1819,7 +1819,7 @@ def test_valid_to_empty(self): # sanity check that the decrypted ciphertext is valid dec = self.priv_key._raw_private_key_op_bytes(ciphertext) self.assertEqual(dec[0:2], b'\x00\x02') - self.assertTrue(i != 0 for i in dec[2:-1]) + self.assertTrue(all(i != 0 for i in dec[2:-1])) self.assertEqual(dec[-1:], b'\x00') msg = self.priv_key.decrypt(ciphertext) @@ -1845,7 +1845,7 @@ def test_positive_11_byte_long_with_null_padded_ciphertext(self): # sanity check that the decrypted ciphertext is valid dec = self.priv_key._raw_private_key_op_bytes(ciphertext) self.assertEqual(dec[0:2], b'\x00\x02') - self.assertTrue(i != 0 for i in dec[2:-12]) + self.assertTrue(all(i != 0 for i in dec[2:-12])) self.assertEqual(dec[-12:], b'\x00lorem ipsum') self.assertEqual(len(plaintext), 11) @@ -1914,6 +1914,33 @@ def test_invalid_decrypting_to_max_length(self): self.assertEqual(msg, plaintext) + def test_invalid_with_zero_padded_ciphertext(self): + ciphertext = a2b_hex(remove_whitespace(""" +006f89db685c0a132700c6a17f88a37a6635d0ab89de4c45dc09736c891ca5bf +3401ce34c6e5d51e94ed2f518857ddc12d9f9f9e68e01cdc30d86ae5dd83988c +0c46a8e39daa1b328a23def551d67fa1964fb15242c83ddd7dd5b1aec720a391 +d0b86cb16cf4d3c466850c3df88a3ed85993900d1287a0c90c4b04d34ba29e59 +967661f3f10e0c998f64e14e777e8e81371eca5318b4e0b53414292130c82147 +7c51e2bff844836ab10dff293d82e4f40d345968ef268c92ed0bc238f31d50f4 +d3f759c23964923e135d15527556410fbd2c451d6a2aa852dc88b01139c6fdd8 +26736d8cd3780601b2977b09c080bd8c0fa471606ad59f053ad33d9eeb905f20 +""")) + self.assertEqual(len(ciphertext), numBytes(self.pub_key.n)) + + # sanity check that the decrypted ciphertext is invalid + dec = self.priv_key._raw_private_key_op_bytes(ciphertext) + self.assertEqual( + dec[0:3], + b'\x15\x1c\x6d') + + plaintext = a2b_hex(remove_whitespace(""" +2b5dd72df3cae37f1aef +""")) + self.assertEqual(len(plaintext), 10) + + msg = self.priv_key.decrypt(ciphertext) + self.assertEqual(msg, plaintext) + def test_invalid_decrypting_to_length_second_to_last_from_prf(self): # the last value from the PRF is 246, which is longer than the max # allowed length: 245, so it needs to select second to last: 2 @@ -2355,33 +2382,34 @@ class TestRSA2049Decrypt(unittest.TestCase): @classmethod def setUpClass(cls): priv_key = """ ------BEGIN RSA PRIVATE KEY----- -MIIEpQIBAAKCAQEBVfiJVWoXdfHHp3hqULGLwoyemG7eVmfKs5uEEk6Q66dcHbCD -rD5EO7qU3CNWD3XjqBaToqQ73HQm2MTq/mjIXeD+dX9uSbue1EfmAkMIANuwTOsi -5/pXoY0zj7ZgJs20Z+cMwEDn02fvQDx78ePfYkZQCUYx8h6v0vtbyRX/BDeazRES -9zLAtGYHwXjTiiD1LtpQny+cBAXVEGnoDM+UFVTQRwRnUFw89UHqCJffyfQAzssp -j/x1M3LZ9pM68XTMQO2W1GcDFzO5f4zd0/krw6A+qFdsQX8kAHteT3UBEFtUTen6 -3N/635jftLsFuBmfP4Ws/ZH3qaCUuaOD9QSQlwIDAQABAoIBAQEZwrP1CnrWFSZ5 -1/9RCVisLYym8AKFkvMy1VoWc2F4qOZ/F+cFzjAOPodUclEAYBP5dNCj20nvNEyl -omo0wEUHBNDkIuDOI6aUJcFf77bybhBu7/ZMyLnXRC5NpOjIUAjq6zZYWaIpT6OT -e8Jr5WMy59geLBYO9jXMUoqnvlXmM6cj28Hha6KeUrKa7y+eVlT9wGZrsPwlSsvo -DmOHTw9fAgeC48nc/CUg0MnEp7Y05FA/u0k+Gq/us/iL16EzmHJdrm/jmed1zV1M -8J/IODR8TJjasaSIPM5iBRNhWvqhCmM2jm17ed9BZqsWJznvUVpEAu4eBgHFpVvH -HfDjDt+BAoGBAYj2k2DwHhjZot4pUlPSUsMeRHbOpf97+EE99/3jVlI83JdoBfhP -wN3sdw3wbO0GXIETSHVLNGrxaXVod/07PVaGgsh4fQsxTvasZ9ZegTM5i2Kgg8D4 -dlxa1A1agfm73OJSftfpUAjLECnLTKvR+em+38KGyWVSJV2n6rGSF473AoGBAN7H -zxHa3oOkxD0vgBl/If1dRv1XtDH0T+gaHeN/agkf/ARk7ZcdyFCINa3mzF9Wbzll -YTqLNnmMkubiP1LvkH6VZ+NBvrxTNxiWJfu+qx87ez+S/7JoHm71p4SowtePfC2J -qqok0s7b0GaBz+ZcNse/o8W6E1FiIi71wukUyYNhAoGAEgk/OnPK7dkPYKME5FQC -+HGrMsjJVbCa9GOjvkNw8tVYSpq7q2n9sDHqRPmEBl0EYehAqyGIhmAONxVUbIsL -ha0m04y0MI9S0H+ZRH2R8IfzndNAONsuk46XrQU6cfvtZ3Xh3IcY5U5sr35lRn2c -ut3H52XIWJ4smN/cJcpOyoECgYEAjM5hNHnPlgj392wkXPkbtJXWHp3mSISQVLTd -G0MW8/mBQg3AlXi/eRb+RpHPrppk5jQLhgMjRSPyXXe2amb8PuWTqfGN6l32PtX3 -3+udILpppb71Wf+w7JTbcl9v9uq7o9SVR8DKdPA+AeweSQ0TmqCnlHuNZizOSjwP -G16GF0ECgYEA+ZWbNMS8qM5IiHgbMbHptdit9dDT4+1UXoNn0/hUW6ZEMriHMDXv -iBwrzeANGAn5LEDYeDe1xPms9Is2uNxTpZVhpFZSNALR6Po68wDlTJG2PmzuBv5t -5mbzkpWCoD4fRU53ifsHgaTW+7Um74gWIf0erNIUZuTN2YrtEPTnb3k= ------END RSA PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQFV+IlVahd18cen +eGpQsYvCjJ6Ybt5WZ8qzm4QSTpDrp1wdsIOsPkQ7upTcI1YPdeOoFpOipDvcdCbY +xOr+aMhd4P51f25Ju57UR+YCQwgA27BM6yLn+lehjTOPtmAmzbRn5wzAQOfTZ+9A +PHvx499iRlAJRjHyHq/S+1vJFf8EN5rNERL3MsC0ZgfBeNOKIPUu2lCfL5wEBdUQ +aegMz5QVVNBHBGdQXDz1QeoIl9/J9ADOyymP/HUzctn2kzrxdMxA7ZbUZwMXM7l/ +jN3T+SvDoD6oV2xBfyQAe15PdQEQW1RN6frc3/rfmN+0uwW4GZ8/haz9kfepoJS5 +o4P1BJCXAgMBAAECggEBARnCs/UKetYVJnnX/1EJWKwtjKbwAoWS8zLVWhZzYXio +5n8X5wXOMA4+h1RyUQBgE/l00KPbSe80TKWiajTARQcE0OQi4M4jppQlwV/vtvJu +EG7v9kzIuddELk2k6MhQCOrrNlhZoilPo5N7wmvlYzLn2B4sFg72NcxSiqe+VeYz +pyPbweFrop5SsprvL55WVP3AZmuw/CVKy+gOY4dPD18CB4Ljydz8JSDQycSntjTk +UD+7ST4ar+6z+IvXoTOYcl2ub+OZ53XNXUzwn8g4NHxMmNqxpIg8zmIFE2Fa+qEK +YzaObXt530FmqxYnOe9RWkQC7h4GAcWlW8cd8OMO34ECgYEBiPaTYPAeGNmi3ilS +U9JSwx5Eds6l/3v4QT33/eNWUjzcl2gF+E/A3ex3DfBs7QZcgRNIdUs0avFpdWh3 +/Ts9VoaCyHh9CzFO9qxn1l6BMzmLYqCDwPh2XFrUDVqB+bvc4lJ+1+lQCMsQKctM +q9H56b7fwobJZVIlXafqsZIXjvcCgYEA3sfPEdreg6TEPS+AGX8h/V1G/Ve0MfRP +6Bod439qCR/8BGTtlx3IUIg1rebMX1ZvOWVhOos2eYyS5uI/Uu+QfpVn40G+vFM3 +GJYl+76rHzt7P5L/smgebvWnhKjC1498LYmqqiTSztvQZoHP5lw2x7+jxboTUWIi +LvXC6RTJg2ECgYASCT86c8rt2Q9gowTkVAL4casyyMlVsJr0Y6O+Q3Dy1VhKmrur +af2wMepE+YQGXQRh6ECrIYiGYA43FVRsiwuFrSbTjLQwj1LQf5lEfZHwh/Od00A4 +2y6TjpetBTpx++1ndeHchxjlTmyvfmVGfZy63cfnZchYniyY39wlyk7KgQKBgQCM +zmE0ec+WCPf3bCRc+Ru0ldYeneZIhJBUtN0bQxbz+YFCDcCVeL95Fv5Gkc+ummTm +NAuGAyNFI/Jdd7ZqZvw+5ZOp8Y3qXfY+1fff650gummlvvVZ/7DslNtyX2/26ruj +1JVHwMp08D4B7B5JDROaoKeUe41mLM5KPA8bXoYXQQKBgQD5lZs0xLyozkiIeBsx +sem12K310NPj7VReg2fT+FRbpkQyuIcwNe+IHCvN4A0YCfksQNh4N7XE+az0iza4 +3FOllWGkVlI0AtHo+jrzAOVMkbY+bO4G/m3mZvOSlYKgPh9FTneJ+weBpNb7tSbv +iBYh/R6s0hRm5M3Ziu0Q9OdveQ== +-----END PRIVATE KEY----- """ cls.priv_key = parsePEMKey(priv_key, private=True) @@ -2421,131 +2449,250 @@ def test_simple(self): msg, self.priv_key.decrypt(self.pub_key.encrypt(msg))) - def test_with_ciphertext_length_from_third_prf_value(self): - # malformed plaintext that generates a fake plaintext of length - # specified by 3rd length from the end of PRF output + def test_positive_11_bytes_long(self): + # a valid ciphertext that decrypts to 11 byte long message ciphertext = a2b_hex(remove_whitespace(""" -00b26f6404b82649629f2704494282443776929122e279a9cf30b0c6fe8122a0a9042870d97c -c8ef65490fe58f031eb2442352191f5fbc311026b5147d32df914599f38b825ebb824af0d63f -2d541a245c5775d1c4b78630e4996cc5fe413d38455a776cf4edcc0aa7fccb31c584d60502ed -2b77398f536e137ff7ba6430e9258e21c2db5b82f5380f566876110ac4c759178900fbad7ab7 -0ea07b1daf7a1639cbb4196543a6cbe8271f35dddb8120304f6eef83059e1c5c5678710f904a -6d760c4d1d8ad076be17904b9e69910040b47914a0176fb7eea0c06444a6c4b86d674d19a556 -a1de5490373cb01ce31bbd15a5633362d3d2cd7d4af1b4c5121288b894""")) +013300edbf0bb3571e59889f7ed76970bf6d57e1c89bbb6d1c3991d9df8e65ed +54b556d928da7d768facb395bbcc81e9f8573b45cf8195dbd85d83a59281cddf +4163aec11b53b4140053e3bd109f787a7c3cec31d535af1f50e0598d85d96d91 +ea01913d07097d25af99c67464ebf2bb396fb28a9233e56f31f7e105d71a23e9 +ef3b736d1e80e713d1691713df97334779552fc94b40dd733c7251bc522b673d +3ec9354af3dd4ad44fa71c0662213a57ada1d75149697d0eb55c053aaed5ffd0 +b815832f454179519d3736fb4faf808416071db0d0f801aca8548311ee708c13 +1f4be658b15f6b54256872c2903ac708bd43b017b073b5707bc84c2cd9da70e9 +67 +""")) self.assertEqual(len(ciphertext), numBytes(self.pub_key.n)) - # sanity check that the decrypted ciphertext is invalid + # sanity check that the decrypted ciphertext is valid dec = self.priv_key._raw_private_key_op_bytes(ciphertext) - self.assertEqual(dec[0:1], b'\x00') - self.assertNotEqual(dec[1:2], b'\x02') - self.assertEqual(dec[-2:], b'\xc8\xfa') + self.assertEqual(dec[0:2], b'\x00\x02') + self.assertTrue(all(i != 0 for i in dec[2:-12])) + self.assertEqual(dec[-12:], b'\x00lorem ipsum') - plaintext = b'\x42' + plaintext = b'lorem ipsum' msg = self.priv_key.decrypt(ciphertext) self.assertEqual(msg, plaintext) - def test_positive_11_bytes_long(self): - # a valid ciphertext that decrypts to 11 byte long message + def test_positive_empty_message(self): ciphertext = a2b_hex(remove_whitespace(""" -013300edbf0bb3571e59889f7ed76970bf6d57e1c89bbb6d1c3991d9df8e65ed54b556d928da -7d768facb395bbcc81e9f8573b45cf8195dbd85d83a59281cddf4163aec11b53b4140053e3bd -109f787a7c3cec31d535af1f50e0598d85d96d91ea01913d07097d25af99c67464ebf2bb396f -b28a9233e56f31f7e105d71a23e9ef3b736d1e80e713d1691713df97334779552fc94b40dd73 -3c7251bc522b673d3ec9354af3dd4ad44fa71c0662213a57ada1d75149697d0eb55c053aaed5 -ffd0b815832f454179519d3736fb4faf808416071db0d0f801aca8548311ee708c131f4be658 -b15f6b54256872c2903ac708bd43b017b073b5707bc84c2cd9da70e967""")) +00cc52e83755a4526fea5e62450450638430a84a5878fd12c2a571f33c55729c +fab6e35c2e1703c452cff65731249460919aeb1b40084bdef573407851e48b3c +72923e48d5c4f3e80990c462bc291a3e635515636ab9ebeb317ca0d75b04b80c +17e2f4851f8929f72c9bea4ec4a6a1fbc5155837813567062d6b4b2a6b6e40be +545d25da39b08c52f3543e2f2cdfa314832dcbf475fcbb8d3565a64bb09b55f9 +22e6ec6cd8bb5203a11e2fa0c1b383674c4f0b63acd78f3690e3a16ad1b71f6c +fe48c56533e2ae42b1393b2d156c2323272490a574ce4f14055249b6a34c3e08 +d4a417039450910ec34bd5f08eb06078f51bdd6e50334ee64c9695a5bde52938 +e3 +""")) self.assertEqual(len(ciphertext), numBytes(self.pub_key.n)) - plaintext = b'lorem ipsum' + + # sanity check that the decrypted ciphertext is valid + dec = self.priv_key._raw_private_key_op_bytes(ciphertext) + self.assertEqual(dec[0:2], b'\x00\x02') + self.assertTrue(all(i != 0 for i in dec[2:-1])) + self.assertEqual(dec[-1:], b'\x00') msg = self.priv_key.decrypt(ciphertext) - self.assertEqual(msg, plaintext) + self.assertEqual(msg, b"") def test_positive_11_bytes_long_with_null_padded_ciphertext(self): # a valid ciphertext that starts with a null byte, decrypts to 11 byte # long value ciphertext = a2b_hex(remove_whitespace(""" -0002aadf846a329fadc6760980303dbd87bfadfa78c2015ce4d6c5782fd9d3f1078bd3c0a2c5 -bfbdd1c024552e5054d98b5bcdc94e476dd280e64d650089326542ce7c61d4f1ab40004c2e6a -88a883613568556a10f3f9edeab67ae8dddc1e6b0831c2793d2715de943f7ce34c5c05d1b09f -14431fde566d17e76c9feee90d86a2c158616ec81dda0c642f58c0ba8fa4495843124a7235d4 -6fb4069715a51bf710fd024259131ba94da73597ace494856c94e7a3ec261545793b0990279b -15fa91c7fd13dbfb1df2f221dab9fa9f7c1d21e48aa49f6aaecbabf5ee76dc6c2af2317ffb4e -303115386a97f8729afc3d0c89419669235f1a3a69570e0836c79fc162""")) +0002aadf846a329fadc6760980303dbd87bfadfa78c2015ce4d6c5782fd9d3f1 +078bd3c0a2c5bfbdd1c024552e5054d98b5bcdc94e476dd280e64d6500893265 +42ce7c61d4f1ab40004c2e6a88a883613568556a10f3f9edeab67ae8dddc1e6b +0831c2793d2715de943f7ce34c5c05d1b09f14431fde566d17e76c9feee90d86 +a2c158616ec81dda0c642f58c0ba8fa4495843124a7235d46fb4069715a51bf7 +10fd024259131ba94da73597ace494856c94e7a3ec261545793b0990279b15fa +91c7fd13dbfb1df2f221dab9fa9f7c1d21e48aa49f6aaecbabf5ee76dc6c2af2 +317ffb4e303115386a97f8729afc3d0c89419669235f1a3a69570e0836c79fc1 +62 +""")) self.assertEqual(len(ciphertext), numBytes(self.pub_key.n)) plaintext = b'lorem ipsum' + # sanity check that the decrypted ciphertext is valid + dec = self.priv_key._raw_private_key_op_bytes(ciphertext) + self.assertEqual(dec[0:2], b'\x00\x02') + self.assertTrue(all(i != 0 for i in dec[2:-12])) + self.assertEqual(dec[-12:], b'\x00lorem ipsum') + msg = self.priv_key.decrypt(ciphertext) self.assertEqual(msg, plaintext) - def test_positive_11_bytes_long_with_double_null_padded_ciphertext(self): - # a valid ciphertext that starts with two null bytes, decrypts to - # 11 byte long value + def test_invalid_decrypting_to_empty(self): ciphertext = a2b_hex(remove_whitespace(""" -0000f36da3b72d8ff6ded74e7efd08c01908f3f5f0de7b55eab92b5f875190809c39d4162e1e -6649618f854fd84aeab03970d16bb814e999852c06de38d82b95c0f32e2a7b5714021fe30338 -9be9c0eac24c90a6b7210f929d390fabf903d44e04110bb7a7fd6c383c275804721efa6d7c93 -aa64c0bb2b18d97c5220a846c66a4895ae52adddbe2a9996825e013585adcec4b32ba61d7827 -37bd343e5fabd68e8a95b8b1340318559860792dd70dffbe05a1052b54cbfb48cfa7bb3c19ce -a52076bddac5c25ee276f153a610f6d06ed696d192d8ae4507ffae4e5bdda10a625d6b67f32f -7cffcd48dee2431fe66f6105f9d17e611cdcc674868e81692a360f4052""")) +0128a1f7837e53b21ee37f0b4d08c76180305d5d854a1bcf3885471610646795 +f1e4c85ce7fce0f71ac3504598afdfc26792dea8ac55c7da10f96d26236ae652 +b282459d679ec84847d523f07213e81d1c713fb159eded43112eab68b610e3f8 +71d9c0009fde783ad7bcdca5568f7a86a716be6b96219c34b061f68718abad7c +947ed107097dc68341b865d73f2e857a345f5cf05c53bb2899d2895565009125 +c7b5fe1c35a73c03bb0f59e7faf381c784988bb71194307ee9a8ac122990fabb +5cc1fd877aaa79039ac163d084c7ee1642aaf05befb9d7ed0e29558f11f0708c +8e83f804f92fd41310a6fd21d91c3ceb88ceee3e424a3fcdda57fe3abb8b7bae +7d +""")) + self.assertEqual(len(ciphertext), numBytes(self.pub_key.n)) - plaintext = b'lorem ipsum' + + # sanity check that the decrypted ciphertext is invalid + dec = self.priv_key._raw_private_key_op_bytes(ciphertext) + # while the first byte is valid, it's because the modulus allows + # only for two acceptable values (0 and 1) for the MSB + self.assertEqual(dec[0:1], b'\x00') + self.assertNotEqual(dec[1:2], b'\x02') + self.assertNotEqual(dec[-1:], b'\x00') + + plaintext = b'' msg = self.priv_key.decrypt(ciphertext) self.assertEqual(msg, plaintext) - def test_negative_11_byte_long(self): - # a random ciphertext that generates a fake 11 byte plaintext - # and fails the padding check + def test_invalid_decrypting_to_max_length(self): ciphertext = a2b_hex(remove_whitespace(""" -00f910200830fc8fff478e99e145f1474b312e2512d0f90b8cef77f8001d09861688c156d1cb -af8a8957f7ebf35f724466952d0524cad48aad4fba1e45ce8ea27e8f3ba44131b7831b62d60c -0762661f4c1d1a88cd06263a259abf1ba9e6b0b172069afb86a7e88387726f8ab3adb30bfd6b -3f6be6d85d5dfd044e7ef052395474a9cbb1c3667a92780b43a22693015af6c513041bdaf87d -43b24ddd244e791eeaea1066e1f4917117b3a468e22e0f7358852bb981248de4d720add2d15d -ccba6280355935b67c96f9dcb6c419cc38ab9f6fba2d649ef2066e0c34c9f788ae49babd9025 -fa85b21113e56ce4f43aa134c512b030dd7ac7ce82e76f0be9ce09ebca""")) +013a60aa202dedad2d9e78c0c99077ccc17b7d0533aeaf184dcb8c9a81ca4de5 +715ada598d59b926606dcb005935421f6ebfd32e62802f0e2de8df08f1ae00e4 +aced6ebf361a38df817c892309bd07c92c4f2f7be89f286f99711372e3dd959c +cb0a150b28578f29040b39ecf989c26eb77a3480c2d4d363b9563a70f0a0789c +c4300af1e600de39dae4a49335d35ac0156f5395ebebf35531c819c9cf498a97 +e67ee2299d84564444f7bcd51f9f08d6bac0872439ad57eb9a8134dc665add1f +813d5031484c905a433c115bf889dc46ac672a8898fe235bf463b1b46345299b +6f100b48fa954fc262ce58e83f95955b321c1e86bbfe398b588dd5c75c2c6853 +2b +""")) + self.assertEqual(len(ciphertext), numBytes(self.pub_key.n)) # sanity check that the decrypted ciphertext is invalid dec = self.priv_key._raw_private_key_op_bytes(ciphertext) - self.assertNotEqual(dec[0:1], b'\x00') + self.assertEqual( + dec[0:11], + b'\x00\xaaG}\x8c\x02