import argparse import logging import sys from jose import jws from pathlib import Path import json def insert_sig_block (j): j['Signature'] = { 'protected' : '', 'signature' : '' } return j if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument('-v', '--verbose', action='count', help='Verbose logging (can be specified multiple times)') parser.add_argument('--pretty', action="store_true", help='Pretty-print the JSON document before signing') parser.add_argument('-i', '--input', type=argparse.FileType('r'), default=sys.stdin, help="Path to input file (if absent, stdin is used)") args = parser.parse_args() match args.verbose: case v if v and v >= 2: logging.basicConfig(level=logging.DEBUG) case 1: logging.basicConfig(level=logging.INFO) case _: logging.basicConfig(level=logging.WARNING) logging.debug(f"Arguments: {args}") json_text = args.input.read() args.input.close() j = json.loads(json_text) j = insert_sig_block(j) indent = None if args.pretty: indent = ' ' presigned_json_text = json.dumps(j, indent=indent) Path('presigned.json').write_text(presigned_json_text) presigned_json_bytes = presigned_json_text.encode('utf-8') signed = jws.sign(presigned_json_bytes, 'secret_key', algorithm="HS256") components = signed.split('.') j['Signature']['protected'] = components[0] j['Signature']['signature'] = components[2] signed_json_text = json.dumps(j, indent=indent) print(signed_json_text)