def test_base64(self): ''' nose2 jose.tests.test_utils.TestBase64.test_base64 ''' self.assertEquals('QWxpY2U', base64.base64url_encode('Alice')) self.assertEquals('Qm9i', base64.base64url_encode('Bob')) self.assertEquals('Alice', base64.base64url_decode('QWxpY2U')) self.assertEquals('Bob', base64.base64url_decode('Qm9i')) self.assertEquals( '=', base64.base64url_decode(base64.base64url_encode('=')))
def test_key_wrap(self): # values from Jwe Appendix A.3 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_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 = ''.join(chr(i) for i in cek_oct) cek_ci = ''.join(chr(i) for i in cek_ci_oct) jwk_dict = { "kty": "oct", "k": "GawgguFyGrWKav7AX4VKUg" } kek = base64.base64url_decode(jwk_dict['k']) from jose.jwa.aes import aes_key_wrap, aes_key_unwrap rk = aes_key_wrap(kek, cek) self.assertEqual(rk, cek_ci) urk = aes_key_unwrap(kek, cek_ci) self.assertEqual(urk, cek)
def wrap_command(): parser = ArgumentParser(description='PBES2 Key Derivation') parser.add_argument('command', help="wrap") parser.add_argument('password') parser.add_argument('cek', nargs='?', default=None, type=basestring) parser.add_argument('key_len', nargs='?', default=16, type=int) parser.add_argument('-f', '--foo') parser.add_argument('-s', '--salt', dest="salt", action="store", default=None, help='base64salt') parser.add_argument('-a', '--alg', dest="alg", action="store", default='HS256', help='HS256|HS384|HS512') parser.add_argument('-c', '--count', dest="count", action="store", type=int, default=1024, help='KDF2 counter') args = parser.parse_args() wrapper = dict( HS256=KeyEncEnum.PBES2_HS384_A192KW, HS348=KeyEncEnum.PBES2_HS384_A192KW, HS512=KeyEncEnum.PBES2_HS512_A256KW, )[args.alg].encryptor if args.cek: cek = base64.base64url_decode(args.cek) else: cek = Random.get_random_bytes(args.key_len) jwk = Jwk(kty=keys.KeyTypeEnum.OCT) if args.password == 'random': jwk.k = base64.base64url_encode( Random.get_random_bytes(wrapper.key_length())) elif args.password.startswith('b64url:'): jwk.k = args.password[6:] else: jwk.k = base64.base64url_encode(args.password) salt = args.salt or base64.base64url_encode( Random.get_random_bytes(wrapper.key_length())) assert len(jwk.key.shared_key) == wrapper.key_length() kek = wrapper.derive(jwk, salt, args.count) cek_ci = wrapper.encrypt(kek, cek) print "share key(b64url)=", base64.base64url_encode(jwk.k), print "cek(b64url)=", base64.base64url_encode(cek) print "salt(b64url)=", base64.base64url_encode(salt), print "kek(b64url)=", base64.base64url_encode(kek), print "warapped cek(b64url)=", base64.base64url_encode(cek_ci), print "key length=", args.key_len, print "alg=", args.alg, wrapper.__name__, print "count=", args.count
def derive_command(): parser = ArgumentParser(description='PBES2 Key Derivation') parser.add_argument('command') parser.add_argument('password') parser.add_argument('key_len', nargs='?', default=16, type=int) parser.add_argument('-f', '--foo') parser.add_argument('-d', '--digest', dest="digest", action="store", default='sha256', help='sha256|384|512') parser.add_argument('-s', '--salt', dest="salt", action="store", default=None, help='base64salt') args = parser.parse_args() klen = args.key_len digest = dict(sha256=SHA256, sha384=SHA384, sha512=SHA512)[args.digest] if args.password == 'random': key = Random.get_random_bytes(klen) elif args.password.startswith('b64url:'): key = base64.base64url_decode(args.password[6:]) else: key = args.password if isinstance(args.salt, basestring): salt = base64.base64url_decode(args.salt) else: salt = Random.get_random_bytes(32) key, derived_key, salt, count = derive( key, salt, klen=klen, digest=digest) print "passowrd(b64url)=", base64.base64url_encode(key), print "key(b64url)=", base64.base64url_encode(derived_key), print "salt(b64url)=", base64.base64url_encode(salt), print "key length=", klen, print "digest=", args.digest, print "count=", count
def from_b64u(cls, b64_str, base=None): return cls.from_json(base64.base64url_decode(b64_str), base)
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)
def _BD(s): # b64decode return base64.base64url_decode(s)
def test_rs256(self): ''' nose2 jose.tests.test_jws.TestJws.test_rs256''' ''' JWS A.2 ''' octes = [123, 34, 97, 108, 103, 34, 58, 34, 82, 83, 50, 53, 54, 34, 125] jws_str = ''.join(chr(i) for i in octes) self.assertEqual(jws_str, '{"alg":"RS256"}') jws_new = Jws.from_json(jws_str) self.assertEqual(jws_new.alg, SigEnum.RS256) b64_header = base64.base64url_encode(jws_str) self.assertEqual(b64_header, 'eyJhbGciOiJSUzI1NiJ9') b64_payload = ''.join([ 'eyJpc3MiOiJqb2UiLA0KICJleHAiOj', 'EzMDA4MTkzODAsDQogImh0dHA6Ly9leGFt', 'cGxlLmNvbS9pc19yb290Ijp0cnVlfQ']) payload = base64.base64url_decode(b64_payload) jwt_new = Jwt.from_json(payload) self.assertEqual(jwt_new.iss, "joe") self.assertEqual(jwt_new.exp, 1300819380) self.assertEqual(jwt_new['http://example.com/is_root'], True) s_input = [ 101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 83, 85, 122, 73, 49, 78, 105, 74, 57, 46, 101, 121, 74, 112, 99, 51, 77, 105, 79, 105, 74, 113, 98, 50, 85, 105, 76, 65, 48, 75, 73, 67, 74, 108, 101, 72, 65, 105, 79, 106, 69, 122, 77, 68, 65, 52, 77, 84, 107, 122, 79, 68, 65, 115, 68, 81, 111, 103, 73, 109, 104, 48, 100, 72, 65, 54, 76, 121, 57, 108, 101, 71, 70, 116, 99, 71, 120, 108, 76, 109, 78, 118, 98, 83, 57, 112, 99, 49, 57, 121, 98, 50, 57, 48, 73, 106, 112, 48, 99, 110, 86, 108, 102, 81] s_input_str = "".join(chr(i) for i in s_input) self.assertEqual( s_input_str, ".".join([b64_header, b64_payload])) pri_json_dict = { "kty": "RSA", "n": "".join([ "ofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd_wWJcyQoTbji9k0l8W26mPddx", "HmfHQp-Vaw-4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL-yRT-SFd2lZS-pCgNMs", "D1W_YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb_7OMg0LOL-bSf63kpaSH", "SXndS5z5rexMdbBYUsLA9e-KXBdQOS-UTo7WTBEMa2R2CapHg665xsmtdV", "MTBQY4uDZlxvb3qCo5ZwKh9kG4LT6_I5IhlJH7aGhyxXFvUK-DWNmoudF8", "NAco9_h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQ"]), "e": "AQAB", "d": "".join([ "Eq5xpGnNCivDflJsRQBXHx1hdR1k6Ulwe2JZD50LpXyWPEAeP88vLNO97I", "jlA7_GQ5sLKMgvfTeXZx9SE-7YwVol2NXOoAJe46sui395IW_GO-pWJ1O0", "BkTGoVEn2bKVRUCgu-GjBVaYLU6f3l9kJfFNS3E0QbVdxzubSu3Mkqzjkn", "439X0M_V51gfpRLI9JYanrC4D4qAdGcopV_0ZHHzQlBjudU2QvXt4ehNYT", "CBr6XCLQUShb1juUO1ZdiYoFaFQT5Tw8bGUl_x_jTj3ccPDVZFD9pIuhLh", "BOneufuBiB4cS98l2SR_RQyGWSeWjnczT0QU91p1DhOVRuOopznQ"]), } jwk = Jwk(**pri_json_dict) self.assertTrue(jwk.key.is_private) signer = jws_new.alg.signer from jose.jwa.rsa import RS256 self.assertEqual(signer, RS256) sig_calc = signer.sign(jwk, s_input_str) sig = [ 112, 46, 33, 137, 67, 232, 143, 209, 30, 181, 216, 45, 191, 120, 69, 243, 65, 6, 174, 27, 129, 255, 247, 115, 17, 22, 173, 209, 113, 125, 131, 101, 109, 66, 10, 253, 60, 150, 238, 221, 115, 162, 102, 62, 81, 102, 104, 123, 0, 11, 135, 34, 110, 1, 135, 237, 16, 115, 249, 69, 229, 130, 173, 252, 239, 22, 216, 90, 121, 142, 232, 198, 109, 219, 61, 184, 151, 91, 23, 208, 148, 2, 190, 237, 213, 217, 217, 112, 7, 16, 141, 178, 129, 96, 213, 248, 4, 12, 167, 68, 87, 98, 184, 31, 190, 127, 249, 217, 46, 10, 231, 111, 36, 242, 91, 51, 187, 230, 244, 74, 230, 30, 177, 4, 10, 203, 32, 4, 77, 62, 249, 18, 142, 212, 1, 48, 121, 91, 212, 189, 59, 65, 238, 202, 208, 102, 171, 101, 25, 129, 253, 228, 141, 247, 127, 55, 45, 195, 139, 159, 175, 221, 59, 239, 177, 139, 93, 163, 204, 60, 46, 176, 47, 158, 58, 65, 214, 18, 202, 173, 21, 145, 18, 115, 160, 95, 35, 185, 232, 56, 250, 175, 132, 157, 105, 132, 41, 239, 90, 30, 136, 121, 130, 54, 195, 212, 14, 96, 69, 34, 165, 68, 200, 242, 122, 122, 45, 184, 6, 99, 209, 108, 247, 202, 234, 86, 222, 64, 92, 178, 33, 90, 69, 178, 194, 85, 102, 181, 90, 193, 167, 72, 160, 112, 223, 200, 163, 42, 70, 149, 67, 208, 25, 238, 251, 71] self.assertEqual(sig, [ord(i) for i in sig_calc]) b64_sig = "".join([ 'cC4hiUPoj9Eetdgtv3hF80EGrhuB__dzERat0XF9g2VtQgr9PJbu3XOiZj5RZmh7', 'AAuHIm4Bh-0Qc_lF5YKt_O8W2Fp5jujGbds9uJdbF9CUAr7t1dnZcAcQjbKBYNX4', 'BAynRFdiuB--f_nZLgrnbyTyWzO75vRK5h6xBArLIARNPvkSjtQBMHlb1L07Qe7K', '0GarZRmB_eSN9383LcOLn6_dO--xi12jzDwusC-eOkHWEsqtFZESc6BfI7noOPqv', 'hJ1phCnvWh6IeYI2w9QOYEUipUTI8np6LbgGY9Fs98rqVt5AXLIhWkWywlVmtVrB', 'p0igcN_IoypGlUPQGe77Rw']) self.assertEqual(b64_sig, base64.base64url_encode(sig_calc)) ########################## # implementation jws_impl = Jws(alg='RS256') msg = Message(payload=_BE(payload)) msg.signatures.append(Signature(_protected=jws_impl)) token = msg.serialize_compact(jwk=jwk) items = token.split('.') self.assertEqual(len(msg.signatures), 1) self.assertEqual(msg.signatures[0]._protected.alg.value, 'RS256') self.assertEqual(len(items), 3) self.assertEqual(msg.signatures[0].protected, items[0]) self.assertEqual(msg.payload, items[1]) self.assertEqual(msg.signatures[0].signature, items[2]) #: restore token msg2 = Message.from_token(token, sender=None, receiver=None) self.assertEqual(len(msg2.signatures), 1) self.assertEqual(msg2.payload, _BE(payload)) self.assertEqual(msg2.payload, msg.payload) self.assertEqual(len(msg2.signatures), 1) self.assertEqual(msg2.signatures[0]._protected.alg.value, 'RS256') self.assertEqual(msg2.signatures[0].protected, items[0]) self.assertEqual(msg2.payload, items[1]) self.assertEqual(msg2.signatures[0].signature, items[2]) #: verify message s = msg2.signatures[0] self.assertTrue(s.verify(msg2.payload, jwk=jwk)) #: wrong key fails new_jwk = Jwk.generate(KeyTypeEnum.RSA) self.assertFalse(s.verify(msg2.payload, jwk=new_jwk)) #: Json Serialization json_str = msg.serialize_json(jwk, indent=2) msg3 = Message.from_token(json_str) self.assertEqual(len(msg3.signatures), 1) self.assertTrue( msg3.signatures[0].verify(msg3.payload, jwk.public_jwk)) self.assertFalse( msg3.signatures[0].verify(msg3.payload, new_jwk.public_jwk))
def test_jws_appendix_a4(self): ''' nose2 jose.tests.test_jws.TestJws.test_jws_appendix_a4''' #: Data header_b64 = 'eyJhbGciOiJFUzUxMiJ9' payload_b64 = "UGF5bG9hZA" signature_b64 = ''.join([ 'AdwMgeerwtHoh-l192l60hp9wAHZFVJbLfD_UxMi70cwnZOYaRI1bKPWROc-mZZq', 'wqT2SI-KGDKB34XO0aw_7XdtAG8GaSwFKdCAPZgoXD2YBJZCPEX3xKpRwcdOO8Kp', 'EHwJjyqOgzDO7iKvU8vcnwNrmxYbSW9ERBXukOXolLzeO_Jn', ]) jws = Jws.from_b64u(header_b64) self.assertIsNotNone(jws) self.assertEqual(jws.alg, SigEnum.ES512) jwk_dict = { "kty": "EC", "crv": "P-521", "x": "".join([ "AekpBQ8ST8a8VcfVOTNl353vSrDCLL", "JXmPk06wTjxrrjcBpXp5EOnYG_NjFZ", "6OvLFV1jSfS9tsz4qUxcWceqwQGk", ]), "y": "".join([ "ADSmRA43Z1DSNx_RvcLI87cdL07l6j", "QyyBXMoxVg_l2Th-x3S1WDhjDly79a", "jL4Kkd0AZMaZmh9ubmf63e3kyMj2", ]), "d": "".join([ "AY5pb7A0UFiB3RELSD64fTLOSV_jaz", "dF7fLYyuTw8lOfRhWg6Y6rUrPAxerE", "zgdRhajnu0ferB0d53vM9mE15j2C" ])} from Crypto.Util.number import bytes_to_long #: Key jwk = Jwk(**jwk_dict) pub_jwk = jwk.public_jwk self.assertEqual( pub_jwk.key.public_key._pub[1], ( bytes_to_long(base64.base64url_decode(jwk_dict['x'])), bytes_to_long(base64.base64url_decode(jwk_dict['y'])), ) ) # Verify jws_token = ".".join([header_b64, payload_b64, signature_b64]) msg = Message.from_token(jws_token, sender=None, receiver=None) self.assertIsNotNone(msg) self.assertEqual(len(msg.signatures), 1) self.assertEqual(msg.signatures[0].signature, signature_b64) from jose.jwa.ec import EcdsaSigner sigbytes = base64.base64url_decode(msg.signatures[0].signature) self.assertEqual(len(sigbytes), 132) (r, s) = EcdsaSigner.decode_signature(sigbytes) R = [ 1, 220, 12, 129, 231, 171, 194, 209, 232, 135, 233, 117, 247, 105, 122, 210, 26, 125, 192, 1, 217, 21, 82, 91, 45, 240, 255, 83, 19, 34, 239, 71, 48, 157, 147, 152, 105, 18, 53, 108, 163, 214, 68, 231, 62, 153, 150, 106, 194, 164, 246, 72, 143, 138, 24, 50, 129, 223, 133, 206, 209, 172, 63, 237, 119, 109] S = [ 0, 111, 6, 105, 44, 5, 41, 208, 128, 61, 152, 40, 92, 61, 152, 4, 150, 66, 60, 69, 247, 196, 170, 81, 193, 199, 78, 59, 194, 169, 16, 124, 9, 143, 42, 142, 131, 48, 206, 238, 34, 175, 83, 203, 220, 159, 3, 107, 155, 22, 27, 73, 111, 68, 68, 21, 238, 144, 229, 232, 148, 188, 222, 59, 242, 103] self.assertEqual(r, bytes_to_long("".join(chr(i) for i in R))) self.assertEqual(s, bytes_to_long("".join(chr(i) for i in S))) print jwk.to_json(indent=2) self.assertTrue(msg.signatures[0].verify( msg.payload, jwk=jwk))
def test_jws_appendix_a1(self): ''' nose2 jose.tests.test_jws.TestJws.test_jws_appendix_a1''' '''{"typ":"JWT", "alg":"HS256"} {"iss":"joe", "exp":1300819380, "http://example.com/is_root":true} ''' jws_oct = [ 123, 34, 116, 121, 112, 34, 58, 34, 74, 87, 84, 34, 44, 13, 10, 32, 34, 97, 108, 103, 34, 58, 34, 72, 83, 50, 53, 54, 34, 125] jws_b64 = 'eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9' self.assertEqual( ''.join(chr(i) for i in jws_oct), base64.base64url_decode(jws_b64)) payload_oct = [ 123, 34, 105, 115, 115, 34, 58, 34, 106, 111, 101, 34, 44, 13, 10, 32, 34, 101, 120, 112, 34, 58, 49, 51, 48, 48, 56, 49, 57, 51, 56, 48, 44, 13, 10, 32, 34, 104, 116, 116, 112, 58, 47, 47, 101, 120, 97, 109, 112, 108, 101, 46, 99, 111, 109, 47, 105, 115, 95, 114, 111, 111, 116, 34, 58, 116, 114, 117, 101, 125] payload_b64 = ''.join([ 'eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA', '4MTkzODAsDQogImh0dHA6Ly9leGFt', 'cGxlLmNvbS9pc19yb290Ijp0cnVlfQ']) self.assertEqual( ''.join(chr(i) for i in payload_oct), base64.base64url_decode(payload_b64)) sinput_oct = [ 101, 121, 74, 48, 101, 88, 65, 105, 79, 105, 74, 75, 86, 49, 81, 105, 76, 65, 48, 75, 73, 67, 74, 104, 98, 71, 99, 105, 79, 105, 74, 73, 85, 122, 73, 49, 78, 105, 74, 57, 46, 101, 121, 74, 112, 99, 51, 77, 105, 79, 105, 74, 113, 98, 50, 85, 105, 76, 65, 48, 75, 73, 67, 74, 108, 101, 72, 65, 105, 79, 106, 69, 122, 77, 68, 65, 52, 77, 84, 107, 122, 79, 68, 65, 115, 68, 81, 111, 103, 73, 109, 104, 48, 100, 72, 65, 54, 76, 121, 57, 108, 101, 71, 70, 116, 99, 71, 120, 108, 76, 109, 78, 118, 98, 83, 57, 112, 99, 49, 57, 121, 98, 50, 57, 48, 73, 106, 112, 48, 99, 110, 86, 108, 102, 81] sinput = '.'.join([jws_b64, payload_b64]) self.assertEqual( ''.join(chr(i) for i in sinput_oct), sinput) jwk_dict = { "kty": "oct", "k": "".join([ "AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75", "aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"]) } jwk = Jwk(**jwk_dict) sig_b64 = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" jws = Jws.from_b64u(jws_b64) sig = jws.alg.signer.sign(jwk, sinput) self.assertEqual(sig_b64, base64.base64url_encode(sig)) self.assertTrue( jws.alg.signer.verify(jwk, sinput, sig))
def test_jws_appendix_a4(self): header_str = '{"alg":"ES512"}' header_oct = [ 123, 34, 97, 108, 103, 34, 58, 34, 69, 83, 53, 49, 50, 34, 125] self.assertEqual( [isinstance(i, int) and i or ord(i[:1]) for i in b(header_str)], header_oct) header_b64 = 'eyJhbGciOiJFUzUxMiJ9' self.assertEqual( base64.base64url_encode(header_str), b(header_b64)) payload_str = "Payload" payload_oct = [ 80, 97, 121, 108, 111, 97, 100, ] self.assertEqual( [isinstance(i, int) and i or ord(i[:1]) for i in b(payload_str)], payload_oct) payload_b64 = "UGF5bG9hZA" self.assertEqual( base64.base64url_encode(payload_str), b(payload_b64)) signing_input_b64 = ".".join([header_b64, payload_b64]) signing_input_oct = [ 101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 70, 85, 122, 85, 120, 77, 105, 74, 57, 46, 85, 71, 70, 53, 98, 71, 57, 104, 90, 65] self.assertEqual(_ilist(signing_input_b64), signing_input_oct) jwk_str = ''' {"kty":"EC", "crv":"P-521", "x":"AekpBQ8ST8a8VcfVOTNl353vSrDCLLJXmPk06wTjxrrjcBpXp5EOnYG_NjFZ6OvLFV1jSfS9tsz4qUxcWceqwQGk", "y":"ADSmRA43Z1DSNx_RvcLI87cdL07l6jQyyBXMoxVg_l2Th-x3S1WDhjDly79ajL4Kkd0AZMaZmh9ubmf63e3kyMj2", "d":"AY5pb7A0UFiB3RELSD64fTLOSV_jazdF7fLYyuTw8lOfRhWg6Y6rUrPAxerEzgdRhajnu0ferB0d53vM9mE15j2C" }''' from jose.jwk import Jwk jwk = Jwk.from_json(jwk_str) import hashlib # Sign pri = jwk.key.private_key_tuple self.assertEqual(pri[0], 521) self.assertEqual( pri[1], base64.long_from_b64( 'AY5pb7A0UFiB3RELSD64fTLOSV_jazdF7fLYyuTw8lOfRhWg6Y6rUrPAxerEzgdRhajnu0ferB0d53vM9mE15j2C') # NOQA ) digest = int(hashlib.new('sha512', b(signing_input_b64)).hexdigest(), 16) signature = jwk.key.sign_longdigest(digest) self.assertEqual(type(signature), tuple) #: This signature changes everytime. self.assertTrue(isinstance(signature, tuple)) self.assertEqual(len(signature), 2) # Verify pub = jwk.key.public_key_tuple self.assertEqual(pub[0], 521) self.assertEqual(pub[1], base64.long_from_b64( "AekpBQ8ST8a8VcfVOTNl353vSrDCLLJXmPk06wTjxrrjcBpXp5EOnYG_NjFZ6OvLFV1jSfS9tsz4qUxcWceqwQGk" # NOQA ) ) self.assertEqual(pub[2], base64.long_from_b64( "ADSmRA43Z1DSNx_RvcLI87cdL07l6jQyyBXMoxVg_l2Th-x3S1WDhjDly79ajL4Kkd0AZMaZmh9ubmf63e3kyMj2" # NOQA ) ) self.assertTrue(jwk.key.verify_longdigest(digest, signature)) sig_jws_oct = ( [1, 220, 12, 129, 231, 171, 194, 209, 232, 135, 233, 117, 247, 105, 122, 210, 26, 125, 192, 1, 217, 21, 82, 91, 45, 240, 255, 83, 19, 34, 239, 71, 48, 157, 147, 152, 105, 18, 53, 108, 163, 214, 68, 231, 62, 153, 150, 106, 194, 164, 246, 72, 143, 138, 24, 50, 129, 223, 133, 206, 209, 172, 63, 237, 119, 109], [0, 111, 6, 105, 44, 5, 41, 208, 128, 61, 152, 40, 92, 61, 152, 4, 150, 66, 60, 69, 247, 196, 170, 81, 193, 199, 78, 59, 194, 169, 16, 124, 9, 143, 42, 142, 131, 48, 206, 238, 34, 175, 83, 203, 220, 159, 3, 107, 155, 22, 27, 73, 111, 68, 68, 21, 238, 144, 229, 232, 148, 188, 222, 59, 242, 103] ) sig_jws_b64 = ''.join([ 'AdwMgeerwtHoh-l192l60hp9wAHZFVJbLfD_UxMi70cwnZOYaRI1bKPWROc-mZZq', 'wqT2SI-KGDKB34XO0aw_7XdtAG8GaSwFKdCAPZgoXD2YBJZCPEX3xKpRwcdOO8Kp', 'EHwJjyqOgzDO7iKvU8vcnwNrmxYbSW9ERBXukOXolLzeO_Jn', ]) sig_jws_str = base64.base64url_decode(sig_jws_b64) self.assertEqual(len(sig_jws_str), 66 * 2) from Crypto.Util.number import bytes_to_long sig_jws_tuple = (bytes_to_long(sig_jws_str[:66]), bytes_to_long(sig_jws_str[66:]),) self.assertTrue(jwk.key.verify_longdigest(digest, sig_jws_tuple))
import unittest from jose.jwk import Jwk, JwkSet from jose.jwe import Jwe, ZipEnum, Message, Recipient from jose.jwa.encs import KeyEncEnum, EncEnum from jose.jwa.keys import KeyTypeEnum from jose.utils import base64 import traceback from jose.tests import ( JWE_A2, JWE_A3, JWE_B, ) from jose.crypto import KeyOwner _S = lambda o: ''.join([chr(i) for i in o]) _BE = lambda s: base64.base64url_encode(s) _BD = lambda s: base64.base64url_decode(s) class TestEntity(KeyOwner): def __init__(self, identifier, jku, jwkset=None): self.identifier = identifier self.jku = jku self.jwkset = JwkSet( keys=[ Jwk.generate(KeyTypeEnum.RSA), Jwk.generate(KeyTypeEnum.EC), Jwk.generate(KeyTypeEnum.OCT), ] ) def get_key(self, crypto, *args, **kwargs):