def __init__(self, sender=None, **kwargs): super(Signature, self).__init__(**kwargs) self.sender = sender self._protected = None #: Jws object from self.protected #: becuase json serialization results could be different #: in each system and framework. if self.protected: if isinstance(self.protected, basestring): #: this case if for veryfing a given token. self._protected = Jws.from_json(_BD(self.protected)) elif isinstance(self.protected, Jws): #: this case is for creating a new token. self._protected = self.protected if isinstance(self.header, dict): #: this case is for creating a new token. self.header = Jws(**self.header) elif isinstance(self.header, str): #: this case if for veryfing a given token. _json = _BD(self.header) self.header = Jws.from_json(_json) if not any([self._protected, self.header]): #: creating default self._protected = Jws(alg=SigEnum.RS256)
def agree(cls, enc, jwk, jwe, cek_ci, *args, **kwargs): kek = jwk.key.shared_key[:cls._enc._KEY_LEN] assert isinstance(jwe.iv, basestring) assert isinstance(jwe.tag, basestring) _iv = _BD(jwe.iv) _tag = _BD(jwe.tag) cek, isv = cls._enc.decrypt(kek, cek_ci, _iv, "", _tag) return cek
def agree_key(self, jwk, jwe=None): jwe = Jwe.merge(self.header, jwe) assert jwk.is_private, "Agreement jwk must be private." self.cek = jwe.alg.encryptor.agree( jwe.enc, jwk, self.header, _BD(self.encrypted_key)) return self.cek
def encrypt(self, header=None, auth_data=None): auth_data = auth_data or self.auth_data header = header or self.header() assert self.cek assert self.iv assert self.auth_data plaint = self.zip(self.plaintext) # 'zip' compression ciphert, tag = header.enc.encryptor.encrypt( self.cek, plaint, _BD(self.iv), auth_data) return (ciphert, tag)
def decrypt(self, jwk=None): if not self.cek: self.find_cek(jwk) header = self.header() # Two Jwe headered are merged. assert self.cek assert self.ciphertext assert self.iv assert self.tag plaint, is_valid = header.enc.encryptor.decrypt( self.cek, _BD(self.ciphertext), _BD(self.iv), self.auth_data, _BD(self.tag)) # TODO: is_valid == False, raise execption self.verified = is_valid #: TODO return self.zip(plaint, unzip=True)
def run(self, args): super(SampleCommand, self).run(args) #Jws self.result.jws = jws.Jws(alg=sigs.SigEnum.create(args.alg)) print self.result.to_json(indent=2) # any parms for param in args.params: self.result.jws.set_value(*param.split('=')) # Initia Value if self.result.jws.alg.key_type == keys.KeyTypeEnum.RSA: self.result.inits = dict(length=args.bits) elif self.result.jws.alg.key_type == keys.KeyTypeEnum.EC: self.result.inits = dict( length=keys.CurveEnum.create(args.curve).bits) elif self.result.jws.alg.key_type == keys.KeyTypeEnum.OCT: self.result.inits = dict(length=args.length) #key if args.jwk: self.result.jwk = jwk.Jwk.from_file(args.jwk) else: self.result.jwk = jwk.Jwk.generate( kty=self.result.jws.alg.key_type, **self.result.inits) assert self.result.jwk.kty == self.result.jws.alg.key_type self.result.signature = _BE( self.result.jws.sign(self.result.plaintext, self.result.jwk)) self.result.verified = self.result.jws.verify( self.result.plaintext, _BD(self.result.signature), self.result.jwk) print self.result.to_json(indent=2)
def from_jwk(self, jwk): self.material = _BD(jwk.k)
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 from_token(cls, token): return cls.from_json(_BD(token.split('.')[0]))
def verify(self, b64_payload, jwk=None): s_input = self.signing_input(b64_payload) jws = self.all_header() return jws.verify(s_input, _BD(self.signature), jwk)
def text(self): return _BD(self.payload)
def derive(cls, jwk, salt, count, *args, **kwargs): salt = _BD(salt) return PBKDF2(jwk.key.shared_key, salt, count, digestmodule=cls._digester, macmodule=cls._mac).read(cls._wrapper._KEY_LEN)
def length(self): return len(_BD(_LBE(self.material.n))) * 8