def sign_enc_payload(load, timestamp=0, sign_key=None, enc_key=None, sign_alg="SHA256"): """ :param load: The basic information in the payload :param timestamp: A timestamp (seconds since epoch) :param sign_key: A :py:class:`cryptojwt.jwk.hmac.SYMKey` instance :param enc_key: A :py:class:`cryptojwt.jwk.hmac.SYMKey` instance :param sign_alg: Which signing algorithm to use :return: Signed and/or encrypted payload """ # Just sign, sign and encrypt or just encrypt if timestamp: timestamp = str(timestamp) else: timestamp = str(int(time.time())) bytes_load = load.encode("utf-8") bytes_timestamp = timestamp.encode("utf-8") if sign_key: signer = HMACSigner(algorithm=sign_alg) mac = signer.sign(bytes_load + bytes_timestamp, sign_key.key) else: mac = b"" if enc_key: if len(enc_key.key) not in [16, 24, 32]: raise ValueError("Wrong size of enc_key") encrypter = AES_GCMEncrypter(key=enc_key.key) iv = os.urandom(12) if mac: msg = lv_pack(load, timestamp, base64.b64encode(mac).decode("utf-8")) else: msg = lv_pack(load, timestamp) enc_msg = encrypter.encrypt(msg.encode("utf-8"), iv) ctx, tag = split_ctx_and_tag(enc_msg) cookie_payload = [ bytes_timestamp, base64.b64encode(iv), base64.b64encode(ctx), base64.b64encode(tag), ] else: cookie_payload = [bytes_timestamp, bytes_load, base64.b64encode(mac)] return (b"|".join(cookie_payload)).decode("utf-8")
def __call__(self, sid="", ttype="", **kwargs): """ Return a token. :param ttype: Type of token :param prev: Previous token, if there is one to go from :param sid: Session id :return: """ if not ttype and self.type: ttype = self.type else: ttype = "A" if self.lifetime >= 0: exp = str(time_sans_frac() + self.lifetime) else: exp = "-1" # Live for ever tmp = "" rnd = "" while rnd == tmp: # Don't use the same random value again rnd = rndstr(32) # Ultimate length multiple of 16 return base64.b64encode( self.crypt.encrypt(lv_pack(rnd, ttype, sid, exp).encode())).decode("utf-8")