def test_merge(self): ''' Jwe specs 3 jwe objects(2 in Message, 1 on Signature) nose2 jose.tests.test_jwe.TestJwe.test_merge ''' jwe1 = Jwe.from_json('{ "alg": "RSA1_5"}') jwe2 = Jwe.from_json('{ "zip": "DEF"}') jwe3 = Jwe.merge(jwe1, jwe2) self.assertEqual(jwe3.alg, KeyEncEnum.RSA1_5) self.assertEqual(jwe3.zip, ZipEnum.DEF) self.assertIsNone(jwe1.zip) self.assertIsNone(jwe2.alg)
def test_message(self): ''' nose2 jose.tests.test_jwe.TestJweMessage.test_message ''' jwe = Jwe(alg=KeyEncEnum.A128KW) jwe2 = Jwe.from_json(jwe.to_json(indent=2)) self.assertEqual(jwe2.alg, jwe.alg) jwe3 = Jwe.from_b64u(jwe.to_b64u()) self.assertEqual(jwe3.alg, jwe.alg) msg = Message( protected=Jwe(enc=EncEnum.A128CBC_HS256), unprotected=Jwe(zip='DEF'), ) rec = Recipient(header=Jwe(alg=KeyEncEnum.A192KW)) msg.recipients.append(rec) msg2 = Message.from_json(msg.to_json(indent=2)) self.assertEqual(len(msg2.recipients), 1) self.assertEqual(msg2.recipients[0].header.alg, KeyEncEnum.A192KW) self.assertEqual(msg2.unprotected.zip, ZipEnum.DEF) header2 = msg2.header() self.assertEqual(header2.enc, EncEnum.A128CBC_HS256) self.assertEqual(header2.zip, ZipEnum.DEF) self.assertIsNone(header2.alg) header3 = msg2.header(0) self.assertEqual(header3.enc, EncEnum.A128CBC_HS256) self.assertEqual(header3.zip, ZipEnum.DEF) self.assertEqual(header3.alg, KeyEncEnum.A192KW)
def test_simple(self): ''' nose2 jose.tests.test_jwe.TestJwe.test_simple ''' data = '{ "alg": "RSA1_5", "zip": "DEF" }' jwe1 = Jwe.from_json(data) print dir(jwe1) self.assertEqual(jwe1.alg, KeyEncEnum.RSA1_5)
def test_jwe_appendix_a2(self): # PlainText plaint_oct = [ 76, 105, 118, 101, 32, 108, 111, 110, 103, 32, 97, 110, 100, 32, 112, 114, 111, 115, 112, 101, 114, 46] plaint = ''.join(chr(i) for i in plaint_oct) self.assertEqual(plaint, 'Live long and prosper.') # Appendix A.2.1 : JWE Header jwe_json = '{"alg":"RSA1_5","enc":"A128CBC-HS256"}' jwe_b64 = 'eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0' self.assertEqual(jwe_json, base64.base64url_decode(jwe_b64)) # Jwe object jwe = Jwe.from_json(jwe_json) # Appendix A.2.2 :CEK cek_oct = [ 4, 211, 31, 197, 84, 157, 252, 254, 11, 100, 157, 250, 63, 170, 106, 206, 107, 124, 212, 45, 111, 107, 9, 219, 200, 177, 0, 240, 143, 156, 44, 207] cek = ''.join(chr(i) for i in cek_oct) self.assertEqual(len(cek) * 8, 256) # Appendix A.2.3 : JWK Key jwk_dict = { "kty": "RSA", "n": "".join([ "sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1Wl", "UzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDpre", "cbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_", "7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBI", "Y2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU", "7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw"]), "e": "AQAB", "d": "".join([ "VFCWOqXr8nvZNyaaJLXdnNPXZKRaWCjkU5Q2egQQpTBMwhprMzWzpR8Sxq", "1OPThh_J6MUD8Z35wky9b8eEO0pwNS8xlh1lOFRRBoNqDIKVOku0aZb-ry", "nq8cxjDTLZQ6Fz7jSjR1Klop-YKaUHc9GsEofQqYruPhzSA-QgajZGPbE_", "0ZaVDJHfyd7UUBUKunFMScbflYAAOYJqVIVwaYR5zWEEceUjNnTNo_CVSj", "-VvXLO5VZfCUAVLgW4dpf1SrtZjSt34YLsRarSb127reG_DUwg9Ch-Kyvj", "T1SkHgUWRVGcyly7uvVGRSDwsXypdrNinPA4jlhoNdizK2zF2CWQ"]) } # Jwk object jwk = Jwk(**jwk_dict) # JWE ENcrypted Key cek_enc_oct = [ 80, 104, 72, 58, 11, 130, 236, 139, 132, 189, 255, 205, 61, 86, 151, 176, 99, 40, 44, 233, 176, 189, 205, 71, 202, 169, 72, 40, 226, 181, 156, 223, 120, 156, 115, 232, 150, 209, 145, 133, 104, 112, 237, 156, 116, 250, 65, 102, 212, 210, 103, 240, 177, 61, 93, 40, 71, 231, 223, 226, 240, 157, 15, 31, 150, 89, 200, 215, 198, 203, 108, 70, 117, 66, 212, 238, 193, 205, 23, 161, 169, 218, 243, 203, 128, 214, 127, 253, 215, 139, 43, 17, 135, 103, 179, 220, 28, 2, 212, 206, 131, 158, 128, 66, 62, 240, 78, 186, 141, 125, 132, 227, 60, 137, 43, 31, 152, 199, 54, 72, 34, 212, 115, 11, 152, 101, 70, 42, 219, 233, 142, 66, 151, 250, 126, 146, 141, 216, 190, 73, 50, 177, 146, 5, 52, 247, 28, 197, 21, 59, 170, 247, 181, 89, 131, 241, 169, 182, 246, 99, 15, 36, 102, 166, 182, 172, 197, 136, 230, 120, 60, 58, 219, 243, 149, 94, 222, 150, 154, 194, 110, 227, 225, 112, 39, 89, 233, 112, 207, 211, 241, 124, 174, 69, 221, 179, 107, 196, 225, 127, 167, 112, 226, 12, 242, 16, 24, 28, 120, 182, 244, 213, 244, 153, 194, 162, 69, 160, 244, 248, 63, 165, 141, 4, 207, 249, 193, 79, 131, 0, 169, 233, 127, 167, 101, 151, 125, 56, 112, 111, 248, 29, 232, 90, 29, 147, 110, 169, 146, 114, 165, 204, 71, 136, 41, 252] cek_enc = ''.join(chr(i) for i in cek_enc_oct) cek_enc_b64 = ''.join([ "UGhIOguC7IuEvf_NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-kFm", "1NJn8LE9XShH59_i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ__deLKxGHZ7Pc", "HALUzoOegEI-8E66jX2E4zyJKx-YxzZIItRzC5hlRirb6Y5Cl_p-ko3YvkkysZIF", "NPccxRU7qve1WYPxqbb2Yw8kZqa2rMWI5ng8OtvzlV7elprCbuPhcCdZ6XDP0_F8", "rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTP-cFPgwCp6X-nZZd9OHBv", "-B3oWh2TbqmScqXMR4gp_A", ]) # WARNING : cek_enc_oct may be wrong. # self.assertEqual(cek_enc, base64.base64url_decode(cek_enc_b64)) cek_enc = base64.base64url_decode(cek_enc_b64) # RSA 1.5 self.assertEqual(jwe.alg.name, 'RSA1_5') key_enc = jwe.alg.encryptor cek_restore = key_enc.decrypt(jwk, cek_enc) self.assertEqual(cek, cek_restore) cek_enc_2 = key_enc.encrypt(jwk, cek) cek_restore_2 = key_enc.decrypt(jwk, cek_enc_2) self.assertEqual(cek, cek_restore_2) # Appendix A.2.4 iv_oct = [ 3, 22, 60, 12, 43, 67, 104, 105, 108, 108, 105, 99, 111, 116, 104, 101] iv = ''.join(chr(i) for i in iv_oct) iv_b64 = 'AxY8DCtDaGlsbGljb3RoZQ' self.assertEqual(base64.base64url_decode(iv_b64), iv) # Appendix A.2.5 aad_oct = [ 101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 83, 85, 48, 69, 120, 88, 122, 85, 105, 76, 67, 74, 108, 98, 109, 77, 105, 79, 105, 74, 66, 77, 84, 73, 52, 81, 48, 74, 68, 76, 85, 104, 84, 77, 106, 85, 50, 73, 110, 48] aad = ''.join(chr(i) for i in aad_oct) # Appendix 2.6 ciphert_oct = [ 40, 57, 83, 181, 119, 33, 133, 148, 198, 185, 243, 24, 152, 230, 6, 75, 129, 223, 127, 19, 210, 82, 183, 230, 168, 33, 215, 104, 143, 112, 56, 102] ciphert = ''.join(chr(i) for i in ciphert_oct) tag_oct = [ 246, 17, 244, 190, 4, 95, 98, 3, 231, 0, 115, 157, 242, 203, 100, 191] tag = ''.join(chr(i) for i in tag_oct) # decrypt cenc = jwe.enc.encryptor p_new, is_valid = cenc.decrypt(cek, ciphert, iv, aad, tag) self.assertTrue(is_valid) self.assertEqual(p_new, plaint) print(p_new) c_new, tag_new = cenc.encrypt(cek, plaint, iv, aad) p_new_2, is_valid_2 = cenc.decrypt(cek, c_new, iv, aad, tag_new) self.assertTrue(is_valid_2) self.assertEqual(p_new_2, plaint) print(p_new_2)
def test_jwe_appendix_a3(self): # Appendix A.3 plaint_oct = [ 76, 105, 118, 101, 32, 108, 111, 110, 103, 32, 97, 110, 100, 32, 112, 114, 111, 115, 112, 101, 114, 46] plaint = ''.join(chr(i) for i in plaint_oct) self.assertEqual(plaint, 'Live long and prosper.') # Appendix A.3.1 jwe_json = '{"alg":"A128KW","enc":"A128CBC-HS256"}' jwe_b64 = 'eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0' self.assertEqual(jwe_json, base64.base64url_decode(jwe_b64)) jwe = Jwe.from_json(jwe_json) # Appendix A.3.2 cek_oct = [ 4, 211, 31, 197, 84, 157, 252, 254, 11, 100, 157, 250, 63, 170, 106, 206, 107, 124, 212, 45, 111, 107, 9, 219, 200, 177, 0, 240, 143, 156, 44, 207] cek = ''.join(chr(i) for i in cek_oct) # Appendix A.3.3 cek_ci_oct = [ 232, 160, 123, 211, 183, 76, 245, 132, 200, 128, 123, 75, 190, 216, 22, 67, 201, 138, 193, 186, 9, 91, 122, 31, 246, 90, 28, 139, 57, 3, 76, 124, 193, 11, 98, 37, 173, 61, 104, 57] cek_ci = ''.join(chr(i) for i in cek_ci_oct) #: Jwk jwk_dict = { "kty": "oct", "k": "GawgguFyGrWKav7AX4VKUg" } jwk = Jwk(**jwk_dict) self.assertEqual(_BD(jwk_dict['k']), jwk.key.shared_key) # Wrap self.assertEqual(jwe.alg, encs.KeyEncEnum.A128KW) uk = jwe.alg.encryptor.encrypt(jwk, cek) self.assertEqual(cek_ci, uk) # Jwe Appendix A.3.4 iv_oct = [ 3, 22, 60, 12, 43, 67, 104, 105, 108, 108, 105, 99, 111, 116, 104, 101] iv = ''.join(chr(i) for i in iv_oct) iv_b64 = 'AxY8DCtDaGlsbGljb3RoZQ' self.assertEqual(iv, base64.base64url_decode(iv_b64)) # Jwe Appendix A.3.5 aad_oct = [ 101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 66, 77, 84, 73, 52, 83, 49, 99, 105, 76, 67, 74, 108, 98, 109, 77, 105, 79, 105, 74, 66, 77, 84, 73, 52, 81, 48, 74, 68, 76, 85, 104, 84, 77, 106, 85, 50, 73, 110, 48] aad = ''.join(chr(i) for i in aad_oct) # Jwe Appendix A.3.6 ciphert_oct = [ 40, 57, 83, 181, 119, 33, 133, 148, 198, 185, 243, 24, 152, 230, 6, 75, 129, 223, 127, 19, 210, 82, 183, 230, 168, 33, 215, 104, 143, 112, 56, 102] tag_oct = [ 83, 73, 191, 98, 104, 205, 211, 128, 201, 189, 199, 133, 32, 38, 194, 85] tag = ''.join(chr(i) for i in tag_oct) ciphert = ''.join(chr(i) for i in ciphert_oct) pt, v = jwe.enc.encryptor.decrypt(cek, ciphert, iv, aad, tag) self.assertTrue(v) self.assertTrue(pt, plaint) print(pt)
def test_jwe_appendix_a1(self): # A.1 plaint_oct = [ 84, 104, 101, 32, 116, 114, 117, 101, 32, 115, 105, 103, 110, 32, 111, 102, 32, 105, 110, 116, 101, 108, 108, 105, 103, 101, 110, 99, 101, 32, 105, 115, 32, 110, 111, 116, 32, 107, 110, 111, 119, 108, 101, 100, 103, 101, 32, 98, 117, 116, 32, 105, 109, 97, 103, 105, 110, 97, 116, 105, 111, 110, 46] plaint = ''.join(chr(i) for i in plaint_oct) self.assertEqual( plaint, 'The true sign of intelligence is not knowledge but imagination.') # A.1.1 jwe_json = '{"alg":"RSA-OAEP","enc":"A256GCM"}' jwe_b64 = 'eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ' self.assertEqual(jwe_b64, base64.base64url_encode(jwe_json)) jwe = Jwe.from_json(jwe_json) self.assertEqual(jwe.alg, KeyEncEnum.RSA_OAEP) self.assertEqual(jwe.enc, EncEnum.GCMA256) # A.1.2. cek_oct = [ 177, 161, 244, 128, 84, 143, 225, 115, 63, 180, 3, 255, 107, 154, 212, 246, 138, 7, 110, 91, 112, 46, 34, 105, 47, 130, 203, 46, 122, 234, 64, 252] cek = ''.join(chr(i) for i in cek_oct) jwk_dict = { 'kty': "RSA", "n": ''.join([ 'oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUW', 'cJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S', 'psk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2a', 'sbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMS', 'tPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2dj', 'YgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw', ]), "e": "AQAB", "d": ''.join([ 'kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5N', 'WV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD9', '3Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghk', 'qDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vl', 't3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSnd', 'VTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ', ]) } jwk = Jwk(**jwk_dict) self.assertEqual(jwk.kty, KeyTypeEnum.RSA) self.assertTrue(jwk.key.is_private) cek_enc_oct = [ 56, 163, 154, 192, 58, 53, 222, 4, 105, 218, 136, 218, 29, 94, 203, 22, 150, 92, 129, 94, 211, 232, 53, 89, 41, 60, 138, 56, 196, 216, 82, 98, 168, 76, 37, 73, 70, 7, 36, 8, 191, 100, 136, 196, 244, 220, 145, 158, 138, 155, 4, 117, 141, 230, 199, 247, 173, 45, 182, 214, 74, 177, 107, 211, 153, 11, 205, 196, 171, 226, 162, 128, 171, 182, 13, 237, 239, 99, 193, 4, 91, 219, 121, 223, 107, 167, 61, 119, 228, 173, 156, 137, 134, 200, 80, 219, 74, 253, 56, 185, 91, 177, 34, 158, 89, 154, 205, 96, 55, 18, 138, 43, 96, 218, 215, 128, 124, 75, 138, 243, 85, 25, 109, 117, 140, 26, 155, 249, 67, 167, 149, 231, 100, 6, 41, 65, 214, 251, 232, 87, 72, 40, 182, 149, 154, 168, 31, 193, 126, 215, 89, 28, 111, 219, 125, 182, 139, 235, 195, 197, 23, 234, 55, 58, 63, 180, 68, 202, 206, 149, 75, 205, 248, 176, 67, 39, 178, 60, 98, 193, 32, 238, 122, 96, 158, 222, 57, 183, 111, 210, 55, 188, 215, 206, 180, 166, 150, 166, 106, 250, 55, 229, 72, 40, 69, 214, 216, 104, 23, 40, 135, 212, 28, 127, 41, 80, 175, 174, 168, 115, 171, 197, 89, 116, 92, 103, 246, 83, 216, 182, 176, 84, 37, 147, 35, 45, 219, 172, 99, 226, 233, 73, 37, 124, 42, 72, 49, 242, 35, 127, 184, 134, 117, 114, 135, 206] cek_enc_b64 = ''.join([ 'OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGe', 'ipsEdY3mx_etLbbWSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDb', 'Sv04uVuxIp5Zms1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaV', 'mqgfwX7XWRxv2322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je8', '1860ppamavo35UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi', '6UklfCpIMfIjf7iGdXKHzg', ]) cek_enc_bytes = ''.join(chr(i) for i in cek_enc_oct) self.assertEqual(cek_enc_bytes, base64.base64url_decode(cek_enc_b64)) self.assertEqual(len(cek) * 8, 256) key_enc = jwe.alg.encryptor from jose.jwa.rsa import RSA_OAEP self.assertEqual(key_enc, RSA_OAEP) # decrypt and encrypt CEK dec_cek = key_enc.decrypt(jwk, cek_enc_bytes) self.assertEqual(dec_cek, cek) # Appendix OK # --- encryption outcome MAY changes, # but decrypted plaint is same as the original enc_cek = key_enc.encrypt(jwk, cek) dec_cek_2 = key_enc.decrypt(jwk, enc_cek) self.assertEqual(dec_cek, dec_cek_2) # Appendix A.1.4 iv_oct = [227, 197, 117, 252, 2, 219, 233, 68, 180, 225, 77, 219] iv = ''.join(chr(i) for i in iv_oct) iv_b64url = '48V1_ALb6US04U3b' self.assertEqual(iv_b64url, base64.base64url_encode(iv)) # Appendix A.1.5 aad_oct = [ 101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 83, 85, 48, 69, 116, 84, 48, 70, 70, 85, 67, 73, 115, 73, 109, 86, 117, 89, 121, 73, 54, 73, 107, 69, 121, 78, 84, 90, 72, 81, 48, 48, 105, 102, 81] aad = ''.join(chr(i) for i in aad_oct) # Appendix A.1.6 cenc = jwe.enc.encryptor from jose.jwa.gcm import GCMA256 self.assertEqual(cenc, GCMA256) ciphert_oct = [ 229, 236, 166, 241, 53, 191, 115, 196, 174, 43, 73, 109, 39, 122, 233, 96, 140, 206, 120, 52, 51, 237, 48, 11, 190, 219, 186, 80, 111, 104, 50, 142, 47, 167, 59, 61, 181, 127, 196, 21, 40, 82, 242, 32, 123, 143, 168, 226, 73, 216, 176, 144, 138, 247, 106, 60, 16, 205, 160, 109, 64, 63, 192] ciphert = "".join(chr(i) for i in ciphert_oct) tag_oct = [ 92, 80, 104, 49, 133, 25, 161, 215, 173, 101, 219, 211, 136, 91, 210, 145] tag = "".join(chr(i) for i in tag_oct) # Content Decrytion pt, is_valid = cenc.decrypt(cek, ciphert, iv, aad, tag) self.assertEqual(pt, plaint) # consistent with the spec self.assertTrue(is_valid) #: encryt and decryt ct, tag2 = cenc.encrypt(cek, plaint, iv, aad) pt2, is_valid2 = cenc.decrypt(cek, ct, iv, aad, tag2) self.assertEqual(pt2, plaint) # consistent with the spec self.assertTrue(is_valid2)
ret = cls._cipher.new(jwk.key.private_key).decrypt(cek_ci, _sentinel) if ret == _sentinel: return None return ret class RSA_OAEP(RsaKeyEncryptor): _cipher = PKCS1_OAEP @classmethod def decrypt(cls, jwk, cek_ci, *args, **kwargs): return cls._cipher.new(jwk.key.private_key).decrypt(cek_ci) if __name__ == '__main__': from jose.jwe import Jwe from jose.jwa.keys import KeyTypeEnum jwk = Jwk.generate(kty=KeyTypeEnum.RSA) jwe = Jwe.from_json('{"alg": "RSA1_5", "enc": "A128CBC-HS256"}') cek, iv, cek_ci, kek = jwe.provide_key(jwk) print("CEK", base64.base64url_encode(cek)) print("IV", base64.base64url_encode(iv)) print("CEK_CI", base64.base64url_encode(cek_ci)) cek2 = jwe.agree_key(jwk, cek_ci) print("CEK2", base64.base64url_encode(cek_ci)) print("IV", base64.base64url_encode(iv)) assert(cek == cek2)