def public_jwk(self): if not self.material: return None jwk = Jwk( kty="RSA", n=base64.long_to_b64(self.material.n), e=base64.long_to_b64(self.material.e), ) return jwk
def public_jwk(self): crv, x, y = self.public_key_tuple if crv: return Jwk( kty=KeyTypeEnum.EC, crv=CurveEnum("P-{:d}".format(crv)), x=base64.long_to_b64(x), y=base64.long_to_b64(y), )
def to_jwk(self, jwk, force_public=False): '''Set parameters to Jwk ''' crv, x, y = self.public_key_tuple if crv: jwk.kty = KeyTypeEnum.EC jwk.crv = CurveEnum.create("P-{:d}".format(crv)) jwk.x = base64.long_to_b64(x) jwk.y = base64.long_to_b64(y) crv, d = self.private_key_tuple if d: jwk.d = base64.long_to_b64(d)
def private_jwk(self): if not self.material: return None jwk = Jwk( kty="RSA", n=base64.long_to_b64(self.material.n), e=base64.long_to_b64(self.material.e), d=base64.long_to_b64(self.material.d), p=base64.long_to_b64(self.material.p), q=base64.long_to_b64(self.material.q), qi=base64.long_to_b64(self.material.u), ) return jwk
def test_ecdh_check(self): ''' https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-23#appendix-C ''' v_stc_material = { "kty": "EC", "crv": "P-256", "x": "gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0", "y": "SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps", "d": "0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo" } u_epk_material = { "kty": "EC", "crv": "P-256", "x": "weNJy2HscCSM6AEDTDg04biOvhFhyyWvOHQfeF_PxMQ", "y": "e8lnCO-AlStT-NJVX-crhB7QRYhiix03illJOVAOyck", "d": "VEmDZpDXXK8p8N0Cndsxs924q6nS1RXFASRl6BfUqdw" } import re def _to_pub(km): return ( int(re.search(r"P-(\d+)$", km['crv']).group(1)), (base64.long_from_b64(km['x']), base64.long_from_b64(km['y'])), ) def _to_pri(km): return ( int(re.search(r"P-(\d+)$", km['crv']).group(1)), base64.long_from_b64(km['d']), ) pub_tuple = _to_pub(v_stc_material) pri_tuple = _to_pri(v_stc_material) import pydoc curve = pydoc.locate('ecdsa.curves.NIST{0}p'.format(pub_tuple[0])) from ecdsa import ( SigningKey, VerifyingKey, ellipticcurve as ec) x, y = pub_tuple[1] v_pub = VerifyingKey.from_public_point( ec.Point(curve.curve, x, y, curve.order), curve, ) v_stc = SigningKey.from_secret_exponent(pri_tuple[1], curve) # Party U provides a ephemeral key pub_tuple = _to_pub(u_epk_material) pri_tuple = _to_pri(u_epk_material) x, y = pub_tuple[1] u_epk = SigningKey.from_secret_exponent(pri_tuple[1], curve) from jose.jwa.ec import ecdsa_dhZ # Party U compute shared_secret_u = ecdsa_dhZ(v_pub, u_epk) print("Aggreement:", base64.long_to_b64(shared_secret_u)) from Crypto.Util.number import long_to_bytes from math import ceil block_size = int(ceil(pub_tuple[0] / 8.0)) # bit number(512 ) / 8 -> octets Zu = long_to_bytes(shared_secret_u, block_size) Z_jwa = [158, 86, 217, 29, 129, 113, 53, 211, 114, 131, 66, 131, 191, 132, 38, 156, 251, 49, 110, 163, 218, 128, 106, 72, 246, 218, 167, 121, 140, 254, 144, 196] self.assertEqual(_ilist(Zu), Z_jwa) # Other Information used in Concat KDF # AlgorithmID || PartyUInfo || PartyVInfo || SuppPubInfo from struct import pack def _otherInfo(alg, pu, pv, klen): return b('').join([ pack("!I", len(alg)), alg, pack("!I", len(pu)), pu, pack("!I", len(pv)), pv, pack("!I", klen), ]) oi_u = _otherInfo( b("A128GCM"), b("Alice"), b("Bob"), 16 * 8, # A128GCM ) oi_jwa = [ 0, 0, 0, 7, 65, 49, 50, 56, 71, 67, 77, 0, 0, 0, 5, 65, 108, 105, 99, 101, 0, 0, 0, 3, 66, 111, 98, 0, 0, 0, 128] print(">>>>>>>", type(oi_u)) print("<<<<<<<", oi_u) self.assertEqual(_ilist(oi_u), oi_jwa) # Coccat KDF : NIST defines SHA256 from Crypto.Hash import SHA256 def _ConcatKDF(Z, dkLen, otherInfo, digest_method=SHA256): def _src(counter_bytes): return b("").join([counter_bytes, Z, otherInfo]) from math import ceil from struct import pack dkm = b'' # Derived Key Material counter = 0 klen = int(ceil(dkLen / 8.0)) while len(dkm) < klen: counter += 1 counter_b = pack("!I", counter) dkm += digest_method.new(_src(counter_b)).digest() return dkm[:klen] _derived_key_u = _ConcatKDF(Zu, 16 * 8, oi_u) # Party V recive Epemeral Public Key v_epk = u_epk.get_verifying_key() Zv = long_to_bytes(ecdsa_dhZ(v_epk, v_stc), block_size) _derived_key_v = _ConcatKDF(Zv, 16 * 8, oi_u) self.assertEqual(_derived_key_u, _derived_key_v) kd_jwa = [ 86, 170, 141, 234, 248, 35, 109, 32, 92, 34, 40, 205, 113, 167, 16, 26] self.assertEqual(_ilist(_derived_key_u), kd_jwa) self.assertEqual(b("VqqN6vgjbSBcIijNcacQGg"), base64.base64url_encode(_derived_key_u))
def private_jwk(self): jwk = self.public_jwk if jwk: crv, d = self.private_key_tuple jwk.d = base64.long_to_b64(d) return jwk