{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Da Vinci CDEX Digital Signature Document Bundle Example\n", "\n", "This is a Jupyter Notebook using Python 3.7 and openSSl to create JSON Web Signature (JWS)(see RFC 7515) and attaching them to a FHIR Bundle.\n", "\n", "*Although self-signed certificates are used for the purpose of these examples, they are not recommended for production systems.*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Fetch Signed Bundle from FHIR Server\n", "\n", "using AIDBox for now at `https://argopatientlist.aidbox.app/fhir/\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "404\n", "Date = Wed, 16 Feb 2022 07:57:37 GMT\n", "Content-Type = application/fhir+json\n", "Content-Length = 187\n", "Connection = keep-alive\n", "X-Duration = 1\n", "X-Request-Id = 93a28f8679f92f3d3aaf57e7515af7cd\n", "Strict-Transport-Security = max-age=15724800; includeSubDomains\n", "BODY:\n", "{\n", " \"resourceType\": \"OperationOutcome\",\n", " \"text\": {\n", " \"div\": \"GET /fhir/Bundle\\\\foo not found\"\n", " },\n", " \"issue\": [\n", " {\n", " \"severity\": \"error\",\n", " \"code\": \"not-found\",\n", " \"details\": {\n", " \"text\": \"GET /fhir/Bundle\\\\foo not found\"\n", " }\n", " }\n", " ]\n", "}\n" ] } ], "source": [ "from requests import get\n", "from json import dumps\n", "\n", "bundle_id = \"foo\" # insert bundle id here\n", "\n", "url = \"https://argopatientlist.aidbox.app/fhir/Bundle\"\n", "# url = 'http://test.fhir.org/r4/Bundle'\n", "username = \"basic\"\n", "password = \"secret\"\n", "headers = {\"Accept\": \"application/fhir+json\" , \"Content-Type\": \"application/fhir+json\"}\n", "\n", "r = get(f'{url}\\{bundle_id}', auth=(username, password), headers = headers)\n", "print(r.status_code)\n", "for k,v in r.headers.items():\n", " print(f'{k} = {v}')\n", "print(\"BODY:\")\n", "print(dumps(r.json(),indent=2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Receiver/Verifier Steps" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1. Remove the `Bundle.signature` element from the Search Bundle resource\n", "- For this example using the python dictionary object from above, but in real life, it would be contained and/or Referenced by TASK over-the-wire. Therefore it would need to be 'decontained' and/or fetched and stored in order to perform these next steps." ] }, { "cell_type": "code", "execution_count": 216, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'type': [{'system': 'urn:iso-astm:E1762-95:2013',\n", " 'code': '1.2.840.10065.1.12.1.5',\n", " 'display': 'Verification Signature'}],\n", " 'when': '2021-10-05T22:42:19-07:00',\n", " 'who': {'display': 'Practitioner/123'},\n", " 'onBehalfOf': {'display': 'Organization/123'},\n", " 'data': 'ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXQwZVNJNklsSlRJaXdpZEhsd0lqb2lTbGRVSWl3aWRYTmxJam9pYzJsbklpd2llRFZqSWpwYklrMUpTVVV6ZWtORFFUQmxaMEYzU1VKQlowbEtRVTlMUmxsMlRYZFNLM2xSVFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlNVZE9UVkZ6ZDBOUldVUldVVkZIUlhkS1ZsVjZSVlJOUWtWSFFURlZSVU5CZDB0Uk1rWnpZVmRhZG1OdE5YQlpWRVZUVFVKQlIwRXhWVVZDZDNkS1ZUSkdNV015Um5OaFdGSjJUVkpWZDBWM1dVUldVVkZMUkVGNFNWcFhSbk5rUjJoc1VrZEdNRmxVUlhoR2VrRldRbWRPVmtKQlRVMUVhMVo1WVZkTloxTkhSbWhqZVhkblVrWmFUazFUVlhkSmQxbEtTMjlhU1doMlkwNUJVV3RDUm1oYWJHRkhSbWhqTUVKdldsZEdjMlJIYUd4YVIwWXdXVlJGZFdJelNtNU5RalJZUkZSSmVFMVVRWGxPZWtVelRrUkpkMDVHYjFoRVZFbDVUVlJCZVUxcVJUTk9SRWwzVGtadmQyZFpNSGhEZWtGS1FtZE9Wa0pCV1ZSQmJGWlVUVkpOZDBWUldVUldVVkZKUkVGd1JGbFhlSEJhYlRsNVltMXNhRTFTU1hkRlFWbEVWbEZSU0VSQmJGUlpXRlo2V1ZkNGNHUkhPSGhHVkVGVVFtZE9Wa0pCYjAxRVJXaHNXVmQ0TUdGSFZrVlpXRkpvVFZSRldFMUNWVWRCTVZWRlFYZDNUMUpZU25CWmVVSkpXVmRHZWt4RFFrVldhekI0U2xSQmFrSm5hM0ZvYTJsSE9YY3dRa05SUlZkR2JWWnZXVmRHZWxGSGFHeFpWM2d3WVVkV2ExbFlVbWhOVXpWMlkyMWpkMmRuUjJsTlFUQkhRMU54UjFOSllqTkVVVVZDUVZGVlFVRTBTVUpxZDBGM1oyZEhTMEZ2U1VKblVVUndTMk5UYTI5QlRUWnpWekl4SzNaWFZHVkpWazlIZURFd1RWZGhjMUY1TjFaSWFXUTJlbmx4V0VGQ1RTdDZibVpDYmxobGJubFZNR294UmxSMlVHMVNaazlFYjA5RVdGWjFVRlYzUkc5dGFFTklhQ3RpWTJ4WE9VdE5NbTgxTmpOamVGSkxSWFpDYm1GSWNuTnFkelY1VG0xNFR6Vlpha1ZTWW1oMFNHUlJaWEZyZEdSM00xWlpSVkpTT1VodmVFeFBNMFpyYzNwU01qa3lTRlJDTkhoWE0zbFhiRll6WjFSclRWRnZlbEJUWTBwTFNETmlSemhRY1hFMlFWbFFTamRETkZsQ1NXeFZVMlJDVFZac00zRnVaVVZtWnpkbWRYaHBSbVpZYjJaa1ZGWnROM0pOYVdsSE4xZzVlalF6VUdacGJIRmhaV2x6Wm0xMFVuaEJiRkozUlU1WWNrZ3pUM1pQUkZCNVREQnlWRzVIT0VOellrRllXVlpKVFcxa1pFaGxORnBHT1hCc2FEazFjMm8wY0UxVWFFeDBZMHBZTDI4NVdFaE1hbWczUlcxYWVXZEtTRmRGVVhFMFVIZEdkMXBrYldKalptaERiVTl5T0RoSU9FSmlWWEoxTHpkV05ucGljMGN4VGpGRFYyeHVaR3hpVm5wdVRDc3pTVTFQY2pocldHRklZMkZ1Y1daamEyZEdWalJGY201bWFrWktjVEZQU1dGQmJYTk5hamcxZUUxcmFubFlUSGxqVEV3dmRUVnVNbTgyUW1jNU15OVZVbVp4ZFU5dlUwbEhUME5TTWpWRVlWcDZjSGN5YXpOek4yOUZPV1JOZDBWWFdIUm1XR2RaZEdneVlteHFlVFYwUmtnd1IycHdUMnQ0TURkcU4xcFVOVWh1ZUc1c2MwTkJkMFZCUVdGT1FVMUVOSGRFUVZsRVZsSXdWRUpCVlhkQmQwVkNMM3BCVEVKblRsWklVVGhGUWtGTlEwSmxRWGRKVVZsRVZsSXdVa0pDYjNkSFNVbFhaRE5rTTB4dGFHeFpWM2d3WVVkV2ExbFlVbWhoVnpWcVRHMU9kbUpVUVU1Q1oydHhhR3RwUnpsM01FSkJVWE5HUVVGUFEwRlpSVUZEZFUxVlRuRTVZWGtySzJVMVdVTTNVVVpQT1RSeVpucDRSMUZ1UmpOSGEyeGFUa0ZZYlVseU4xQldSMlJwUjFreVIxUjRMemxTZEVoRGQxUkxlbXRNSzNsMlMyOXFaVm81WkZaTE9IZHlSMVpwVW10UEwycFZlVm9yUzJOWFVtOXJWV3B6TlRsdVkwcEhVazFUVTFKNGRHVkRVWFZxZERSb1pqSXJMM0ZXSzJZeWMwMVJkRVZ5ZDFCRk16QjJZbkZTV1ZWT1RrNUNWa1ZSY0dGUmVDOWhZMHBFVlhZNWRqZHpha2hwU2tSeFdIZFJLM0o2YWprMWFVaEJTV0ZsUlVoeFJpOU5jekl5Y0RKaVpWcDFjWFpKVVV0bFRXd3JjM1pXY1VoMGFYVjZWMjVHTkZVMlZrbHRjR3R5TkdKSWJEZGxaMVk1U0Rac05sUXlVMDFyYWpaeFJGVTFaVGxPWnpCYWJFeFVkRzl6YzJoQ1RHMXZjRVkzWlRkSWVYSlVSVUZ0Wms5UVMxRmxNRVZuT1VVeWRYSjZlSEZDZFVjMU5HczFNRWN5U2pCR2FWQnpVVXBCYUVacFRrZDNVMmMwVXpOSWVWWkVSemQxWlV0a01FdzVNM2RMVDA1UFdVZDJUVXRwZWtOSVFpdHdTM1pGVFVwdldqaDVPWFZwUWl0SVJsaGpjRGxTWVVweFNqazNTSEJhVkVWMksyeHBRM0F5VUZOWWVtTkxNSEl5TlZOamVXcEdObVJNYjNWTE1sTkNNekI0UVhaS09IUkZOVGcwSzJweFVUWkRSMlZqVlRsWWFuWnNRV3AxU21SRGNrUmxWbEJ6YW10dU4wOVFXRWNyT0ZoYVZUZDZjVWhhVG0xWVdERlpXVFJJTlhKblJVbzBPR3h5VlhKUU0wazRVaUpkZlEuLmQ0MjByMFk1cGktLU9rSW1DaWhselA0XzhQd1BaaUVRcjRQeTJyZER0QXdubF9OYUU1SDFucXp2bm1qU00zSkhuaEhRakhzeDBZOWxjWEhpc2ZUbUp5QmlNYmhIQ28ycGRHeUx6RTZrbTdNYlktSTYyOXlLRy1ENXNLaFFldklYblRlZ1dHN3h6WTNDQjlHUTMzSUFEcU1EZkctdkg3N21nR2xjQk05WFRJX1liRzZGZUZqd0Z3TGcyenYxM0JWNzI3d3U2RWpDNnhPSHRiQ3NuS1NxUnZheFNZWVIwWWgyNG9jZmJuaVFiWHhEVlNndFFwNWlWUjdQUkdvX29JNEFscHozQVBUcmNaYUVNdXI5VWhoNm81MEZYbkUzZTlpMkM5TThwTkhyY3d4SjdWV2d1UGJ3UGN0dFd0ZG9RYXBKRWQwZnR1WEVwWnhzZ2t3aWgzSGZQQXQ3Vm84a1ZsUkRIM0lrQ0FBNVg2cUtlYzFIU2hYRFp1QklqMFNWVUJHSDFsMlRPb0VCd29nWGhlTDkwbHVqejRBUnpabHdfSzNrQk1tUk10dHVucDdjLWpZYmdubVRpcE1MQW4weWhSOUFsSmdUMVV4Z2FpTE5adTJtekZuMHZSTkU2OU95cm5Rc0Z3THhWQlhCcUJ2NzRyWmNPbGQ5OVJydENEVEdHemlR'}" ] }, "execution_count": 216, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my_bundle = r.json()\n", "\n", "def pop_element(resource, element):\n", " try:\n", " my_element = resource.pop(element) # remove element\n", " return my_element \n", " except KeyError:\n", " pass\n", " \n", "recd_signature = pop_element(my_bundle, 'signature')\n", "recd_signature" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2. Canonicalize the bundle using IETF JSON Canonicalization Scheme (JCS):\n", "\n", "- Remove the id and meta elements if present before canonicalization" ] }, { "cell_type": "code", "execution_count": 217, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(b'{\"entry\":[{\"fullUrl\":\"http://fhir.healthintersections.com.au/open/Composition/180f219f-97a8-486d-99d9-ed631fe4fc57\",\"resource\":{\"author\":[{\"display\":\"Doctor Dave\",\"reference\":\"Practitioner/example\"}],\"confidentiality\":\"N\",\"date\":\"2013-02-01T12:30:02Z\",\"encounter\":{\"reference\":\"http://fhir.healthintersections.com.au/open/Encounter/doc-example\"},\"id\":\"180f219f-97a8-486d-99d9-ed631fe4fc57\",\"meta\":{\"lastUpdated\":\"2013-05-28T22:12:21Z\"},\"resourceType\":\"Composition\",\"section\":[{\"code\":{\"coding\":[{\"code\":\"29299-5\",\"display\":\"Reason for visit Narrative\",\"system\":\"http://loinc.org\"}]},\"entry\":[{\"reference\":\"urn:uuid:541a72a8-df75-4484-ac89-ac4923f03b81\"}],\"text\":{\"div\":\"
\\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n
Details\\\\n\\\\n
Acute Asthmatic attack. Was wheezing for days prior to admission.\\\\n\\\\n
\\\\n\\\\n
\",\"status\":\"additional\"},\"title\":\"Reason for admission\"},{\"code\":{\"coding\":[{\"code\":\"10183-2\",\"display\":\"Hospital discharge medications Narrative\",\"system\":\"http://loinc.org\"}]},\"entry\":[{\"reference\":\"urn:uuid:124a6916-5d84-4b8c-b250-10cefb8e6e86\"},{\"reference\":\"urn:uuid:673f8db5-0ffd-4395-9657-6da00420bbc1\"}],\"mode\":\"working\",\"text\":{\"div\":\"
\\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n
MedicationLast ChangeLast ChangeReason
Theophylline 200mg BD after mealscontinued
Ventolin InhalerstoppedGetting side effect of tremor
\\\\n\\\\n
\",\"status\":\"additional\"},\"title\":\"Medications on Discharge\"},{\"code\":{\"coding\":[{\"code\":\"48765-2\",\"display\":\"Allergies and adverse reactions Document\",\"system\":\"http://loinc.org\"}]},\"entry\":[{\"reference\":\"urn:uuid:47600e0f-b6b5-4308-84b5-5dec157f7637\"}],\"text\":{\"div\":\"
\\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n \\\\n\\\\n
AllergenReaction
DoxycyclineHives
\\\\n\\\\n
\",\"status\":\"additional\"},\"title\":\"Known allergies\"}],\"status\":\"final\",\"subject\":{\"display\":\"Eve Everywoman\",\"reference\":\"http://fhir.healthintersections.com.au/open/Patient/d1\"},\"text\":{\"div\":\"

Generated Narrative with Details

id: 180f219f-97a8-486d-99d9-ed631fe4fc57

meta:

status: final

type: Discharge Summary from Responsible Clinician (Details : {LOINC code \\'28655-9\\' = \\'Physician attending Discharge summary)

encounter: http://fhir.healthintersections.com.au/open/Encounter/doc-example

date: 01/02/2013 12:30:02 PM

author: Doctor Dave

title: Discharge Summary

confidentiality: N

\",\"status\":\"generated\"},\"title\":\"Discharge Summary\",\"type\":{\"coding\":[{\"code\":\"28655-9\",\"system\":\"http://loinc.org\"}],\"text\":\"Discharge Summary from Responsible Clinician\"}}},{\"fullUrl\":\"http://fhir.healthintersections.com.au/open/Practitioner/example\",\"resource\":{\"id\":\"example\",\"identifier\":[{\"system\":\"http://www.acme.org/practitioners\",\"value\":\"23\"}],\"meta\":{\"lastUpdated\":\"2013-05-05T16:13:03Z\"},\"name\":[{\"family\":\"Careful\",\"given\":[\"Adam\"],\"prefix\":[\"Dr\"]}],\"resourceType\":\"Practitioner\",\"text\":{\"div\":\"
\\\\n\\\\n

Dr Adam Careful

\\\\n\\\\n
\",\"status\":\"generated\"}}},{\"fullUrl\":\"http://fhir.healthintersections.com.au/open/Patient/d1\",\"resource\":{\"active\":true,\"address\":[{\"line\":[\"2222 Home Street\"],\"use\":\"home\"}],\"birthDate\":\"1955-01-06\",\"gender\":\"female\",\"id\":\"d1\",\"name\":[{\"family\":\"Everywoman1\",\"given\":[\"Eve\"],\"text\":\"Eve Everywoman\"}],\"resourceType\":\"Patient\",\"telecom\":[{\"system\":\"phone\",\"use\":\"work\",\"value\":\"555-555-2003\"}],\"text\":{\"div\":\"
\\\\n\\\\n

Eve Everywoman

\\\\n\\\\n
\",\"status\":\"generated\"}}},{\"fullUrl\":\"http://fhir.healthintersections.com.au/open/Encounter/doc-example\",\"resource\":{\"class\":{\"code\":\"IMP\",\"display\":\"inpatient encounter\",\"system\":\"http://terminology.hl7.org/CodeSystem/v3-ActCode\"},\"hospitalization\":{\"dischargeDisposition\":{\"text\":\"Discharged to care of GP\"}},\"id\":\"doc-example\",\"identifier\":[{\"value\":\"S100\"}],\"meta\":{\"lastUpdated\":\"2013-05-05T16:13:03Z\"},\"period\":{\"end\":\"2013-02-01T12:30:02Z\",\"start\":\"2013-01-20T12:30:02Z\"},\"resourceType\":\"Encounter\",\"status\":\"finished\",\"subject\":{\"reference\":\"Patient/d1\"},\"text\":{\"div\":\"
Admitted to Orthopedics Service,\\\\n Middlemore Hospital between Jan 20 and Feb ist 2013
\",\"status\":\"generated\"},\"type\":[{\"text\":\"Orthopedic Admission\"}]}},{\"fullUrl\":\"urn:uuid:541a72a8-df75-4484-ac89-ac4923f03b81\",\"resource\":{\"code\":{\"coding\":[{\"code\":\"46241-6\",\"system\":\"http://loinc.org\"}],\"text\":\"Reason for admission\"},\"encounter\":{\"reference\":\"http://fhir.healthintersections.com.au/open/Encounter/doc-example\"},\"meta\":{\"lastUpdated\":\"2013-05-05T16:13:03Z\"},\"resourceType\":\"Observation\",\"status\":\"final\",\"subject\":{\"display\":\"Eve Everywoman\",\"reference\":\"http://fhir.healthintersections.com.au/open/Patient/d1\"},\"text\":{\"div\":\"
Acute Asthmatic attack. Was wheezing\\\\n for days prior to admission.
\",\"status\":\"additional\"},\"valueString\":\"Acute Asthmatic attack. Was wheezing for days prior to admission.\"}},{\"fullUrl\":\"urn:uuid:124a6916-5d84-4b8c-b250-10cefb8e6e86\",\"resource\":{\"dosageInstruction\":[{\"additionalInstruction\":[{\"text\":\"Take with Food\"}],\"doseAndRate\":[{\"doseQuantity\":{\"code\":\"tbl\",\"system\":\"http://unitsofmeasure.org\",\"unit\":\"tablet\",\"value\":1},\"type\":{\"coding\":[{\"code\":\"ordered\",\"display\":\"Ordered\",\"system\":\"http://terminology.hl7.org/CodeSystem/dose-rate-type\"}]}}],\"route\":{\"coding\":[{\"code\":\"394899003\",\"display\":\"oral administration of treatment\",\"system\":\"http://snomed.info/sct\"}]},\"timing\":{\"repeat\":{\"frequency\":2,\"period\":1,\"periodUnit\":\"d\"}}}],\"intent\":\"order\",\"medicationCodeableConcept\":{\"coding\":[{\"code\":\"66493003\",\"system\":\"http://snomed.info/sct\"}],\"text\":\"Theophylline 200mg\"},\"meta\":{\"lastUpdated\":\"2013-05-05T16:13:03Z\"},\"reasonCode\":[{\"text\":\"Management of Asthma\"}],\"requester\":{\"display\":\"Peter Practitioner\",\"reference\":\"Practitioner/example\"},\"resourceType\":\"MedicationRequest\",\"status\":\"unknown\",\"subject\":{\"display\":\"Peter Patient\",\"reference\":\"http://fhir.healthintersections.com.au/open/Patient/d1\"},\"text\":{\"div\":\"
\\\\n\\\\n

Theophylline 200mg twice a day

\\\\n\\\\n
\",\"status\":\"generated\"}}},{\"fullUrl\":\"urn:uuid:673f8db5-0ffd-4395-9657-6da00420bbc1\",\"resource\":{\"dateAsserted\":\"2013-05-05T16:13:03Z\",\"medicationCodeableConcept\":{\"text\":\"Ventolin Inhaler\"},\"resourceType\":\"MedicationStatement\",\"status\":\"active\",\"statusReason\":[{\"text\":\"Management of Asthma\"}],\"subject\":{\"display\":\"Peter Patient\",\"reference\":\"http://fhir.healthintersections.com.au/open/Patient/d1\"},\"text\":{\"div\":\"
\\\\n\\\\n

Ventolin inhaler discontinued

\\\\n\\\\n
\",\"status\":\"generated\"}}},{\"fullUrl\":\"urn:uuid:47600e0f-b6b5-4308-84b5-5dec157f7637\",\"resource\":{\"clinicalStatus\":{\"coding\":[{\"code\":\"active\",\"display\":\"Active\",\"system\":\"http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical\"}]},\"code\":{\"text\":\"Doxycycline\"},\"criticality\":\"high\",\"meta\":{\"lastUpdated\":\"2013-05-05T16:13:03Z\"},\"patient\":{\"display\":\"Eve Everywoman\",\"reference\":\"http://fhir.healthintersections.com.au/open/Patient/d1\"},\"reaction\":[{\"manifestation\":[{\"coding\":[{\"code\":\"xxx\",\"display\":\"Hives\",\"system\":\"http://example.org/system\"}],\"text\":\"Hives\"}]}],\"recordedDate\":\"2012-09-17\",\"resourceType\":\"AllergyIntolerance\",\"text\":{\"div\":\"
Sensitivity to Doxycycline :\\\\n Hives
\",\"status\":\"generated\"},\"type\":\"allergy\",\"verificationStatus\":{\"coding\":[{\"code\":\"confirmed\",\"display\":\"Confirmed\",\"system\":\"http://terminology.hl7.org/CodeSystem/allergyintolerance-verification\"}]}}}],\"identifier\":{\"system\":\"urn:ietf:rfc:3986\",\"value\":\"urn:uuid:0c3151bd-1cbf-4d64-b04d-cd9187a4c6e0\"},\"resourceType\":\"Bundle\",\"timestamp\":\"2013-05-28T22:12:21Z\",\"type\":\"document\"}',\n", " 9388)" ] }, "execution_count": 217, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from jcs import canonicalize #package for a JCS (RFC 8785) compliant canonicalizer.\n", "my_bundle_id = pop_element(my_bundle, 'id')\n", "my_bundle_meta = pop_element(my_bundle, 'meta')\n", "canonical_bundle = canonicalize(my_bundle)\n", "canonical_bundle, len(canonical_bundle)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3. Transform canonicalize Bundle to a base64 format using the Base64-URL algorithm." ] }, { "cell_type": "code", "execution_count": 218, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'eyJlbnRyeSI6W3siZnVsbFVybCI6Imh0dHA6Ly9maGlyLmhlYWx0aGludGVyc2VjdGlvbnMuY29tLmF1L29wZW4vQ29tcG9zaXRpb24vMTgwZjIxOWYtOTdhOC00ODZkLTk5ZDktZWQ2MzFmZTRmYzU3IiwicmVzb3VyY2UiOnsiYXV0aG9yIjpbeyJkaXNwbGF5IjoiRG9jdG9yIERhdmUiLCJyZWZlcmVuY2UiOiJQcmFjdGl0aW9uZXIvZXhhbXBsZSJ9XSwiY29uZmlkZW50aWFsaXR5IjoiTiIsImRhdGUiOiIyMDEzLTAyLTAxVDEyOjMwOjAyWiIsImVuY291bnRlciI6eyJyZWZlcmVuY2UiOiJodHRwOi8vZmhpci5oZWFsdGhpbnRlcnNlY3Rpb25zLmNvbS5hdS9vcGVuL0VuY291bnRlci9kb2MtZXhhbXBsZSJ9LCJpZCI6IjE4MGYyMTlmLTk3YTgtNDg2ZC05OWQ5LWVkNjMxZmU0ZmM1NyIsIm1ldGEiOnsibGFzdFVwZGF0ZWQiOiIyMDEzLTA1LTI4VDIyOjEyOjIxWiJ9LCJyZXNvdXJjZVR5cGUiOiJDb21wb3NpdGlvbiIsInNlY3Rpb24iOlt7ImNvZGUiOnsiY29kaW5nIjpbeyJjb2RlIjoiMjkyOTktNSIsImRpc3BsYXkiOiJSZWFzb24gZm9yIHZpc2l0IE5hcnJhdGl2ZSIsInN5c3RlbSI6Imh0dHA6Ly9sb2luYy5vcmcifV19LCJlbnRyeSI6W3sicmVmZXJlbmNlIjoidXJuOnV1aWQ6NTQxYTcyYTgtZGY3NS00NDg0LWFjODktYWM0OTIzZjAzYjgxIn1dLCJ0ZXh0Ijp7ImRpdiI6IjxkaXYgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI-XG5cbiAgICAgICAgICAgICAgPHRhYmxlPlxuXG4gICAgICAgICAgICAgICAgPHRoZWFkPlxuXG4gICAgICAgICAgICAgICAgICA8dHI-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPkRldGFpbHM8L3RkPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ZC8-XG5cbiAgICAgICAgICAgICAgICAgIDwvdHI-XG5cbiAgICAgICAgICAgICAgICA8L3RoZWFkPlxuXG4gICAgICAgICAgICAgICAgPHRib2R5PlxuXG4gICAgICAgICAgICAgICAgICA8dHI-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPkFjdXRlIEFzdGhtYXRpYyBhdHRhY2suIFdhcyB3aGVlemluZyBmb3IgZGF5cyBwcmlvciB0byBhZG1pc3Npb24uPC90ZD5cblxuICAgICAgICAgICAgICAgICAgICA8dGQvPlxuXG4gICAgICAgICAgICAgICAgICA8L3RyPlxuXG4gICAgICAgICAgICAgICAgPC90Ym9keT5cblxuICAgICAgICAgICAgICA8L3RhYmxlPlxuXG4gICAgICAgICAgICA8L2Rpdj4iLCJzdGF0dXMiOiJhZGRpdGlvbmFsIn0sInRpdGxlIjoiUmVhc29uIGZvciBhZG1pc3Npb24ifSx7ImNvZGUiOnsiY29kaW5nIjpbeyJjb2RlIjoiMTAxODMtMiIsImRpc3BsYXkiOiJIb3NwaXRhbCBkaXNjaGFyZ2UgbWVkaWNhdGlvbnMgTmFycmF0aXZlIiwic3lzdGVtIjoiaHR0cDovL2xvaW5jLm9yZyJ9XX0sImVudHJ5IjpbeyJyZWZlcmVuY2UiOiJ1cm46dXVpZDoxMjRhNjkxNi01ZDg0LTRiOGMtYjI1MC0xMGNlZmI4ZTZlODYifSx7InJlZmVyZW5jZSI6InVybjp1dWlkOjY3M2Y4ZGI1LTBmZmQtNDM5NS05NjU3LTZkYTAwNDIwYmJjMSJ9XSwibW9kZSI6IndvcmtpbmciLCJ0ZXh0Ijp7ImRpdiI6IjxkaXYgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI-XG5cbiAgICAgICAgICAgICAgPHRhYmxlPlxuXG4gICAgICAgICAgICAgICAgPHRoZWFkPlxuXG4gICAgICAgICAgICAgICAgICA8dHI-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPk1lZGljYXRpb248L3RkPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ZD5MYXN0IENoYW5nZTwvdGQ-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPkxhc3QgQ2hhbmdlUmVhc29uPC90ZD5cblxuICAgICAgICAgICAgICAgICAgPC90cj5cblxuICAgICAgICAgICAgICAgIDwvdGhlYWQ-XG5cbiAgICAgICAgICAgICAgICA8dGJvZHk-XG5cbiAgICAgICAgICAgICAgICAgIDx0cj5cblxuICAgICAgICAgICAgICAgICAgICA8dGQ-VGhlb3BoeWxsaW5lIDIwMG1nIEJEIGFmdGVyIG1lYWxzPC90ZD5cblxuICAgICAgICAgICAgICAgICAgICA8dGQ-Y29udGludWVkPC90ZD5cblxuICAgICAgICAgICAgICAgICAgPC90cj5cblxuICAgICAgICAgICAgICAgICAgPHRyPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ZD5WZW50b2xpbiBJbmhhbGVyPC90ZD5cblxuICAgICAgICAgICAgICAgICAgICA8dGQ-c3RvcHBlZDwvdGQ-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPkdldHRpbmcgc2lkZSBlZmZlY3Qgb2YgdHJlbW9yPC90ZD5cblxuICAgICAgICAgICAgICAgICAgPC90cj5cblxuICAgICAgICAgICAgICAgIDwvdGJvZHk-XG5cbiAgICAgICAgICAgICAgPC90YWJsZT5cblxuICAgICAgICAgICAgPC9kaXY-Iiwic3RhdHVzIjoiYWRkaXRpb25hbCJ9LCJ0aXRsZSI6Ik1lZGljYXRpb25zIG9uIERpc2NoYXJnZSJ9LHsiY29kZSI6eyJjb2RpbmciOlt7ImNvZGUiOiI0ODc2NS0yIiwiZGlzcGxheSI6IkFsbGVyZ2llcyBhbmQgYWR2ZXJzZSByZWFjdGlvbnMgRG9jdW1lbnQiLCJzeXN0ZW0iOiJodHRwOi8vbG9pbmMub3JnIn1dfSwiZW50cnkiOlt7InJlZmVyZW5jZSI6InVybjp1dWlkOjQ3NjAwZTBmLWI2YjUtNDMwOC04NGI1LTVkZWMxNTdmNzYzNyJ9XSwidGV4dCI6eyJkaXYiOiI8ZGl2IHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiPlxuXG4gICAgICAgICAgICAgIDx0YWJsZT5cblxuICAgICAgICAgICAgICAgIDx0aGVhZD5cblxuICAgICAgICAgICAgICAgICAgPHRyPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ZD5BbGxlcmdlbjwvdGQ-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPlJlYWN0aW9uPC90ZD5cblxuICAgICAgICAgICAgICAgICAgPC90cj5cblxuICAgICAgICAgICAgICAgIDwvdGhlYWQ-XG5cbiAgICAgICAgICAgICAgICA8dGJvZHk-XG5cbiAgICAgICAgICAgICAgICAgIDx0cj5cblxuICAgICAgICAgICAgICAgICAgICA8dGQ-RG94eWN5Y2xpbmU8L3RkPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ZD5IaXZlczwvdGQ-XG5cbiAgICAgICAgICAgICAgICAgIDwvdHI-XG5cbiAgICAgICAgICAgICAgICA8L3Rib2R5PlxuXG4gICAgICAgICAgICAgIDwvdGFibGU-XG5cbiAgICAgICAgICAgIDwvZGl2PiIsInN0YXR1cyI6ImFkZGl0aW9uYWwifSwidGl0bGUiOiJLbm93biBhbGxlcmdpZXMifV0sInN0YXR1cyI6ImZpbmFsIiwic3ViamVjdCI6eyJkaXNwbGF5IjoiRXZlIEV2ZXJ5d29tYW4iLCJyZWZlcmVuY2UiOiJodHRwOi8vZmhpci5oZWFsdGhpbnRlcnNlY3Rpb25zLmNvbS5hdS9vcGVuL1BhdGllbnQvZDEifSwidGV4dCI6eyJkaXYiOiI8ZGl2IHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiPjxwPjxiPkdlbmVyYXRlZCBOYXJyYXRpdmUgd2l0aCBEZXRhaWxzPC9iPjwvcD48cD48Yj5pZDwvYj46IDE4MGYyMTlmLTk3YTgtNDg2ZC05OWQ5LWVkNjMxZmU0ZmM1NzwvcD48cD48Yj5tZXRhPC9iPjogPC9wPjxwPjxiPnN0YXR1czwvYj46IGZpbmFsPC9wPjxwPjxiPnR5cGU8L2I-OiBEaXNjaGFyZ2UgU3VtbWFyeSBmcm9tIFJlc3BvbnNpYmxlIENsaW5pY2lhbiA8c3Bhbj4oRGV0YWlscyA6IHtMT0lOQyBjb2RlICcyODY1NS05JyA9ICdQaHlzaWNpYW4gYXR0ZW5kaW5nIERpc2NoYXJnZSBzdW1tYXJ5KTwvc3Bhbj48L3A-PHA-PGI-ZW5jb3VudGVyPC9iPjogPGE-aHR0cDovL2ZoaXIuaGVhbHRoaW50ZXJzZWN0aW9ucy5jb20uYXUvb3Blbi9FbmNvdW50ZXIvZG9jLWV4YW1wbGU8L2E-PC9wPjxwPjxiPmRhdGU8L2I-OiAwMS8wMi8yMDEzIDEyOjMwOjAyIFBNPC9wPjxwPjxiPmF1dGhvcjwvYj46IDxhPkRvY3RvciBEYXZlPC9hPjwvcD48cD48Yj50aXRsZTwvYj46IERpc2NoYXJnZSBTdW1tYXJ5PC9wPjxwPjxiPmNvbmZpZGVudGlhbGl0eTwvYj46IE48L3A-PC9kaXY-Iiwic3RhdHVzIjoiZ2VuZXJhdGVkIn0sInRpdGxlIjoiRGlzY2hhcmdlIFN1bW1hcnkiLCJ0eXBlIjp7ImNvZGluZyI6W3siY29kZSI6IjI4NjU1LTkiLCJzeXN0ZW0iOiJodHRwOi8vbG9pbmMub3JnIn1dLCJ0ZXh0IjoiRGlzY2hhcmdlIFN1bW1hcnkgZnJvbSBSZXNwb25zaWJsZSBDbGluaWNpYW4ifX19LHsiZnVsbFVybCI6Imh0dHA6Ly9maGlyLmhlYWx0aGludGVyc2VjdGlvbnMuY29tLmF1L29wZW4vUHJhY3RpdGlvbmVyL2V4YW1wbGUiLCJyZXNvdXJjZSI6eyJpZCI6ImV4YW1wbGUiLCJpZGVudGlmaWVyIjpbeyJzeXN0ZW0iOiJodHRwOi8vd3d3LmFjbWUub3JnL3ByYWN0aXRpb25lcnMiLCJ2YWx1ZSI6IjIzIn1dLCJtZXRhIjp7Imxhc3RVcGRhdGVkIjoiMjAxMy0wNS0wNVQxNjoxMzowM1oifSwibmFtZSI6W3siZmFtaWx5IjoiQ2FyZWZ1bCIsImdpdmVuIjpbIkFkYW0iXSwicHJlZml4IjpbIkRyIl19XSwicmVzb3VyY2VUeXBlIjoiUHJhY3RpdGlvbmVyIiwidGV4dCI6eyJkaXYiOiI8ZGl2IHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiPlxuXG4gICAgICAgICAgICA8cD5EciBBZGFtIENhcmVmdWw8L3A-XG5cbiAgICAgICAgICA8L2Rpdj4iLCJzdGF0dXMiOiJnZW5lcmF0ZWQifX19LHsiZnVsbFVybCI6Imh0dHA6Ly9maGlyLmhlYWx0aGludGVyc2VjdGlvbnMuY29tLmF1L29wZW4vUGF0aWVudC9kMSIsInJlc291cmNlIjp7ImFjdGl2ZSI6dHJ1ZSwiYWRkcmVzcyI6W3sibGluZSI6WyIyMjIyIEhvbWUgU3RyZWV0Il0sInVzZSI6ImhvbWUifV0sImJpcnRoRGF0ZSI6IjE5NTUtMDEtMDYiLCJnZW5kZXIiOiJmZW1hbGUiLCJpZCI6ImQxIiwibmFtZSI6W3siZmFtaWx5IjoiRXZlcnl3b21hbjEiLCJnaXZlbiI6WyJFdmUiXSwidGV4dCI6IkV2ZSBFdmVyeXdvbWFuIn1dLCJyZXNvdXJjZVR5cGUiOiJQYXRpZW50IiwidGVsZWNvbSI6W3sic3lzdGVtIjoicGhvbmUiLCJ1c2UiOiJ3b3JrIiwidmFsdWUiOiI1NTUtNTU1LTIwMDMifV0sInRleHQiOnsiZGl2IjoiPGRpdiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIj5cblxuICAgICAgICAgICAgPGgxPkV2ZSBFdmVyeXdvbWFuPC9oMT5cblxuICAgICAgICAgIDwvZGl2PiIsInN0YXR1cyI6ImdlbmVyYXRlZCJ9fX0seyJmdWxsVXJsIjoiaHR0cDovL2ZoaXIuaGVhbHRoaW50ZXJzZWN0aW9ucy5jb20uYXUvb3Blbi9FbmNvdW50ZXIvZG9jLWV4YW1wbGUiLCJyZXNvdXJjZSI6eyJjbGFzcyI6eyJjb2RlIjoiSU1QIiwiZGlzcGxheSI6ImlucGF0aWVudCBlbmNvdW50ZXIiLCJzeXN0ZW0iOiJodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL3YzLUFjdENvZGUifSwiaG9zcGl0YWxpemF0aW9uIjp7ImRpc2NoYXJnZURpc3Bvc2l0aW9uIjp7InRleHQiOiJEaXNjaGFyZ2VkIHRvIGNhcmUgb2YgR1AifX0sImlkIjoiZG9jLWV4YW1wbGUiLCJpZGVudGlmaWVyIjpbeyJ2YWx1ZSI6IlMxMDAifV0sIm1ldGEiOnsibGFzdFVwZGF0ZWQiOiIyMDEzLTA1LTA1VDE2OjEzOjAzWiJ9LCJwZXJpb2QiOnsiZW5kIjoiMjAxMy0wMi0wMVQxMjozMDowMloiLCJzdGFydCI6IjIwMTMtMDEtMjBUMTI6MzA6MDJaIn0sInJlc291cmNlVHlwZSI6IkVuY291bnRlciIsInN0YXR1cyI6ImZpbmlzaGVkIiwic3ViamVjdCI6eyJyZWZlcmVuY2UiOiJQYXRpZW50L2QxIn0sInRleHQiOnsiZGl2IjoiPGRpdiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIj4gQWRtaXR0ZWQgdG8gT3J0aG9wZWRpY3MgU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIE1pZGRsZW1vcmUgSG9zcGl0YWwgYmV0d2VlbiBKYW4gMjAgYW5kIEZlYiBpc3QgMjAxMyA8L2Rpdj4iLCJzdGF0dXMiOiJnZW5lcmF0ZWQifSwidHlwZSI6W3sidGV4dCI6Ik9ydGhvcGVkaWMgQWRtaXNzaW9uIn1dfX0seyJmdWxsVXJsIjoidXJuOnV1aWQ6NTQxYTcyYTgtZGY3NS00NDg0LWFjODktYWM0OTIzZjAzYjgxIiwicmVzb3VyY2UiOnsiY29kZSI6eyJjb2RpbmciOlt7ImNvZGUiOiI0NjI0MS02Iiwic3lzdGVtIjoiaHR0cDovL2xvaW5jLm9yZyJ9XSwidGV4dCI6IlJlYXNvbiBmb3IgYWRtaXNzaW9uIn0sImVuY291bnRlciI6eyJyZWZlcmVuY2UiOiJodHRwOi8vZmhpci5oZWFsdGhpbnRlcnNlY3Rpb25zLmNvbS5hdS9vcGVuL0VuY291bnRlci9kb2MtZXhhbXBsZSJ9LCJtZXRhIjp7Imxhc3RVcGRhdGVkIjoiMjAxMy0wNS0wNVQxNjoxMzowM1oifSwicmVzb3VyY2VUeXBlIjoiT2JzZXJ2YXRpb24iLCJzdGF0dXMiOiJmaW5hbCIsInN1YmplY3QiOnsiZGlzcGxheSI6IkV2ZSBFdmVyeXdvbWFuIiwicmVmZXJlbmNlIjoiaHR0cDovL2ZoaXIuaGVhbHRoaW50ZXJzZWN0aW9ucy5jb20uYXUvb3Blbi9QYXRpZW50L2QxIn0sInRleHQiOnsiZGl2IjoiPGRpdiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIj4gQWN1dGUgQXN0aG1hdGljIGF0dGFjay4gV2FzIHdoZWV6aW5nXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgZGF5cyBwcmlvciB0byBhZG1pc3Npb24uIDwvZGl2PiIsInN0YXR1cyI6ImFkZGl0aW9uYWwifSwidmFsdWVTdHJpbmciOiJBY3V0ZSBBc3RobWF0aWMgYXR0YWNrLiBXYXMgd2hlZXppbmcgZm9yIGRheXMgcHJpb3IgdG8gYWRtaXNzaW9uLiJ9fSx7ImZ1bGxVcmwiOiJ1cm46dXVpZDoxMjRhNjkxNi01ZDg0LTRiOGMtYjI1MC0xMGNlZmI4ZTZlODYiLCJyZXNvdXJjZSI6eyJkb3NhZ2VJbnN0cnVjdGlvbiI6W3siYWRkaXRpb25hbEluc3RydWN0aW9uIjpbeyJ0ZXh0IjoiVGFrZSB3aXRoIEZvb2QifV0sImRvc2VBbmRSYXRlIjpbeyJkb3NlUXVhbnRpdHkiOnsiY29kZSI6InRibCIsInN5c3RlbSI6Imh0dHA6Ly91bml0c29mbWVhc3VyZS5vcmciLCJ1bml0IjoidGFibGV0IiwidmFsdWUiOjF9LCJ0eXBlIjp7ImNvZGluZyI6W3siY29kZSI6Im9yZGVyZWQiLCJkaXNwbGF5IjoiT3JkZXJlZCIsInN5c3RlbSI6Imh0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vZG9zZS1yYXRlLXR5cGUifV19fV0sInJvdXRlIjp7ImNvZGluZyI6W3siY29kZSI6IjM5NDg5OTAwMyIsImRpc3BsYXkiOiJvcmFsIGFkbWluaXN0cmF0aW9uIG9mIHRyZWF0bWVudCIsInN5c3RlbSI6Imh0dHA6Ly9zbm9tZWQuaW5mby9zY3QifV19LCJ0aW1pbmciOnsicmVwZWF0Ijp7ImZyZXF1ZW5jeSI6MiwicGVyaW9kIjoxLCJwZXJpb2RVbml0IjoiZCJ9fX1dLCJpbnRlbnQiOiJvcmRlciIsIm1lZGljYXRpb25Db2RlYWJsZUNvbmNlcHQiOnsiY29kaW5nIjpbeyJjb2RlIjoiNjY0OTMwMDMiLCJzeXN0ZW0iOiJodHRwOi8vc25vbWVkLmluZm8vc2N0In1dLCJ0ZXh0IjoiVGhlb3BoeWxsaW5lIDIwMG1nIn0sIm1ldGEiOnsibGFzdFVwZGF0ZWQiOiIyMDEzLTA1LTA1VDE2OjEzOjAzWiJ9LCJyZWFzb25Db2RlIjpbeyJ0ZXh0IjoiTWFuYWdlbWVudCBvZiBBc3RobWEifV0sInJlcXVlc3RlciI6eyJkaXNwbGF5IjoiUGV0ZXIgUHJhY3RpdGlvbmVyIiwicmVmZXJlbmNlIjoiUHJhY3RpdGlvbmVyL2V4YW1wbGUifSwicmVzb3VyY2VUeXBlIjoiTWVkaWNhdGlvblJlcXVlc3QiLCJzdGF0dXMiOiJ1bmtub3duIiwic3ViamVjdCI6eyJkaXNwbGF5IjoiUGV0ZXIgUGF0aWVudCIsInJlZmVyZW5jZSI6Imh0dHA6Ly9maGlyLmhlYWx0aGludGVyc2VjdGlvbnMuY29tLmF1L29wZW4vUGF0aWVudC9kMSJ9LCJ0ZXh0Ijp7ImRpdiI6IjxkaXYgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI-XG5cbiAgICAgICAgICAgIDxwPlRoZW9waHlsbGluZSAyMDBtZyB0d2ljZSBhIGRheTwvcD5cblxuICAgICAgICAgIDwvZGl2PiIsInN0YXR1cyI6ImdlbmVyYXRlZCJ9fX0seyJmdWxsVXJsIjoidXJuOnV1aWQ6NjczZjhkYjUtMGZmZC00Mzk1LTk2NTctNmRhMDA0MjBiYmMxIiwicmVzb3VyY2UiOnsiZGF0ZUFzc2VydGVkIjoiMjAxMy0wNS0wNVQxNjoxMzowM1oiLCJtZWRpY2F0aW9uQ29kZWFibGVDb25jZXB0Ijp7InRleHQiOiJWZW50b2xpbiBJbmhhbGVyIn0sInJlc291cmNlVHlwZSI6Ik1lZGljYXRpb25TdGF0ZW1lbnQiLCJzdGF0dXMiOiJhY3RpdmUiLCJzdGF0dXNSZWFzb24iOlt7InRleHQiOiJNYW5hZ2VtZW50IG9mIEFzdGhtYSJ9XSwic3ViamVjdCI6eyJkaXNwbGF5IjoiUGV0ZXIgUGF0aWVudCIsInJlZmVyZW5jZSI6Imh0dHA6Ly9maGlyLmhlYWx0aGludGVyc2VjdGlvbnMuY29tLmF1L29wZW4vUGF0aWVudC9kMSJ9LCJ0ZXh0Ijp7ImRpdiI6IjxkaXYgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI-XG5cbiAgICAgICAgICAgIDxwPlZlbnRvbGluIGluaGFsZXIgZGlzY29udGludWVkPC9wPlxuXG4gICAgICAgICAgPC9kaXY-Iiwic3RhdHVzIjoiZ2VuZXJhdGVkIn19fSx7ImZ1bGxVcmwiOiJ1cm46dXVpZDo0NzYwMGUwZi1iNmI1LTQzMDgtODRiNS01ZGVjMTU3Zjc2MzciLCJyZXNvdXJjZSI6eyJjbGluaWNhbFN0YXR1cyI6eyJjb2RpbmciOlt7ImNvZGUiOiJhY3RpdmUiLCJkaXNwbGF5IjoiQWN0aXZlIiwic3lzdGVtIjoiaHR0cDovL3Rlcm1pbm9sb2d5LmhsNy5vcmcvQ29kZVN5c3RlbS9hbGxlcmd5aW50b2xlcmFuY2UtY2xpbmljYWwifV19LCJjb2RlIjp7InRleHQiOiJEb3h5Y3ljbGluZSJ9LCJjcml0aWNhbGl0eSI6ImhpZ2giLCJtZXRhIjp7Imxhc3RVcGRhdGVkIjoiMjAxMy0wNS0wNVQxNjoxMzowM1oifSwicGF0aWVudCI6eyJkaXNwbGF5IjoiRXZlIEV2ZXJ5d29tYW4iLCJyZWZlcmVuY2UiOiJodHRwOi8vZmhpci5oZWFsdGhpbnRlcnNlY3Rpb25zLmNvbS5hdS9vcGVuL1BhdGllbnQvZDEifSwicmVhY3Rpb24iOlt7Im1hbmlmZXN0YXRpb24iOlt7ImNvZGluZyI6W3siY29kZSI6Inh4eCIsImRpc3BsYXkiOiJIaXZlcyIsInN5c3RlbSI6Imh0dHA6Ly9leGFtcGxlLm9yZy9zeXN0ZW0ifV0sInRleHQiOiJIaXZlcyJ9XX1dLCJyZWNvcmRlZERhdGUiOiIyMDEyLTA5LTE3IiwicmVzb3VyY2VUeXBlIjoiQWxsZXJneUludG9sZXJhbmNlIiwidGV4dCI6eyJkaXYiOiI8ZGl2IHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiPlNlbnNpdGl2aXR5IHRvIERveHljeWNsaW5lIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIEhpdmVzPC9kaXY-Iiwic3RhdHVzIjoiZ2VuZXJhdGVkIn0sInR5cGUiOiJhbGxlcmd5IiwidmVyaWZpY2F0aW9uU3RhdHVzIjp7ImNvZGluZyI6W3siY29kZSI6ImNvbmZpcm1lZCIsImRpc3BsYXkiOiJDb25maXJtZWQiLCJzeXN0ZW0iOiJodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2FsbGVyZ3lpbnRvbGVyYW5jZS12ZXJpZmljYXRpb24ifV19fX1dLCJpZGVudGlmaWVyIjp7InN5c3RlbSI6InVybjppZXRmOnJmYzozOTg2IiwidmFsdWUiOiJ1cm46dXVpZDowYzMxNTFiZC0xY2JmLTRkNjQtYjA0ZC1jZDkxODdhNGM2ZTAifSwicmVzb3VyY2VUeXBlIjoiQnVuZGxlIiwidGltZXN0YW1wIjoiMjAxMy0wNS0yOFQyMjoxMjoyMVoiLCJ0eXBlIjoiZG9jdW1lbnQifQ'" ] }, "execution_count": 218, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from base64 import urlsafe_b64encode\n", "recd_b64_canonical_bundle = urlsafe_b64encode(canonical_bundle).decode()\n", "recd_b64_canonical_bundle = recd_b64_canonical_bundle.replace(\"=\",\"\") #remove padding since decode package doesn't use them \n", "recd_b64_canonical_bundle" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4. Get the base64 encoded JWS from the `Bundle.signature.data` element" ] }, { "cell_type": "code", "execution_count": 219, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXQwZVNJNklsSlRJaXdpZEhsd0lqb2lTbGRVSWl3aWRYTmxJam9pYzJsbklpd2llRFZqSWpwYklrMUpTVVV6ZWtORFFUQmxaMEYzU1VKQlowbEtRVTlMUmxsMlRYZFNLM2xSVFVFd1IwTlRjVWRUU1dJelJGRkZRa04zVlVGTlNVZE9UVkZ6ZDBOUldVUldVVkZIUlhkS1ZsVjZSVlJOUWtWSFFURlZSVU5CZDB0Uk1rWnpZVmRhZG1OdE5YQlpWRVZUVFVKQlIwRXhWVVZDZDNkS1ZUSkdNV015Um5OaFdGSjJUVkpWZDBWM1dVUldVVkZMUkVGNFNWcFhSbk5rUjJoc1VrZEdNRmxVUlhoR2VrRldRbWRPVmtKQlRVMUVhMVo1WVZkTloxTkhSbWhqZVhkblVrWmFUazFUVlhkSmQxbEtTMjlhU1doMlkwNUJVV3RDUm1oYWJHRkhSbWhqTUVKdldsZEdjMlJIYUd4YVIwWXdXVlJGZFdJelNtNU5RalJZUkZSSmVFMVVRWGxPZWtVelRrUkpkMDVHYjFoRVZFbDVUVlJCZVUxcVJUTk9SRWwzVGtadmQyZFpNSGhEZWtGS1FtZE9Wa0pCV1ZSQmJGWlVUVkpOZDBWUldVUldVVkZKUkVGd1JGbFhlSEJhYlRsNVltMXNhRTFTU1hkRlFWbEVWbEZSU0VSQmJGUlpXRlo2V1ZkNGNHUkhPSGhHVkVGVVFtZE9Wa0pCYjAxRVJXaHNXVmQ0TUdGSFZrVlpXRkpvVFZSRldFMUNWVWRCTVZWRlFYZDNUMUpZU25CWmVVSkpXVmRHZWt4RFFrVldhekI0U2xSQmFrSm5hM0ZvYTJsSE9YY3dRa05SUlZkR2JWWnZXVmRHZWxGSGFHeFpWM2d3WVVkV2ExbFlVbWhOVXpWMlkyMWpkMmRuUjJsTlFUQkhRMU54UjFOSllqTkVVVVZDUVZGVlFVRTBTVUpxZDBGM1oyZEhTMEZ2U1VKblVVUndTMk5UYTI5QlRUWnpWekl4SzNaWFZHVkpWazlIZURFd1RWZGhjMUY1TjFaSWFXUTJlbmx4V0VGQ1RTdDZibVpDYmxobGJubFZNR294UmxSMlVHMVNaazlFYjA5RVdGWjFVRlYzUkc5dGFFTklhQ3RpWTJ4WE9VdE5NbTgxTmpOamVGSkxSWFpDYm1GSWNuTnFkelY1VG0xNFR6Vlpha1ZTWW1oMFNHUlJaWEZyZEdSM00xWlpSVkpTT1VodmVFeFBNMFpyYzNwU01qa3lTRlJDTkhoWE0zbFhiRll6WjFSclRWRnZlbEJUWTBwTFNETmlSemhRY1hFMlFWbFFTamRETkZsQ1NXeFZVMlJDVFZac00zRnVaVVZtWnpkbWRYaHBSbVpZYjJaa1ZGWnROM0pOYVdsSE4xZzVlalF6VUdacGJIRmhaV2x6Wm0xMFVuaEJiRkozUlU1WWNrZ3pUM1pQUkZCNVREQnlWRzVIT0VOellrRllXVlpKVFcxa1pFaGxORnBHT1hCc2FEazFjMm8wY0UxVWFFeDBZMHBZTDI4NVdFaE1hbWczUlcxYWVXZEtTRmRGVVhFMFVIZEdkMXBrYldKalptaERiVTl5T0RoSU9FSmlWWEoxTHpkV05ucGljMGN4VGpGRFYyeHVaR3hpVm5wdVRDc3pTVTFQY2pocldHRklZMkZ1Y1daamEyZEdWalJGY201bWFrWktjVEZQU1dGQmJYTk5hamcxZUUxcmFubFlUSGxqVEV3dmRUVnVNbTgyUW1jNU15OVZVbVp4ZFU5dlUwbEhUME5TTWpWRVlWcDZjSGN5YXpOek4yOUZPV1JOZDBWWFdIUm1XR2RaZEdneVlteHFlVFYwUmtnd1IycHdUMnQ0TURkcU4xcFVOVWh1ZUc1c2MwTkJkMFZCUVdGT1FVMUVOSGRFUVZsRVZsSXdWRUpCVlhkQmQwVkNMM3BCVEVKblRsWklVVGhGUWtGTlEwSmxRWGRKVVZsRVZsSXdVa0pDYjNkSFNVbFhaRE5rTTB4dGFHeFpWM2d3WVVkV2ExbFlVbWhoVnpWcVRHMU9kbUpVUVU1Q1oydHhhR3RwUnpsM01FSkJVWE5HUVVGUFEwRlpSVUZEZFUxVlRuRTVZWGtySzJVMVdVTTNVVVpQT1RSeVpucDRSMUZ1UmpOSGEyeGFUa0ZZYlVseU4xQldSMlJwUjFreVIxUjRMemxTZEVoRGQxUkxlbXRNSzNsMlMyOXFaVm81WkZaTE9IZHlSMVpwVW10UEwycFZlVm9yUzJOWFVtOXJWV3B6TlRsdVkwcEhVazFUVTFKNGRHVkRVWFZxZERSb1pqSXJMM0ZXSzJZeWMwMVJkRVZ5ZDFCRk16QjJZbkZTV1ZWT1RrNUNWa1ZSY0dGUmVDOWhZMHBFVlhZNWRqZHpha2hwU2tSeFdIZFJLM0o2YWprMWFVaEJTV0ZsUlVoeFJpOU5jekl5Y0RKaVpWcDFjWFpKVVV0bFRXd3JjM1pXY1VoMGFYVjZWMjVHTkZVMlZrbHRjR3R5TkdKSWJEZGxaMVk1U0Rac05sUXlVMDFyYWpaeFJGVTFaVGxPWnpCYWJFeFVkRzl6YzJoQ1RHMXZjRVkzWlRkSWVYSlVSVUZ0Wms5UVMxRmxNRVZuT1VVeWRYSjZlSEZDZFVjMU5HczFNRWN5U2pCR2FWQnpVVXBCYUVacFRrZDNVMmMwVXpOSWVWWkVSemQxWlV0a01FdzVNM2RMVDA1UFdVZDJUVXRwZWtOSVFpdHdTM1pGVFVwdldqaDVPWFZwUWl0SVJsaGpjRGxTWVVweFNqazNTSEJhVkVWMksyeHBRM0F5VUZOWWVtTkxNSEl5TlZOamVXcEdObVJNYjNWTE1sTkNNekI0UVhaS09IUkZOVGcwSzJweFVUWkRSMlZqVlRsWWFuWnNRV3AxU21SRGNrUmxWbEJ6YW10dU4wOVFXRWNyT0ZoYVZUZDZjVWhhVG0xWVdERlpXVFJJTlhKblJVbzBPR3h5VlhKUU0wazRVaUpkZlEuLmQ0MjByMFk1cGktLU9rSW1DaWhselA0XzhQd1BaaUVRcjRQeTJyZER0QXdubF9OYUU1SDFucXp2bm1qU00zSkhuaEhRakhzeDBZOWxjWEhpc2ZUbUp5QmlNYmhIQ28ycGRHeUx6RTZrbTdNYlktSTYyOXlLRy1ENXNLaFFldklYblRlZ1dHN3h6WTNDQjlHUTMzSUFEcU1EZkctdkg3N21nR2xjQk05WFRJX1liRzZGZUZqd0Z3TGcyenYxM0JWNzI3d3U2RWpDNnhPSHRiQ3NuS1NxUnZheFNZWVIwWWgyNG9jZmJuaVFiWHhEVlNndFFwNWlWUjdQUkdvX29JNEFscHozQVBUcmNaYUVNdXI5VWhoNm81MEZYbkUzZTlpMkM5TThwTkhyY3d4SjdWV2d1UGJ3UGN0dFd0ZG9RYXBKRWQwZnR1WEVwWnhzZ2t3aWgzSGZQQXQ3Vm84a1ZsUkRIM0lrQ0FBNVg2cUtlYzFIU2hYRFp1QklqMFNWVUJHSDFsMlRPb0VCd29nWGhlTDkwbHVqejRBUnpabHdfSzNrQk1tUk10dHVucDdjLWpZYmdubVRpcE1MQW4weWhSOUFsSmdUMVV4Z2FpTE5adTJtekZuMHZSTkU2OU95cm5Rc0Z3THhWQlhCcUJ2NzRyWmNPbGQ5OVJydENEVEdHemlR'" ] }, "execution_count": 219, "metadata": {}, "output_type": "execute_result" } ], "source": [ "recd_b64_jws = recd_signature['data']\n", "recd_b64_jws" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5. Base64 decode the encoded JWS\n", "\n", "note the signature is displayed with the parts labeled and separated with line breaks for easier viewing" ] }, { "cell_type": "code", "execution_count": 220, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "header:\n", "eyJhbGciOiJSUzI1NiIsImt0eSI6IlJTIiwidHlwIjoiSldUIiwidXNlIjoic2lnIiwieDVjIjpbIk1JSUUzekNDQTBlZ0F3SUJBZ0lKQU9LRll2TXdSK3lRTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdOTVFzd0NRWURWUVFHRXdKVlV6RVRNQkVHQTFVRUNBd0tRMkZzYVdadmNtNXBZVEVTTUJBR0ExVUVCd3dKVTJGMWMyRnNhWFJ2TVJVd0V3WURWUVFLREF4SVpXRnNkR2hsUkdGMFlURXhGekFWQmdOVkJBTU1Ea1Z5YVdNZ1NHRmhjeXdnUkZaTk1TVXdJd1lKS29aSWh2Y05BUWtCRmhabGFHRmhjMEJvWldGc2RHaGxaR0YwWVRFdWIzSm5NQjRYRFRJeE1UQXlOekUzTkRJd05Gb1hEVEl5TVRBeU1qRTNOREl3TkZvd2dZMHhDekFKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SSXdFQVlEVlFRSERBbFRZWFZ6WVd4cGRHOHhGVEFUQmdOVkJBb01ERWhsWVd4MGFHVkVZWFJoTVRFWE1CVUdBMVVFQXd3T1JYSnBZeUJJWVdGekxDQkVWazB4SlRBakJna3Foa2lHOXcwQkNRRVdGbVZvWVdGelFHaGxZV3gwYUdWa1lYUmhNUzV2Y21jd2dnR2lNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJqd0F3Z2dHS0FvSUJnUURwS2NTa29BTTZzVzIxK3ZXVGVJVk9HeDEwTVdhc1F5N1ZIaWQ2enlxWEFCTSt6bmZCblhlbnlVMGoxRlR2UG1SZk9Eb09EWFZ1UFV3RG9taENIaCtiY2xXOUtNMm81NjNjeFJLRXZCbmFIcnNqdzV5Tm14TzVZakVSYmh0SGRRZXFrdGR3M1ZZRVJSOUhveExPM0Zrc3pSMjkySFRCNHhXM3lXbFYzZ1RrTVFvelBTY0pLSDNiRzhQcXE2QVlQSjdDNFlCSWxVU2RCTVZsM3FuZUVmZzdmdXhpRmZYb2ZkVFZtN3JNaWlHN1g5ejQzUGZpbHFhZWlzZm10UnhBbFJ3RU5YckgzT3ZPRFB5TDByVG5HOENzYkFYWVZJTW1kZEhlNFpGOXBsaDk1c2o0cE1UaEx0Y0pYL285WEhMamg3RW1aeWdKSFdFUXE0UHdGd1pkbWJjZmhDbU9yODhIOEJiVXJ1LzdWNnpic0cxTjFDV2xuZGxiVnpuTCszSU1PcjhrWGFIY2FucWZja2dGVjRFcm5makZKcTFPSWFBbXNNajg1eE1ranlYTHljTEwvdTVuMm82Qmc5My9VUmZxdU9vU0lHT0NSMjVEYVp6cHcyazNzN29FOWRNd0VXWHRmWGdZdGgyYmxqeTV0RkgwR2pwT2t4MDdqN1pUNUhueG5sc0NBd0VBQWFOQU1ENHdEQVlEVlIwVEJBVXdBd0VCL3pBTEJnTlZIUThFQkFNQ0JlQXdJUVlEVlIwUkJCb3dHSUlXZDNkM0xtaGxZV3gwYUdWa1lYUmhhVzVqTG1OdmJUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FZRUFDdU1VTnE5YXkrK2U1WUM3UUZPOTRyZnp4R1FuRjNHa2xaTkFYbUlyN1BWR2RpR1kyR1R4LzlSdEhDd1RLemtMK3l2S29qZVo5ZFZLOHdyR1ZpUmtPL2pVeVorS2NXUm9rVWpzNTluY0pHUk1TU1J4dGVDUXVqdDRoZjIrL3FWK2Yyc01RdEVyd1BFMzB2YnFSWVVOTk5CVkVRcGFReC9hY0pEVXY5djdzakhpSkRxWHdRK3J6ajk1aUhBSWFlRUhxRi9NczIycDJiZVp1cXZJUUtlTWwrc3ZWcUh0aXV6V25GNFU2VkltcGtyNGJIbDdlZ1Y5SDZsNlQyU01rajZxRFU1ZTlOZzBabExUdG9zc2hCTG1vcEY3ZTdIeXJURUFtZk9QS1FlMEVnOUUydXJ6eHFCdUc1NGs1MEcySjBGaVBzUUpBaEZpTkd3U2c0UzNIeVZERzd1ZUtkMEw5M3dLT05PWUd2TUtpekNIQitwS3ZFTUpvWjh5OXVpQitIRlhjcDlSYUpxSjk3SHBaVEV2K2xpQ3AyUFNYemNLMHIyNVNjeWpGNmRMb3VLMlNCMzB4QXZKOHRFNTg0K2pxUTZDR2VjVTlYanZsQWp1SmRDckRlVlBzamtuN09QWEcrOFhaVTd6cUhaTm1YWDFZWTRINXJnRUo0OGxyVXJQM0k4UiJdfQ\n", "\n", "payload:\n", "\n", "\n", "signature:\n", "d420r0Y5pi--OkImCihlzP4_8PwPZiEQr4Py2rdDtAwnl_NaE5H1nqzvnmjSM3JHnhHQjHsx0Y9lcXHisfTmJyBiMbhHCo2pdGyLzE6km7MbY-I629yKG-D5sKhQevIXnTegWG7xzY3CB9GQ33IADqMDfG-vH77mgGlcBM9XTI_YbG6FeFjwFwLg2zv13BV727wu6EjC6xOHtbCsnKSqRvaxSYYR0Yh24ocfbniQbXxDVSgtQp5iVR7PRGo_oI4Alpz3APTrcZaEMur9Uhh6o50FXnE3e9i2C9M8pNHrcwxJ7VWguPbwPcttWtdoQapJEd0ftuXEpZxsgkwih3HfPAt7Vo8kVlRDH3IkCAA5X6qKec1HShXDZuBIj0SVUBGH1l2TOoEBwogXheL90lujz4ARzZlw_K3kBMmRMttunp7c-jYbgnmTipMLAn0yhR9AlJgT1UxgaiLNZu2mzFn0vRNE69OyrnQsFwLxVBXBqBv74rZcOld99RrtCDTGGziQ\n", "\n" ] } ], "source": [ "labels = ['header', 'payload', 'signature']\n", "from base64 import b64decode\n", "recd_jws = b64decode(recd_b64_jws.encode()).decode()\n", "for i,j in enumerate(recd_jws.split('.')):\n", " print(f'{labels[i]}:')\n", " print(f'{j}')\n", " print()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 6. reattach the payload - the base64 encoded Bundle - into the JWS payload element. \n", "\n", "note the signature is displayed with the parts labeled and separated with line breaks for easier viewing" ] }, { "cell_type": "code", "execution_count": 221, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "header:\n", "eyJhbGciOiJSUzI1NiIsImt0eSI6IlJTIiwidHlwIjoiSldUIiwidXNlIjoic2lnIiwieDVjIjpbIk1JSUUzekNDQTBlZ0F3SUJBZ0lKQU9LRll2TXdSK3lRTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdOTVFzd0NRWURWUVFHRXdKVlV6RVRNQkVHQTFVRUNBd0tRMkZzYVdadmNtNXBZVEVTTUJBR0ExVUVCd3dKVTJGMWMyRnNhWFJ2TVJVd0V3WURWUVFLREF4SVpXRnNkR2hsUkdGMFlURXhGekFWQmdOVkJBTU1Ea1Z5YVdNZ1NHRmhjeXdnUkZaTk1TVXdJd1lKS29aSWh2Y05BUWtCRmhabGFHRmhjMEJvWldGc2RHaGxaR0YwWVRFdWIzSm5NQjRYRFRJeE1UQXlOekUzTkRJd05Gb1hEVEl5TVRBeU1qRTNOREl3TkZvd2dZMHhDekFKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SSXdFQVlEVlFRSERBbFRZWFZ6WVd4cGRHOHhGVEFUQmdOVkJBb01ERWhsWVd4MGFHVkVZWFJoTVRFWE1CVUdBMVVFQXd3T1JYSnBZeUJJWVdGekxDQkVWazB4SlRBakJna3Foa2lHOXcwQkNRRVdGbVZvWVdGelFHaGxZV3gwYUdWa1lYUmhNUzV2Y21jd2dnR2lNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJqd0F3Z2dHS0FvSUJnUURwS2NTa29BTTZzVzIxK3ZXVGVJVk9HeDEwTVdhc1F5N1ZIaWQ2enlxWEFCTSt6bmZCblhlbnlVMGoxRlR2UG1SZk9Eb09EWFZ1UFV3RG9taENIaCtiY2xXOUtNMm81NjNjeFJLRXZCbmFIcnNqdzV5Tm14TzVZakVSYmh0SGRRZXFrdGR3M1ZZRVJSOUhveExPM0Zrc3pSMjkySFRCNHhXM3lXbFYzZ1RrTVFvelBTY0pLSDNiRzhQcXE2QVlQSjdDNFlCSWxVU2RCTVZsM3FuZUVmZzdmdXhpRmZYb2ZkVFZtN3JNaWlHN1g5ejQzUGZpbHFhZWlzZm10UnhBbFJ3RU5YckgzT3ZPRFB5TDByVG5HOENzYkFYWVZJTW1kZEhlNFpGOXBsaDk1c2o0cE1UaEx0Y0pYL285WEhMamg3RW1aeWdKSFdFUXE0UHdGd1pkbWJjZmhDbU9yODhIOEJiVXJ1LzdWNnpic0cxTjFDV2xuZGxiVnpuTCszSU1PcjhrWGFIY2FucWZja2dGVjRFcm5makZKcTFPSWFBbXNNajg1eE1ranlYTHljTEwvdTVuMm82Qmc5My9VUmZxdU9vU0lHT0NSMjVEYVp6cHcyazNzN29FOWRNd0VXWHRmWGdZdGgyYmxqeTV0RkgwR2pwT2t4MDdqN1pUNUhueG5sc0NBd0VBQWFOQU1ENHdEQVlEVlIwVEJBVXdBd0VCL3pBTEJnTlZIUThFQkFNQ0JlQXdJUVlEVlIwUkJCb3dHSUlXZDNkM0xtaGxZV3gwYUdWa1lYUmhhVzVqTG1OdmJUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FZRUFDdU1VTnE5YXkrK2U1WUM3UUZPOTRyZnp4R1FuRjNHa2xaTkFYbUlyN1BWR2RpR1kyR1R4LzlSdEhDd1RLemtMK3l2S29qZVo5ZFZLOHdyR1ZpUmtPL2pVeVorS2NXUm9rVWpzNTluY0pHUk1TU1J4dGVDUXVqdDRoZjIrL3FWK2Yyc01RdEVyd1BFMzB2YnFSWVVOTk5CVkVRcGFReC9hY0pEVXY5djdzakhpSkRxWHdRK3J6ajk1aUhBSWFlRUhxRi9NczIycDJiZVp1cXZJUUtlTWwrc3ZWcUh0aXV6V25GNFU2VkltcGtyNGJIbDdlZ1Y5SDZsNlQyU01rajZxRFU1ZTlOZzBabExUdG9zc2hCTG1vcEY3ZTdIeXJURUFtZk9QS1FlMEVnOUUydXJ6eHFCdUc1NGs1MEcySjBGaVBzUUpBaEZpTkd3U2c0UzNIeVZERzd1ZUtkMEw5M3dLT05PWUd2TUtpekNIQitwS3ZFTUpvWjh5OXVpQitIRlhjcDlSYUpxSjk3SHBaVEV2K2xpQ3AyUFNYemNLMHIyNVNjeWpGNmRMb3VLMlNCMzB4QXZKOHRFNTg0K2pxUTZDR2VjVTlYanZsQWp1SmRDckRlVlBzamtuN09QWEcrOFhaVTd6cUhaTm1YWDFZWTRINXJnRUo0OGxyVXJQM0k4UiJdfQ\n", "\n", "payload:\n", "eyJlbnRyeSI6W3siZnVsbFVybCI6Imh0dHA6Ly9maGlyLmhlYWx0aGludGVyc2VjdGlvbnMuY29tLmF1L29wZW4vQ29tcG9zaXRpb24vMTgwZjIxOWYtOTdhOC00ODZkLTk5ZDktZWQ2MzFmZTRmYzU3IiwicmVzb3VyY2UiOnsiYXV0aG9yIjpbeyJkaXNwbGF5IjoiRG9jdG9yIERhdmUiLCJyZWZlcmVuY2UiOiJQcmFjdGl0aW9uZXIvZXhhbXBsZSJ9XSwiY29uZmlkZW50aWFsaXR5IjoiTiIsImRhdGUiOiIyMDEzLTAyLTAxVDEyOjMwOjAyWiIsImVuY291bnRlciI6eyJyZWZlcmVuY2UiOiJodHRwOi8vZmhpci5oZWFsdGhpbnRlcnNlY3Rpb25zLmNvbS5hdS9vcGVuL0VuY291bnRlci9kb2MtZXhhbXBsZSJ9LCJpZCI6IjE4MGYyMTlmLTk3YTgtNDg2ZC05OWQ5LWVkNjMxZmU0ZmM1NyIsIm1ldGEiOnsibGFzdFVwZGF0ZWQiOiIyMDEzLTA1LTI4VDIyOjEyOjIxWiJ9LCJyZXNvdXJjZVR5cGUiOiJDb21wb3NpdGlvbiIsInNlY3Rpb24iOlt7ImNvZGUiOnsiY29kaW5nIjpbeyJjb2RlIjoiMjkyOTktNSIsImRpc3BsYXkiOiJSZWFzb24gZm9yIHZpc2l0IE5hcnJhdGl2ZSIsInN5c3RlbSI6Imh0dHA6Ly9sb2luYy5vcmcifV19LCJlbnRyeSI6W3sicmVmZXJlbmNlIjoidXJuOnV1aWQ6NTQxYTcyYTgtZGY3NS00NDg0LWFjODktYWM0OTIzZjAzYjgxIn1dLCJ0ZXh0Ijp7ImRpdiI6IjxkaXYgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI-XG5cbiAgICAgICAgICAgICAgPHRhYmxlPlxuXG4gICAgICAgICAgICAgICAgPHRoZWFkPlxuXG4gICAgICAgICAgICAgICAgICA8dHI-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPkRldGFpbHM8L3RkPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ZC8-XG5cbiAgICAgICAgICAgICAgICAgIDwvdHI-XG5cbiAgICAgICAgICAgICAgICA8L3RoZWFkPlxuXG4gICAgICAgICAgICAgICAgPHRib2R5PlxuXG4gICAgICAgICAgICAgICAgICA8dHI-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPkFjdXRlIEFzdGhtYXRpYyBhdHRhY2suIFdhcyB3aGVlemluZyBmb3IgZGF5cyBwcmlvciB0byBhZG1pc3Npb24uPC90ZD5cblxuICAgICAgICAgICAgICAgICAgICA8dGQvPlxuXG4gICAgICAgICAgICAgICAgICA8L3RyPlxuXG4gICAgICAgICAgICAgICAgPC90Ym9keT5cblxuICAgICAgICAgICAgICA8L3RhYmxlPlxuXG4gICAgICAgICAgICA8L2Rpdj4iLCJzdGF0dXMiOiJhZGRpdGlvbmFsIn0sInRpdGxlIjoiUmVhc29uIGZvciBhZG1pc3Npb24ifSx7ImNvZGUiOnsiY29kaW5nIjpbeyJjb2RlIjoiMTAxODMtMiIsImRpc3BsYXkiOiJIb3NwaXRhbCBkaXNjaGFyZ2UgbWVkaWNhdGlvbnMgTmFycmF0aXZlIiwic3lzdGVtIjoiaHR0cDovL2xvaW5jLm9yZyJ9XX0sImVudHJ5IjpbeyJyZWZlcmVuY2UiOiJ1cm46dXVpZDoxMjRhNjkxNi01ZDg0LTRiOGMtYjI1MC0xMGNlZmI4ZTZlODYifSx7InJlZmVyZW5jZSI6InVybjp1dWlkOjY3M2Y4ZGI1LTBmZmQtNDM5NS05NjU3LTZkYTAwNDIwYmJjMSJ9XSwibW9kZSI6IndvcmtpbmciLCJ0ZXh0Ijp7ImRpdiI6IjxkaXYgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI-XG5cbiAgICAgICAgICAgICAgPHRhYmxlPlxuXG4gICAgICAgICAgICAgICAgPHRoZWFkPlxuXG4gICAgICAgICAgICAgICAgICA8dHI-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPk1lZGljYXRpb248L3RkPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ZD5MYXN0IENoYW5nZTwvdGQ-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPkxhc3QgQ2hhbmdlUmVhc29uPC90ZD5cblxuICAgICAgICAgICAgICAgICAgPC90cj5cblxuICAgICAgICAgICAgICAgIDwvdGhlYWQ-XG5cbiAgICAgICAgICAgICAgICA8dGJvZHk-XG5cbiAgICAgICAgICAgICAgICAgIDx0cj5cblxuICAgICAgICAgICAgICAgICAgICA8dGQ-VGhlb3BoeWxsaW5lIDIwMG1nIEJEIGFmdGVyIG1lYWxzPC90ZD5cblxuICAgICAgICAgICAgICAgICAgICA8dGQ-Y29udGludWVkPC90ZD5cblxuICAgICAgICAgICAgICAgICAgPC90cj5cblxuICAgICAgICAgICAgICAgICAgPHRyPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ZD5WZW50b2xpbiBJbmhhbGVyPC90ZD5cblxuICAgICAgICAgICAgICAgICAgICA8dGQ-c3RvcHBlZDwvdGQ-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPkdldHRpbmcgc2lkZSBlZmZlY3Qgb2YgdHJlbW9yPC90ZD5cblxuICAgICAgICAgICAgICAgICAgPC90cj5cblxuICAgICAgICAgICAgICAgIDwvdGJvZHk-XG5cbiAgICAgICAgICAgICAgPC90YWJsZT5cblxuICAgICAgICAgICAgPC9kaXY-Iiwic3RhdHVzIjoiYWRkaXRpb25hbCJ9LCJ0aXRsZSI6Ik1lZGljYXRpb25zIG9uIERpc2NoYXJnZSJ9LHsiY29kZSI6eyJjb2RpbmciOlt7ImNvZGUiOiI0ODc2NS0yIiwiZGlzcGxheSI6IkFsbGVyZ2llcyBhbmQgYWR2ZXJzZSByZWFjdGlvbnMgRG9jdW1lbnQiLCJzeXN0ZW0iOiJodHRwOi8vbG9pbmMub3JnIn1dfSwiZW50cnkiOlt7InJlZmVyZW5jZSI6InVybjp1dWlkOjQ3NjAwZTBmLWI2YjUtNDMwOC04NGI1LTVkZWMxNTdmNzYzNyJ9XSwidGV4dCI6eyJkaXYiOiI8ZGl2IHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiPlxuXG4gICAgICAgICAgICAgIDx0YWJsZT5cblxuICAgICAgICAgICAgICAgIDx0aGVhZD5cblxuICAgICAgICAgICAgICAgICAgPHRyPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ZD5BbGxlcmdlbjwvdGQ-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPlJlYWN0aW9uPC90ZD5cblxuICAgICAgICAgICAgICAgICAgPC90cj5cblxuICAgICAgICAgICAgICAgIDwvdGhlYWQ-XG5cbiAgICAgICAgICAgICAgICA8dGJvZHk-XG5cbiAgICAgICAgICAgICAgICAgIDx0cj5cblxuICAgICAgICAgICAgICAgICAgICA8dGQ-RG94eWN5Y2xpbmU8L3RkPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ZD5IaXZlczwvdGQ-XG5cbiAgICAgICAgICAgICAgICAgIDwvdHI-XG5cbiAgICAgICAgICAgICAgICA8L3Rib2R5PlxuXG4gICAgICAgICAgICAgIDwvdGFibGU-XG5cbiAgICAgICAgICAgIDwvZGl2PiIsInN0YXR1cyI6ImFkZGl0aW9uYWwifSwidGl0bGUiOiJLbm93biBhbGxlcmdpZXMifV0sInN0YXR1cyI6ImZpbmFsIiwic3ViamVjdCI6eyJkaXNwbGF5IjoiRXZlIEV2ZXJ5d29tYW4iLCJyZWZlcmVuY2UiOiJodHRwOi8vZmhpci5oZWFsdGhpbnRlcnNlY3Rpb25zLmNvbS5hdS9vcGVuL1BhdGllbnQvZDEifSwidGV4dCI6eyJkaXYiOiI8ZGl2IHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiPjxwPjxiPkdlbmVyYXRlZCBOYXJyYXRpdmUgd2l0aCBEZXRhaWxzPC9iPjwvcD48cD48Yj5pZDwvYj46IDE4MGYyMTlmLTk3YTgtNDg2ZC05OWQ5LWVkNjMxZmU0ZmM1NzwvcD48cD48Yj5tZXRhPC9iPjogPC9wPjxwPjxiPnN0YXR1czwvYj46IGZpbmFsPC9wPjxwPjxiPnR5cGU8L2I-OiBEaXNjaGFyZ2UgU3VtbWFyeSBmcm9tIFJlc3BvbnNpYmxlIENsaW5pY2lhbiA8c3Bhbj4oRGV0YWlscyA6IHtMT0lOQyBjb2RlICcyODY1NS05JyA9ICdQaHlzaWNpYW4gYXR0ZW5kaW5nIERpc2NoYXJnZSBzdW1tYXJ5KTwvc3Bhbj48L3A-PHA-PGI-ZW5jb3VudGVyPC9iPjogPGE-aHR0cDovL2ZoaXIuaGVhbHRoaW50ZXJzZWN0aW9ucy5jb20uYXUvb3Blbi9FbmNvdW50ZXIvZG9jLWV4YW1wbGU8L2E-PC9wPjxwPjxiPmRhdGU8L2I-OiAwMS8wMi8yMDEzIDEyOjMwOjAyIFBNPC9wPjxwPjxiPmF1dGhvcjwvYj46IDxhPkRvY3RvciBEYXZlPC9hPjwvcD48cD48Yj50aXRsZTwvYj46IERpc2NoYXJnZSBTdW1tYXJ5PC9wPjxwPjxiPmNvbmZpZGVudGlhbGl0eTwvYj46IE48L3A-PC9kaXY-Iiwic3RhdHVzIjoiZ2VuZXJhdGVkIn0sInRpdGxlIjoiRGlzY2hhcmdlIFN1bW1hcnkiLCJ0eXBlIjp7ImNvZGluZyI6W3siY29kZSI6IjI4NjU1LTkiLCJzeXN0ZW0iOiJodHRwOi8vbG9pbmMub3JnIn1dLCJ0ZXh0IjoiRGlzY2hhcmdlIFN1bW1hcnkgZnJvbSBSZXNwb25zaWJsZSBDbGluaWNpYW4ifX19LHsiZnVsbFVybCI6Imh0dHA6Ly9maGlyLmhlYWx0aGludGVyc2VjdGlvbnMuY29tLmF1L29wZW4vUHJhY3RpdGlvbmVyL2V4YW1wbGUiLCJyZXNvdXJjZSI6eyJpZCI6ImV4YW1wbGUiLCJpZGVudGlmaWVyIjpbeyJzeXN0ZW0iOiJodHRwOi8vd3d3LmFjbWUub3JnL3ByYWN0aXRpb25lcnMiLCJ2YWx1ZSI6IjIzIn1dLCJtZXRhIjp7Imxhc3RVcGRhdGVkIjoiMjAxMy0wNS0wNVQxNjoxMzowM1oifSwibmFtZSI6W3siZmFtaWx5IjoiQ2FyZWZ1bCIsImdpdmVuIjpbIkFkYW0iXSwicHJlZml4IjpbIkRyIl19XSwicmVzb3VyY2VUeXBlIjoiUHJhY3RpdGlvbmVyIiwidGV4dCI6eyJkaXYiOiI8ZGl2IHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiPlxuXG4gICAgICAgICAgICA8cD5EciBBZGFtIENhcmVmdWw8L3A-XG5cbiAgICAgICAgICA8L2Rpdj4iLCJzdGF0dXMiOiJnZW5lcmF0ZWQifX19LHsiZnVsbFVybCI6Imh0dHA6Ly9maGlyLmhlYWx0aGludGVyc2VjdGlvbnMuY29tLmF1L29wZW4vUGF0aWVudC9kMSIsInJlc291cmNlIjp7ImFjdGl2ZSI6dHJ1ZSwiYWRkcmVzcyI6W3sibGluZSI6WyIyMjIyIEhvbWUgU3RyZWV0Il0sInVzZSI6ImhvbWUifV0sImJpcnRoRGF0ZSI6IjE5NTUtMDEtMDYiLCJnZW5kZXIiOiJmZW1hbGUiLCJpZCI6ImQxIiwibmFtZSI6W3siZmFtaWx5IjoiRXZlcnl3b21hbjEiLCJnaXZlbiI6WyJFdmUiXSwidGV4dCI6IkV2ZSBFdmVyeXdvbWFuIn1dLCJyZXNvdXJjZVR5cGUiOiJQYXRpZW50IiwidGVsZWNvbSI6W3sic3lzdGVtIjoicGhvbmUiLCJ1c2UiOiJ3b3JrIiwidmFsdWUiOiI1NTUtNTU1LTIwMDMifV0sInRleHQiOnsiZGl2IjoiPGRpdiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIj5cblxuICAgICAgICAgICAgPGgxPkV2ZSBFdmVyeXdvbWFuPC9oMT5cblxuICAgICAgICAgIDwvZGl2PiIsInN0YXR1cyI6ImdlbmVyYXRlZCJ9fX0seyJmdWxsVXJsIjoiaHR0cDovL2ZoaXIuaGVhbHRoaW50ZXJzZWN0aW9ucy5jb20uYXUvb3Blbi9FbmNvdW50ZXIvZG9jLWV4YW1wbGUiLCJyZXNvdXJjZSI6eyJjbGFzcyI6eyJjb2RlIjoiSU1QIiwiZGlzcGxheSI6ImlucGF0aWVudCBlbmNvdW50ZXIiLCJzeXN0ZW0iOiJodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL3YzLUFjdENvZGUifSwiaG9zcGl0YWxpemF0aW9uIjp7ImRpc2NoYXJnZURpc3Bvc2l0aW9uIjp7InRleHQiOiJEaXNjaGFyZ2VkIHRvIGNhcmUgb2YgR1AifX0sImlkIjoiZG9jLWV4YW1wbGUiLCJpZGVudGlmaWVyIjpbeyJ2YWx1ZSI6IlMxMDAifV0sIm1ldGEiOnsibGFzdFVwZGF0ZWQiOiIyMDEzLTA1LTA1VDE2OjEzOjAzWiJ9LCJwZXJpb2QiOnsiZW5kIjoiMjAxMy0wMi0wMVQxMjozMDowMloiLCJzdGFydCI6IjIwMTMtMDEtMjBUMTI6MzA6MDJaIn0sInJlc291cmNlVHlwZSI6IkVuY291bnRlciIsInN0YXR1cyI6ImZpbmlzaGVkIiwic3ViamVjdCI6eyJyZWZlcmVuY2UiOiJQYXRpZW50L2QxIn0sInRleHQiOnsiZGl2IjoiPGRpdiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIj4gQWRtaXR0ZWQgdG8gT3J0aG9wZWRpY3MgU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIE1pZGRsZW1vcmUgSG9zcGl0YWwgYmV0d2VlbiBKYW4gMjAgYW5kIEZlYiBpc3QgMjAxMyA8L2Rpdj4iLCJzdGF0dXMiOiJnZW5lcmF0ZWQifSwidHlwZSI6W3sidGV4dCI6Ik9ydGhvcGVkaWMgQWRtaXNzaW9uIn1dfX0seyJmdWxsVXJsIjoidXJuOnV1aWQ6NTQxYTcyYTgtZGY3NS00NDg0LWFjODktYWM0OTIzZjAzYjgxIiwicmVzb3VyY2UiOnsiY29kZSI6eyJjb2RpbmciOlt7ImNvZGUiOiI0NjI0MS02Iiwic3lzdGVtIjoiaHR0cDovL2xvaW5jLm9yZyJ9XSwidGV4dCI6IlJlYXNvbiBmb3IgYWRtaXNzaW9uIn0sImVuY291bnRlciI6eyJyZWZlcmVuY2UiOiJodHRwOi8vZmhpci5oZWFsdGhpbnRlcnNlY3Rpb25zLmNvbS5hdS9vcGVuL0VuY291bnRlci9kb2MtZXhhbXBsZSJ9LCJtZXRhIjp7Imxhc3RVcGRhdGVkIjoiMjAxMy0wNS0wNVQxNjoxMzowM1oifSwicmVzb3VyY2VUeXBlIjoiT2JzZXJ2YXRpb24iLCJzdGF0dXMiOiJmaW5hbCIsInN1YmplY3QiOnsiZGlzcGxheSI6IkV2ZSBFdmVyeXdvbWFuIiwicmVmZXJlbmNlIjoiaHR0cDovL2ZoaXIuaGVhbHRoaW50ZXJzZWN0aW9ucy5jb20uYXUvb3Blbi9QYXRpZW50L2QxIn0sInRleHQiOnsiZGl2IjoiPGRpdiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIj4gQWN1dGUgQXN0aG1hdGljIGF0dGFjay4gV2FzIHdoZWV6aW5nXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgZGF5cyBwcmlvciB0byBhZG1pc3Npb24uIDwvZGl2PiIsInN0YXR1cyI6ImFkZGl0aW9uYWwifSwidmFsdWVTdHJpbmciOiJBY3V0ZSBBc3RobWF0aWMgYXR0YWNrLiBXYXMgd2hlZXppbmcgZm9yIGRheXMgcHJpb3IgdG8gYWRtaXNzaW9uLiJ9fSx7ImZ1bGxVcmwiOiJ1cm46dXVpZDoxMjRhNjkxNi01ZDg0LTRiOGMtYjI1MC0xMGNlZmI4ZTZlODYiLCJyZXNvdXJjZSI6eyJkb3NhZ2VJbnN0cnVjdGlvbiI6W3siYWRkaXRpb25hbEluc3RydWN0aW9uIjpbeyJ0ZXh0IjoiVGFrZSB3aXRoIEZvb2QifV0sImRvc2VBbmRSYXRlIjpbeyJkb3NlUXVhbnRpdHkiOnsiY29kZSI6InRibCIsInN5c3RlbSI6Imh0dHA6Ly91bml0c29mbWVhc3VyZS5vcmciLCJ1bml0IjoidGFibGV0IiwidmFsdWUiOjF9LCJ0eXBlIjp7ImNvZGluZyI6W3siY29kZSI6Im9yZGVyZWQiLCJkaXNwbGF5IjoiT3JkZXJlZCIsInN5c3RlbSI6Imh0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vZG9zZS1yYXRlLXR5cGUifV19fV0sInJvdXRlIjp7ImNvZGluZyI6W3siY29kZSI6IjM5NDg5OTAwMyIsImRpc3BsYXkiOiJvcmFsIGFkbWluaXN0cmF0aW9uIG9mIHRyZWF0bWVudCIsInN5c3RlbSI6Imh0dHA6Ly9zbm9tZWQuaW5mby9zY3QifV19LCJ0aW1pbmciOnsicmVwZWF0Ijp7ImZyZXF1ZW5jeSI6MiwicGVyaW9kIjoxLCJwZXJpb2RVbml0IjoiZCJ9fX1dLCJpbnRlbnQiOiJvcmRlciIsIm1lZGljYXRpb25Db2RlYWJsZUNvbmNlcHQiOnsiY29kaW5nIjpbeyJjb2RlIjoiNjY0OTMwMDMiLCJzeXN0ZW0iOiJodHRwOi8vc25vbWVkLmluZm8vc2N0In1dLCJ0ZXh0IjoiVGhlb3BoeWxsaW5lIDIwMG1nIn0sIm1ldGEiOnsibGFzdFVwZGF0ZWQiOiIyMDEzLTA1LTA1VDE2OjEzOjAzWiJ9LCJyZWFzb25Db2RlIjpbeyJ0ZXh0IjoiTWFuYWdlbWVudCBvZiBBc3RobWEifV0sInJlcXVlc3RlciI6eyJkaXNwbGF5IjoiUGV0ZXIgUHJhY3RpdGlvbmVyIiwicmVmZXJlbmNlIjoiUHJhY3RpdGlvbmVyL2V4YW1wbGUifSwicmVzb3VyY2VUeXBlIjoiTWVkaWNhdGlvblJlcXVlc3QiLCJzdGF0dXMiOiJ1bmtub3duIiwic3ViamVjdCI6eyJkaXNwbGF5IjoiUGV0ZXIgUGF0aWVudCIsInJlZmVyZW5jZSI6Imh0dHA6Ly9maGlyLmhlYWx0aGludGVyc2VjdGlvbnMuY29tLmF1L29wZW4vUGF0aWVudC9kMSJ9LCJ0ZXh0Ijp7ImRpdiI6IjxkaXYgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI-XG5cbiAgICAgICAgICAgIDxwPlRoZW9waHlsbGluZSAyMDBtZyB0d2ljZSBhIGRheTwvcD5cblxuICAgICAgICAgIDwvZGl2PiIsInN0YXR1cyI6ImdlbmVyYXRlZCJ9fX0seyJmdWxsVXJsIjoidXJuOnV1aWQ6NjczZjhkYjUtMGZmZC00Mzk1LTk2NTctNmRhMDA0MjBiYmMxIiwicmVzb3VyY2UiOnsiZGF0ZUFzc2VydGVkIjoiMjAxMy0wNS0wNVQxNjoxMzowM1oiLCJtZWRpY2F0aW9uQ29kZWFibGVDb25jZXB0Ijp7InRleHQiOiJWZW50b2xpbiBJbmhhbGVyIn0sInJlc291cmNlVHlwZSI6Ik1lZGljYXRpb25TdGF0ZW1lbnQiLCJzdGF0dXMiOiJhY3RpdmUiLCJzdGF0dXNSZWFzb24iOlt7InRleHQiOiJNYW5hZ2VtZW50IG9mIEFzdGhtYSJ9XSwic3ViamVjdCI6eyJkaXNwbGF5IjoiUGV0ZXIgUGF0aWVudCIsInJlZmVyZW5jZSI6Imh0dHA6Ly9maGlyLmhlYWx0aGludGVyc2VjdGlvbnMuY29tLmF1L29wZW4vUGF0aWVudC9kMSJ9LCJ0ZXh0Ijp7ImRpdiI6IjxkaXYgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI-XG5cbiAgICAgICAgICAgIDxwPlZlbnRvbGluIGluaGFsZXIgZGlzY29udGludWVkPC9wPlxuXG4gICAgICAgICAgPC9kaXY-Iiwic3RhdHVzIjoiZ2VuZXJhdGVkIn19fSx7ImZ1bGxVcmwiOiJ1cm46dXVpZDo0NzYwMGUwZi1iNmI1LTQzMDgtODRiNS01ZGVjMTU3Zjc2MzciLCJyZXNvdXJjZSI6eyJjbGluaWNhbFN0YXR1cyI6eyJjb2RpbmciOlt7ImNvZGUiOiJhY3RpdmUiLCJkaXNwbGF5IjoiQWN0aXZlIiwic3lzdGVtIjoiaHR0cDovL3Rlcm1pbm9sb2d5LmhsNy5vcmcvQ29kZVN5c3RlbS9hbGxlcmd5aW50b2xlcmFuY2UtY2xpbmljYWwifV19LCJjb2RlIjp7InRleHQiOiJEb3h5Y3ljbGluZSJ9LCJjcml0aWNhbGl0eSI6ImhpZ2giLCJtZXRhIjp7Imxhc3RVcGRhdGVkIjoiMjAxMy0wNS0wNVQxNjoxMzowM1oifSwicGF0aWVudCI6eyJkaXNwbGF5IjoiRXZlIEV2ZXJ5d29tYW4iLCJyZWZlcmVuY2UiOiJodHRwOi8vZmhpci5oZWFsdGhpbnRlcnNlY3Rpb25zLmNvbS5hdS9vcGVuL1BhdGllbnQvZDEifSwicmVhY3Rpb24iOlt7Im1hbmlmZXN0YXRpb24iOlt7ImNvZGluZyI6W3siY29kZSI6Inh4eCIsImRpc3BsYXkiOiJIaXZlcyIsInN5c3RlbSI6Imh0dHA6Ly9leGFtcGxlLm9yZy9zeXN0ZW0ifV0sInRleHQiOiJIaXZlcyJ9XX1dLCJyZWNvcmRlZERhdGUiOiIyMDEyLTA5LTE3IiwicmVzb3VyY2VUeXBlIjoiQWxsZXJneUludG9sZXJhbmNlIiwidGV4dCI6eyJkaXYiOiI8ZGl2IHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiPlNlbnNpdGl2aXR5IHRvIERveHljeWNsaW5lIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIEhpdmVzPC9kaXY-Iiwic3RhdHVzIjoiZ2VuZXJhdGVkIn0sInR5cGUiOiJhbGxlcmd5IiwidmVyaWZpY2F0aW9uU3RhdHVzIjp7ImNvZGluZyI6W3siY29kZSI6ImNvbmZpcm1lZCIsImRpc3BsYXkiOiJDb25maXJtZWQiLCJzeXN0ZW0iOiJodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2FsbGVyZ3lpbnRvbGVyYW5jZS12ZXJpZmljYXRpb24ifV19fX1dLCJpZGVudGlmaWVyIjp7InN5c3RlbSI6InVybjppZXRmOnJmYzozOTg2IiwidmFsdWUiOiJ1cm46dXVpZDowYzMxNTFiZC0xY2JmLTRkNjQtYjA0ZC1jZDkxODdhNGM2ZTAifSwicmVzb3VyY2VUeXBlIjoiQnVuZGxlIiwidGltZXN0YW1wIjoiMjAxMy0wNS0yOFQyMjoxMjoyMVoiLCJ0eXBlIjoiZG9jdW1lbnQifQ\n", "\n", "signature:\n", "d420r0Y5pi--OkImCihlzP4_8PwPZiEQr4Py2rdDtAwnl_NaE5H1nqzvnmjSM3JHnhHQjHsx0Y9lcXHisfTmJyBiMbhHCo2pdGyLzE6km7MbY-I629yKG-D5sKhQevIXnTegWG7xzY3CB9GQ33IADqMDfG-vH77mgGlcBM9XTI_YbG6FeFjwFwLg2zv13BV727wu6EjC6xOHtbCsnKSqRvaxSYYR0Yh24ocfbniQbXxDVSgtQp5iVR7PRGo_oI4Alpz3APTrcZaEMur9Uhh6o50FXnE3e9i2C9M8pNHrcwxJ7VWguPbwPcttWtdoQapJEd0ftuXEpZxsgkwih3HfPAt7Vo8kVlRDH3IkCAA5X6qKec1HShXDZuBIj0SVUBGH1l2TOoEBwogXheL90lujz4ARzZlw_K3kBMmRMttunp7c-jYbgnmTipMLAn0yhR9AlJgT1UxgaiLNZu2mzFn0vRNE69OyrnQsFwLxVBXBqBv74rZcOld99RrtCDTGGziQ\n", "\n" ] } ], "source": [ "split_sig = recd_jws.split('.')\n", "split_sig[1] = recd_b64_canonical_bundle\n", "recd_jws = '.'.join(split_sig)\n", "for i,j in enumerate(recd_jws.split('.')):\n", " print(f'{labels[i]}:')\n", " print(f'{j}')\n", " print()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 7. Obtain public Key from the first certificate in JWS header `\"x5c\"` key\n", "\n", "- base64 decode the key value\n", "- Verify Issuer, Validity Dates, Subject,and KeyUsage of certificate,\n", "- Get the “Subject Public Key Info” from the cert to verify the signature" ] }, { "cell_type": "code", "execution_count": 222, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'alg': 'RS256',\n", " 'kty': 'RS',\n", " 'typ': 'JWT',\n", " 'use': 'sig',\n", " 'x5c': ['MIIE3zCCA0egAwIBAgIJAOKFYvMwR+yQMA0GCSqGSIb3DQEBCwUAMIGNMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU2F1c2FsaXRvMRUwEwYDVQQKDAxIZWFsdGhlRGF0YTExFzAVBgNVBAMMDkVyaWMgSGFhcywgRFZNMSUwIwYJKoZIhvcNAQkBFhZlaGFhc0BoZWFsdGhlZGF0YTEub3JnMB4XDTIxMTAyNzE3NDIwNFoXDTIyMTAyMjE3NDIwNFowgY0xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlTYXVzYWxpdG8xFTATBgNVBAoMDEhlYWx0aGVEYXRhMTEXMBUGA1UEAwwORXJpYyBIYWFzLCBEVk0xJTAjBgkqhkiG9w0BCQEWFmVoYWFzQGhlYWx0aGVkYXRhMS5vcmcwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDpKcSkoAM6sW21+vWTeIVOGx10MWasQy7VHid6zyqXABM+znfBnXenyU0j1FTvPmRfODoODXVuPUwDomhCHh+bclW9KM2o563cxRKEvBnaHrsjw5yNmxO5YjERbhtHdQeqktdw3VYERR9HoxLO3FkszR292HTB4xW3yWlV3gTkMQozPScJKH3bG8Pqq6AYPJ7C4YBIlUSdBMVl3qneEfg7fuxiFfXofdTVm7rMiiG7X9z43PfilqaeisfmtRxAlRwENXrH3OvODPyL0rTnG8CsbAXYVIMmddHe4ZF9plh95sj4pMThLtcJX/o9XHLjh7EmZygJHWEQq4PwFwZdmbcfhCmOr88H8BbUru/7V6zbsG1N1CWlndlbVznL+3IMOr8kXaHcanqfckgFV4ErnfjFJq1OIaAmsMj85xMkjyXLycLL/u5n2o6Bg93/URfquOoSIGOCR25DaZzpw2k3s7oE9dMwEWXtfXgYth2bljy5tFH0GjpOkx07j7ZT5HnxnlsCAwEAAaNAMD4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCBeAwIQYDVR0RBBowGIIWd3d3LmhlYWx0aGVkYXRhaW5jLmNvbTANBgkqhkiG9w0BAQsFAAOCAYEACuMUNq9ay++e5YC7QFO94rfzxGQnF3GklZNAXmIr7PVGdiGY2GTx/9RtHCwTKzkL+yvKojeZ9dVK8wrGViRkO/jUyZ+KcWRokUjs59ncJGRMSSRxteCQujt4hf2+/qV+f2sMQtErwPE30vbqRYUNNNBVEQpaQx/acJDUv9v7sjHiJDqXwQ+rzj95iHAIaeEHqF/Ms22p2beZuqvIQKeMl+svVqHtiuzWnF4U6VImpkr4bHl7egV9H6l6T2SMkj6qDU5e9Ng0ZlLTtosshBLmopF7e7HyrTEAmfOPKQe0Eg9E2urzxqBuG54k50G2J0FiPsQJAhFiNGwSg4S3HyVDG7ueKd0L93wKONOYGvMKizCHB+pKvEMJoZ8y9uiB+HFXcp9RaJqJ97HpZTEv+liCp2PSXzcK0r25ScyjF6dLouK2SB30xAvJ8tE584+jqQ6CGecU9XjvlAjuJdCrDeVPsjkn7OPXG+8XZU7zqHZNmXX1YY4H5rgEJ48lrUrP3I8R']}" ] }, "execution_count": 222, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from jose import jws\n", "recd_header = jws.get_unverified_header(recd_jws)\n", "recd_header" ] }, { "cell_type": "code", "execution_count": 223, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Certificate:\n", " Data:\n", " Version: 3 (0x2)\n", " Serial Number: 16322561221100825744 (0xe28562f33047ec90)\n", " Signature Algorithm: sha256WithRSAEncryption\n", " Issuer: C=US, ST=California, L=Sausalito, O=HealtheData1, CN=Eric Haas, DVM/emailAddress=ehaas@healthedata1.org\n", " Validity\n", " Not Before: Oct 27 17:42:04 2021 GMT\n", " Not After : Oct 22 17:42:04 2022 GMT\n", " Subject: C=US, ST=California, L=Sausalito, O=HealtheData1, CN=Eric Haas, DVM/emailAddress=ehaas@healthedata1.org\n", " Subject Public Key Info:\n", " Public Key Algorithm: rsaEncryption\n", " Public-Key: (3072 bit)\n", " Modulus:\n", " 00:e9:29:c4:a4:a0:03:3a:b1:6d:b5:fa:f5:93:78:\n", " 85:4e:1b:1d:74:31:66:ac:43:2e:d5:1e:27:7a:cf:\n", " 2a:97:00:13:3e:ce:77:c1:9d:77:a7:c9:4d:23:d4:\n", " 54:ef:3e:64:5f:38:3a:0e:0d:75:6e:3d:4c:03:a2:\n", " 68:42:1e:1f:9b:72:55:bd:28:cd:a8:e7:ad:dc:c5:\n", " 12:84:bc:19:da:1e:bb:23:c3:9c:8d:9b:13:b9:62:\n", " 31:11:6e:1b:47:75:07:aa:92:d7:70:dd:56:04:45:\n", " 1f:47:a3:12:ce:dc:59:2c:cd:1d:bd:d8:74:c1:e3:\n", " 15:b7:c9:69:55:de:04:e4:31:0a:33:3d:27:09:28:\n", " 7d:db:1b:c3:ea:ab:a0:18:3c:9e:c2:e1:80:48:95:\n", " 44:9d:04:c5:65:de:a9:de:11:f8:3b:7e:ec:62:15:\n", " f5:e8:7d:d4:d5:9b:ba:cc:8a:21:bb:5f:dc:f8:dc:\n", " f7:e2:96:a6:9e:8a:c7:e6:b5:1c:40:95:1c:04:35:\n", " 7a:c7:dc:eb:ce:0c:fc:8b:d2:b4:e7:1b:c0:ac:6c:\n", " 05:d8:54:83:26:75:d1:de:e1:91:7d:a6:58:7d:e6:\n", " c8:f8:a4:c4:e1:2e:d7:09:5f:fa:3d:5c:72:e3:87:\n", " b1:26:67:28:09:1d:61:10:ab:83:f0:17:06:5d:99:\n", " b7:1f:84:29:8e:af:cf:07:f0:16:d4:ae:ef:fb:57:\n", " ac:db:b0:6d:4d:d4:25:a5:9d:d9:5b:57:39:cb:fb:\n", " 72:0c:3a:bf:24:5d:a1:dc:6a:7a:9f:72:48:05:57:\n", " 81:2b:9d:f8:c5:26:ad:4e:21:a0:26:b0:c8:fc:e7:\n", " 13:24:8f:25:cb:c9:c2:cb:fe:ee:67:da:8e:81:83:\n", " dd:ff:51:17:ea:b8:ea:12:20:63:82:47:6e:43:69:\n", " 9c:e9:c3:69:37:b3:ba:04:f5:d3:30:11:65:ed:7d:\n", " 78:18:b6:1d:9b:96:3c:b9:b4:51:f4:1a:3a:4e:93:\n", " 1d:3b:8f:b6:53:e4:79:f1:9e:5b\n", " Exponent: 65537 (0x10001)\n", " X509v3 extensions:\n", " X509v3 Basic Constraints: \n", " CA:TRUE\n", " X509v3 Key Usage: \n", " Digital Signature, Non Repudiation, Key Encipherment\n", " X509v3 Subject Alternative Name: \n", " DNS:www.healthedatainc.com\n", " Signature Algorithm: sha256WithRSAEncryption\n", " 0a:e3:14:36:af:5a:cb:ef:9e:e5:80:bb:40:53:bd:e2:b7:f3:\n", " c4:64:27:17:71:a4:95:93:40:5e:62:2b:ec:f5:46:76:21:98:\n", " d8:64:f1:ff:d4:6d:1c:2c:13:2b:39:0b:fb:2b:ca:a2:37:99:\n", " f5:d5:4a:f3:0a:c6:56:24:64:3b:f8:d4:c9:9f:8a:71:64:68:\n", " 91:48:ec:e7:d9:dc:24:64:4c:49:24:71:b5:e0:90:ba:3b:78:\n", " 85:fd:be:fe:a5:7e:7f:6b:0c:42:d1:2b:c0:f1:37:d2:f6:ea:\n", " 45:85:0d:34:d0:55:11:0a:5a:43:1f:da:70:90:d4:bf:db:fb:\n", " b2:31:e2:24:3a:97:c1:0f:ab:ce:3f:79:88:70:08:69:e1:07:\n", " a8:5f:cc:b3:6d:a9:d9:b7:99:ba:ab:c8:40:a7:8c:97:eb:2f:\n", " 56:a1:ed:8a:ec:d6:9c:5e:14:e9:52:26:a6:4a:f8:6c:79:7b:\n", " 7a:05:7d:1f:a9:7a:4f:64:8c:92:3e:aa:0d:4e:5e:f4:d8:34:\n", " 66:52:d3:b6:8b:2c:84:12:e6:a2:91:7b:7b:b1:f2:ad:31:00:\n", " 99:f3:8f:29:07:b4:12:0f:44:da:ea:f3:c6:a0:6e:1b:9e:24:\n", " e7:41:b6:27:41:62:3e:c4:09:02:11:62:34:6c:12:83:84:b7:\n", " 1f:25:43:1b:bb:9e:29:dd:0b:f7:7c:0a:38:d3:98:1a:f3:0a:\n", " 8b:30:87:07:ea:4a:bc:43:09:a1:9f:32:f6:e8:81:f8:71:57:\n", " 72:9f:51:68:9a:89:f7:b1:e9:65:31:2f:fa:58:82:a7:63:d2:\n", " 5f:37:0a:d2:bd:b9:49:cc:a3:17:a7:4b:a2:e2:b6:48:1d:f4:\n", " c4:0b:c9:f2:d1:39:f3:8f:a3:a9:0e:82:19:e7:14:f5:78:ef:\n", " 94:08:ee:25:d0:ab:0d:e5:4f:b2:39:27:ec:e3:d7:1b:ef:17:\n", " 65:4e:f3:a8:76:4d:99:75:f5:61:8e:07:e6:b8:04:27:8f:25:\n", " ad:4a:cf:dc:8f:11\n", "-----BEGIN CERTIFICATE-----\n", "MIIE3zCCA0egAwIBAgIJAOKFYvMwR+yQMA0GCSqGSIb3DQEBCwUAMIGNMQswCQYD\n", "VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU2F1c2FsaXRv\n", "MRUwEwYDVQQKDAxIZWFsdGhlRGF0YTExFzAVBgNVBAMMDkVyaWMgSGFhcywgRFZN\n", "MSUwIwYJKoZIhvcNAQkBFhZlaGFhc0BoZWFsdGhlZGF0YTEub3JnMB4XDTIxMTAy\n", "NzE3NDIwNFoXDTIyMTAyMjE3NDIwNFowgY0xCzAJBgNVBAYTAlVTMRMwEQYDVQQI\n", "DApDYWxpZm9ybmlhMRIwEAYDVQQHDAlTYXVzYWxpdG8xFTATBgNVBAoMDEhlYWx0\n", "aGVEYXRhMTEXMBUGA1UEAwwORXJpYyBIYWFzLCBEVk0xJTAjBgkqhkiG9w0BCQEW\n", "FmVoYWFzQGhlYWx0aGVkYXRhMS5vcmcwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAw\n", "ggGKAoIBgQDpKcSkoAM6sW21+vWTeIVOGx10MWasQy7VHid6zyqXABM+znfBnXen\n", "yU0j1FTvPmRfODoODXVuPUwDomhCHh+bclW9KM2o563cxRKEvBnaHrsjw5yNmxO5\n", "YjERbhtHdQeqktdw3VYERR9HoxLO3FkszR292HTB4xW3yWlV3gTkMQozPScJKH3b\n", "G8Pqq6AYPJ7C4YBIlUSdBMVl3qneEfg7fuxiFfXofdTVm7rMiiG7X9z43Pfilqae\n", "isfmtRxAlRwENXrH3OvODPyL0rTnG8CsbAXYVIMmddHe4ZF9plh95sj4pMThLtcJ\n", "X/o9XHLjh7EmZygJHWEQq4PwFwZdmbcfhCmOr88H8BbUru/7V6zbsG1N1CWlndlb\n", "VznL+3IMOr8kXaHcanqfckgFV4ErnfjFJq1OIaAmsMj85xMkjyXLycLL/u5n2o6B\n", "g93/URfquOoSIGOCR25DaZzpw2k3s7oE9dMwEWXtfXgYth2bljy5tFH0GjpOkx07\n", "j7ZT5HnxnlsCAwEAAaNAMD4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCBeAwIQYD\n", "VR0RBBowGIIWd3d3LmhlYWx0aGVkYXRhaW5jLmNvbTANBgkqhkiG9w0BAQsFAAOC\n", "AYEACuMUNq9ay++e5YC7QFO94rfzxGQnF3GklZNAXmIr7PVGdiGY2GTx/9RtHCwT\n", "KzkL+yvKojeZ9dVK8wrGViRkO/jUyZ+KcWRokUjs59ncJGRMSSRxteCQujt4hf2+\n", "/qV+f2sMQtErwPE30vbqRYUNNNBVEQpaQx/acJDUv9v7sjHiJDqXwQ+rzj95iHAI\n", "aeEHqF/Ms22p2beZuqvIQKeMl+svVqHtiuzWnF4U6VImpkr4bHl7egV9H6l6T2SM\n", "kj6qDU5e9Ng0ZlLTtosshBLmopF7e7HyrTEAmfOPKQe0Eg9E2urzxqBuG54k50G2\n", "J0FiPsQJAhFiNGwSg4S3HyVDG7ueKd0L93wKONOYGvMKizCHB+pKvEMJoZ8y9uiB\n", "+HFXcp9RaJqJ97HpZTEv+liCp2PSXzcK0r25ScyjF6dLouK2SB30xAvJ8tE584+j\n", "qQ6CGecU9XjvlAjuJdCrDeVPsjkn7OPXG+8XZU7zqHZNmXX1YY4H5rgEJ48lrUrP\n", "3I8R\n", "-----END CERTIFICATE-----\n" ] } ], "source": [ "recd_cert = b64decode(recd_header['x5c'][0])\n", "with open('recd_cert.der', 'wb') as f:\n", " f.write(recd_cert)\n", "!openssl x509 -in recd_cert.der -inform DER -text" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 10. Verify Signature using the public key or the X.509 Certificate\n", "\n", "Alternatively:\n", "1. visit https://jwt.io.\n", "1. At the top of the page, select \"RS256\" for the algorithm.\n", "1. Paste the JWS value printed below into the “Encoded” field.\n", "1. The plaintext JWT will be displayed in the “Decoded:Payload” field.\n", "1. The X509 Cert above will appear in the \"Verify Signature\" box.\n", "1. If verified, a “Signature Verified” message will appear in the bottom left hand corner." ] }, { "cell_type": "code", "execution_count": 224, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'eyJhbGciOiJSUzI1NiIsImt0eSI6IlJTIiwidHlwIjoiSldUIiwidXNlIjoic2lnIiwieDVjIjpbIk1JSUUzekNDQTBlZ0F3SUJBZ0lKQU9LRll2TXdSK3lRTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdOTVFzd0NRWURWUVFHRXdKVlV6RVRNQkVHQTFVRUNBd0tRMkZzYVdadmNtNXBZVEVTTUJBR0ExVUVCd3dKVTJGMWMyRnNhWFJ2TVJVd0V3WURWUVFLREF4SVpXRnNkR2hsUkdGMFlURXhGekFWQmdOVkJBTU1Ea1Z5YVdNZ1NHRmhjeXdnUkZaTk1TVXdJd1lKS29aSWh2Y05BUWtCRmhabGFHRmhjMEJvWldGc2RHaGxaR0YwWVRFdWIzSm5NQjRYRFRJeE1UQXlOekUzTkRJd05Gb1hEVEl5TVRBeU1qRTNOREl3TkZvd2dZMHhDekFKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SSXdFQVlEVlFRSERBbFRZWFZ6WVd4cGRHOHhGVEFUQmdOVkJBb01ERWhsWVd4MGFHVkVZWFJoTVRFWE1CVUdBMVVFQXd3T1JYSnBZeUJJWVdGekxDQkVWazB4SlRBakJna3Foa2lHOXcwQkNRRVdGbVZvWVdGelFHaGxZV3gwYUdWa1lYUmhNUzV2Y21jd2dnR2lNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJqd0F3Z2dHS0FvSUJnUURwS2NTa29BTTZzVzIxK3ZXVGVJVk9HeDEwTVdhc1F5N1ZIaWQ2enlxWEFCTSt6bmZCblhlbnlVMGoxRlR2UG1SZk9Eb09EWFZ1UFV3RG9taENIaCtiY2xXOUtNMm81NjNjeFJLRXZCbmFIcnNqdzV5Tm14TzVZakVSYmh0SGRRZXFrdGR3M1ZZRVJSOUhveExPM0Zrc3pSMjkySFRCNHhXM3lXbFYzZ1RrTVFvelBTY0pLSDNiRzhQcXE2QVlQSjdDNFlCSWxVU2RCTVZsM3FuZUVmZzdmdXhpRmZYb2ZkVFZtN3JNaWlHN1g5ejQzUGZpbHFhZWlzZm10UnhBbFJ3RU5YckgzT3ZPRFB5TDByVG5HOENzYkFYWVZJTW1kZEhlNFpGOXBsaDk1c2o0cE1UaEx0Y0pYL285WEhMamg3RW1aeWdKSFdFUXE0UHdGd1pkbWJjZmhDbU9yODhIOEJiVXJ1LzdWNnpic0cxTjFDV2xuZGxiVnpuTCszSU1PcjhrWGFIY2FucWZja2dGVjRFcm5makZKcTFPSWFBbXNNajg1eE1ranlYTHljTEwvdTVuMm82Qmc5My9VUmZxdU9vU0lHT0NSMjVEYVp6cHcyazNzN29FOWRNd0VXWHRmWGdZdGgyYmxqeTV0RkgwR2pwT2t4MDdqN1pUNUhueG5sc0NBd0VBQWFOQU1ENHdEQVlEVlIwVEJBVXdBd0VCL3pBTEJnTlZIUThFQkFNQ0JlQXdJUVlEVlIwUkJCb3dHSUlXZDNkM0xtaGxZV3gwYUdWa1lYUmhhVzVqTG1OdmJUQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FZRUFDdU1VTnE5YXkrK2U1WUM3UUZPOTRyZnp4R1FuRjNHa2xaTkFYbUlyN1BWR2RpR1kyR1R4LzlSdEhDd1RLemtMK3l2S29qZVo5ZFZLOHdyR1ZpUmtPL2pVeVorS2NXUm9rVWpzNTluY0pHUk1TU1J4dGVDUXVqdDRoZjIrL3FWK2Yyc01RdEVyd1BFMzB2YnFSWVVOTk5CVkVRcGFReC9hY0pEVXY5djdzakhpSkRxWHdRK3J6ajk1aUhBSWFlRUhxRi9NczIycDJiZVp1cXZJUUtlTWwrc3ZWcUh0aXV6V25GNFU2VkltcGtyNGJIbDdlZ1Y5SDZsNlQyU01rajZxRFU1ZTlOZzBabExUdG9zc2hCTG1vcEY3ZTdIeXJURUFtZk9QS1FlMEVnOUUydXJ6eHFCdUc1NGs1MEcySjBGaVBzUUpBaEZpTkd3U2c0UzNIeVZERzd1ZUtkMEw5M3dLT05PWUd2TUtpekNIQitwS3ZFTUpvWjh5OXVpQitIRlhjcDlSYUpxSjk3SHBaVEV2K2xpQ3AyUFNYemNLMHIyNVNjeWpGNmRMb3VLMlNCMzB4QXZKOHRFNTg0K2pxUTZDR2VjVTlYanZsQWp1SmRDckRlVlBzamtuN09QWEcrOFhaVTd6cUhaTm1YWDFZWTRINXJnRUo0OGxyVXJQM0k4UiJdfQ.eyJlbnRyeSI6W3siZnVsbFVybCI6Imh0dHA6Ly9maGlyLmhlYWx0aGludGVyc2VjdGlvbnMuY29tLmF1L29wZW4vQ29tcG9zaXRpb24vMTgwZjIxOWYtOTdhOC00ODZkLTk5ZDktZWQ2MzFmZTRmYzU3IiwicmVzb3VyY2UiOnsiYXV0aG9yIjpbeyJkaXNwbGF5IjoiRG9jdG9yIERhdmUiLCJyZWZlcmVuY2UiOiJQcmFjdGl0aW9uZXIvZXhhbXBsZSJ9XSwiY29uZmlkZW50aWFsaXR5IjoiTiIsImRhdGUiOiIyMDEzLTAyLTAxVDEyOjMwOjAyWiIsImVuY291bnRlciI6eyJyZWZlcmVuY2UiOiJodHRwOi8vZmhpci5oZWFsdGhpbnRlcnNlY3Rpb25zLmNvbS5hdS9vcGVuL0VuY291bnRlci9kb2MtZXhhbXBsZSJ9LCJpZCI6IjE4MGYyMTlmLTk3YTgtNDg2ZC05OWQ5LWVkNjMxZmU0ZmM1NyIsIm1ldGEiOnsibGFzdFVwZGF0ZWQiOiIyMDEzLTA1LTI4VDIyOjEyOjIxWiJ9LCJyZXNvdXJjZVR5cGUiOiJDb21wb3NpdGlvbiIsInNlY3Rpb24iOlt7ImNvZGUiOnsiY29kaW5nIjpbeyJjb2RlIjoiMjkyOTktNSIsImRpc3BsYXkiOiJSZWFzb24gZm9yIHZpc2l0IE5hcnJhdGl2ZSIsInN5c3RlbSI6Imh0dHA6Ly9sb2luYy5vcmcifV19LCJlbnRyeSI6W3sicmVmZXJlbmNlIjoidXJuOnV1aWQ6NTQxYTcyYTgtZGY3NS00NDg0LWFjODktYWM0OTIzZjAzYjgxIn1dLCJ0ZXh0Ijp7ImRpdiI6IjxkaXYgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI-XG5cbiAgICAgICAgICAgICAgPHRhYmxlPlxuXG4gICAgICAgICAgICAgICAgPHRoZWFkPlxuXG4gICAgICAgICAgICAgICAgICA8dHI-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPkRldGFpbHM8L3RkPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ZC8-XG5cbiAgICAgICAgICAgICAgICAgIDwvdHI-XG5cbiAgICAgICAgICAgICAgICA8L3RoZWFkPlxuXG4gICAgICAgICAgICAgICAgPHRib2R5PlxuXG4gICAgICAgICAgICAgICAgICA8dHI-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPkFjdXRlIEFzdGhtYXRpYyBhdHRhY2suIFdhcyB3aGVlemluZyBmb3IgZGF5cyBwcmlvciB0byBhZG1pc3Npb24uPC90ZD5cblxuICAgICAgICAgICAgICAgICAgICA8dGQvPlxuXG4gICAgICAgICAgICAgICAgICA8L3RyPlxuXG4gICAgICAgICAgICAgICAgPC90Ym9keT5cblxuICAgICAgICAgICAgICA8L3RhYmxlPlxuXG4gICAgICAgICAgICA8L2Rpdj4iLCJzdGF0dXMiOiJhZGRpdGlvbmFsIn0sInRpdGxlIjoiUmVhc29uIGZvciBhZG1pc3Npb24ifSx7ImNvZGUiOnsiY29kaW5nIjpbeyJjb2RlIjoiMTAxODMtMiIsImRpc3BsYXkiOiJIb3NwaXRhbCBkaXNjaGFyZ2UgbWVkaWNhdGlvbnMgTmFycmF0aXZlIiwic3lzdGVtIjoiaHR0cDovL2xvaW5jLm9yZyJ9XX0sImVudHJ5IjpbeyJyZWZlcmVuY2UiOiJ1cm46dXVpZDoxMjRhNjkxNi01ZDg0LTRiOGMtYjI1MC0xMGNlZmI4ZTZlODYifSx7InJlZmVyZW5jZSI6InVybjp1dWlkOjY3M2Y4ZGI1LTBmZmQtNDM5NS05NjU3LTZkYTAwNDIwYmJjMSJ9XSwibW9kZSI6IndvcmtpbmciLCJ0ZXh0Ijp7ImRpdiI6IjxkaXYgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI-XG5cbiAgICAgICAgICAgICAgPHRhYmxlPlxuXG4gICAgICAgICAgICAgICAgPHRoZWFkPlxuXG4gICAgICAgICAgICAgICAgICA8dHI-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPk1lZGljYXRpb248L3RkPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ZD5MYXN0IENoYW5nZTwvdGQ-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPkxhc3QgQ2hhbmdlUmVhc29uPC90ZD5cblxuICAgICAgICAgICAgICAgICAgPC90cj5cblxuICAgICAgICAgICAgICAgIDwvdGhlYWQ-XG5cbiAgICAgICAgICAgICAgICA8dGJvZHk-XG5cbiAgICAgICAgICAgICAgICAgIDx0cj5cblxuICAgICAgICAgICAgICAgICAgICA8dGQ-VGhlb3BoeWxsaW5lIDIwMG1nIEJEIGFmdGVyIG1lYWxzPC90ZD5cblxuICAgICAgICAgICAgICAgICAgICA8dGQ-Y29udGludWVkPC90ZD5cblxuICAgICAgICAgICAgICAgICAgPC90cj5cblxuICAgICAgICAgICAgICAgICAgPHRyPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ZD5WZW50b2xpbiBJbmhhbGVyPC90ZD5cblxuICAgICAgICAgICAgICAgICAgICA8dGQ-c3RvcHBlZDwvdGQ-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPkdldHRpbmcgc2lkZSBlZmZlY3Qgb2YgdHJlbW9yPC90ZD5cblxuICAgICAgICAgICAgICAgICAgPC90cj5cblxuICAgICAgICAgICAgICAgIDwvdGJvZHk-XG5cbiAgICAgICAgICAgICAgPC90YWJsZT5cblxuICAgICAgICAgICAgPC9kaXY-Iiwic3RhdHVzIjoiYWRkaXRpb25hbCJ9LCJ0aXRsZSI6Ik1lZGljYXRpb25zIG9uIERpc2NoYXJnZSJ9LHsiY29kZSI6eyJjb2RpbmciOlt7ImNvZGUiOiI0ODc2NS0yIiwiZGlzcGxheSI6IkFsbGVyZ2llcyBhbmQgYWR2ZXJzZSByZWFjdGlvbnMgRG9jdW1lbnQiLCJzeXN0ZW0iOiJodHRwOi8vbG9pbmMub3JnIn1dfSwiZW50cnkiOlt7InJlZmVyZW5jZSI6InVybjp1dWlkOjQ3NjAwZTBmLWI2YjUtNDMwOC04NGI1LTVkZWMxNTdmNzYzNyJ9XSwidGV4dCI6eyJkaXYiOiI8ZGl2IHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiPlxuXG4gICAgICAgICAgICAgIDx0YWJsZT5cblxuICAgICAgICAgICAgICAgIDx0aGVhZD5cblxuICAgICAgICAgICAgICAgICAgPHRyPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ZD5BbGxlcmdlbjwvdGQ-XG5cbiAgICAgICAgICAgICAgICAgICAgPHRkPlJlYWN0aW9uPC90ZD5cblxuICAgICAgICAgICAgICAgICAgPC90cj5cblxuICAgICAgICAgICAgICAgIDwvdGhlYWQ-XG5cbiAgICAgICAgICAgICAgICA8dGJvZHk-XG5cbiAgICAgICAgICAgICAgICAgIDx0cj5cblxuICAgICAgICAgICAgICAgICAgICA8dGQ-RG94eWN5Y2xpbmU8L3RkPlxuXG4gICAgICAgICAgICAgICAgICAgIDx0ZD5IaXZlczwvdGQ-XG5cbiAgICAgICAgICAgICAgICAgIDwvdHI-XG5cbiAgICAgICAgICAgICAgICA8L3Rib2R5PlxuXG4gICAgICAgICAgICAgIDwvdGFibGU-XG5cbiAgICAgICAgICAgIDwvZGl2PiIsInN0YXR1cyI6ImFkZGl0aW9uYWwifSwidGl0bGUiOiJLbm93biBhbGxlcmdpZXMifV0sInN0YXR1cyI6ImZpbmFsIiwic3ViamVjdCI6eyJkaXNwbGF5IjoiRXZlIEV2ZXJ5d29tYW4iLCJyZWZlcmVuY2UiOiJodHRwOi8vZmhpci5oZWFsdGhpbnRlcnNlY3Rpb25zLmNvbS5hdS9vcGVuL1BhdGllbnQvZDEifSwidGV4dCI6eyJkaXYiOiI8ZGl2IHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiPjxwPjxiPkdlbmVyYXRlZCBOYXJyYXRpdmUgd2l0aCBEZXRhaWxzPC9iPjwvcD48cD48Yj5pZDwvYj46IDE4MGYyMTlmLTk3YTgtNDg2ZC05OWQ5LWVkNjMxZmU0ZmM1NzwvcD48cD48Yj5tZXRhPC9iPjogPC9wPjxwPjxiPnN0YXR1czwvYj46IGZpbmFsPC9wPjxwPjxiPnR5cGU8L2I-OiBEaXNjaGFyZ2UgU3VtbWFyeSBmcm9tIFJlc3BvbnNpYmxlIENsaW5pY2lhbiA8c3Bhbj4oRGV0YWlscyA6IHtMT0lOQyBjb2RlICcyODY1NS05JyA9ICdQaHlzaWNpYW4gYXR0ZW5kaW5nIERpc2NoYXJnZSBzdW1tYXJ5KTwvc3Bhbj48L3A-PHA-PGI-ZW5jb3VudGVyPC9iPjogPGE-aHR0cDovL2ZoaXIuaGVhbHRoaW50ZXJzZWN0aW9ucy5jb20uYXUvb3Blbi9FbmNvdW50ZXIvZG9jLWV4YW1wbGU8L2E-PC9wPjxwPjxiPmRhdGU8L2I-OiAwMS8wMi8yMDEzIDEyOjMwOjAyIFBNPC9wPjxwPjxiPmF1dGhvcjwvYj46IDxhPkRvY3RvciBEYXZlPC9hPjwvcD48cD48Yj50aXRsZTwvYj46IERpc2NoYXJnZSBTdW1tYXJ5PC9wPjxwPjxiPmNvbmZpZGVudGlhbGl0eTwvYj46IE48L3A-PC9kaXY-Iiwic3RhdHVzIjoiZ2VuZXJhdGVkIn0sInRpdGxlIjoiRGlzY2hhcmdlIFN1bW1hcnkiLCJ0eXBlIjp7ImNvZGluZyI6W3siY29kZSI6IjI4NjU1LTkiLCJzeXN0ZW0iOiJodHRwOi8vbG9pbmMub3JnIn1dLCJ0ZXh0IjoiRGlzY2hhcmdlIFN1bW1hcnkgZnJvbSBSZXNwb25zaWJsZSBDbGluaWNpYW4ifX19LHsiZnVsbFVybCI6Imh0dHA6Ly9maGlyLmhlYWx0aGludGVyc2VjdGlvbnMuY29tLmF1L29wZW4vUHJhY3RpdGlvbmVyL2V4YW1wbGUiLCJyZXNvdXJjZSI6eyJpZCI6ImV4YW1wbGUiLCJpZGVudGlmaWVyIjpbeyJzeXN0ZW0iOiJodHRwOi8vd3d3LmFjbWUub3JnL3ByYWN0aXRpb25lcnMiLCJ2YWx1ZSI6IjIzIn1dLCJtZXRhIjp7Imxhc3RVcGRhdGVkIjoiMjAxMy0wNS0wNVQxNjoxMzowM1oifSwibmFtZSI6W3siZmFtaWx5IjoiQ2FyZWZ1bCIsImdpdmVuIjpbIkFkYW0iXSwicHJlZml4IjpbIkRyIl19XSwicmVzb3VyY2VUeXBlIjoiUHJhY3RpdGlvbmVyIiwidGV4dCI6eyJkaXYiOiI8ZGl2IHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiPlxuXG4gICAgICAgICAgICA8cD5EciBBZGFtIENhcmVmdWw8L3A-XG5cbiAgICAgICAgICA8L2Rpdj4iLCJzdGF0dXMiOiJnZW5lcmF0ZWQifX19LHsiZnVsbFVybCI6Imh0dHA6Ly9maGlyLmhlYWx0aGludGVyc2VjdGlvbnMuY29tLmF1L29wZW4vUGF0aWVudC9kMSIsInJlc291cmNlIjp7ImFjdGl2ZSI6dHJ1ZSwiYWRkcmVzcyI6W3sibGluZSI6WyIyMjIyIEhvbWUgU3RyZWV0Il0sInVzZSI6ImhvbWUifV0sImJpcnRoRGF0ZSI6IjE5NTUtMDEtMDYiLCJnZW5kZXIiOiJmZW1hbGUiLCJpZCI6ImQxIiwibmFtZSI6W3siZmFtaWx5IjoiRXZlcnl3b21hbjEiLCJnaXZlbiI6WyJFdmUiXSwidGV4dCI6IkV2ZSBFdmVyeXdvbWFuIn1dLCJyZXNvdXJjZVR5cGUiOiJQYXRpZW50IiwidGVsZWNvbSI6W3sic3lzdGVtIjoicGhvbmUiLCJ1c2UiOiJ3b3JrIiwidmFsdWUiOiI1NTUtNTU1LTIwMDMifV0sInRleHQiOnsiZGl2IjoiPGRpdiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIj5cblxuICAgICAgICAgICAgPGgxPkV2ZSBFdmVyeXdvbWFuPC9oMT5cblxuICAgICAgICAgIDwvZGl2PiIsInN0YXR1cyI6ImdlbmVyYXRlZCJ9fX0seyJmdWxsVXJsIjoiaHR0cDovL2ZoaXIuaGVhbHRoaW50ZXJzZWN0aW9ucy5jb20uYXUvb3Blbi9FbmNvdW50ZXIvZG9jLWV4YW1wbGUiLCJyZXNvdXJjZSI6eyJjbGFzcyI6eyJjb2RlIjoiSU1QIiwiZGlzcGxheSI6ImlucGF0aWVudCBlbmNvdW50ZXIiLCJzeXN0ZW0iOiJodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL3YzLUFjdENvZGUifSwiaG9zcGl0YWxpemF0aW9uIjp7ImRpc2NoYXJnZURpc3Bvc2l0aW9uIjp7InRleHQiOiJEaXNjaGFyZ2VkIHRvIGNhcmUgb2YgR1AifX0sImlkIjoiZG9jLWV4YW1wbGUiLCJpZGVudGlmaWVyIjpbeyJ2YWx1ZSI6IlMxMDAifV0sIm1ldGEiOnsibGFzdFVwZGF0ZWQiOiIyMDEzLTA1LTA1VDE2OjEzOjAzWiJ9LCJwZXJpb2QiOnsiZW5kIjoiMjAxMy0wMi0wMVQxMjozMDowMloiLCJzdGFydCI6IjIwMTMtMDEtMjBUMTI6MzA6MDJaIn0sInJlc291cmNlVHlwZSI6IkVuY291bnRlciIsInN0YXR1cyI6ImZpbmlzaGVkIiwic3ViamVjdCI6eyJyZWZlcmVuY2UiOiJQYXRpZW50L2QxIn0sInRleHQiOnsiZGl2IjoiPGRpdiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIj4gQWRtaXR0ZWQgdG8gT3J0aG9wZWRpY3MgU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIE1pZGRsZW1vcmUgSG9zcGl0YWwgYmV0d2VlbiBKYW4gMjAgYW5kIEZlYiBpc3QgMjAxMyA8L2Rpdj4iLCJzdGF0dXMiOiJnZW5lcmF0ZWQifSwidHlwZSI6W3sidGV4dCI6Ik9ydGhvcGVkaWMgQWRtaXNzaW9uIn1dfX0seyJmdWxsVXJsIjoidXJuOnV1aWQ6NTQxYTcyYTgtZGY3NS00NDg0LWFjODktYWM0OTIzZjAzYjgxIiwicmVzb3VyY2UiOnsiY29kZSI6eyJjb2RpbmciOlt7ImNvZGUiOiI0NjI0MS02Iiwic3lzdGVtIjoiaHR0cDovL2xvaW5jLm9yZyJ9XSwidGV4dCI6IlJlYXNvbiBmb3IgYWRtaXNzaW9uIn0sImVuY291bnRlciI6eyJyZWZlcmVuY2UiOiJodHRwOi8vZmhpci5oZWFsdGhpbnRlcnNlY3Rpb25zLmNvbS5hdS9vcGVuL0VuY291bnRlci9kb2MtZXhhbXBsZSJ9LCJtZXRhIjp7Imxhc3RVcGRhdGVkIjoiMjAxMy0wNS0wNVQxNjoxMzowM1oifSwicmVzb3VyY2VUeXBlIjoiT2JzZXJ2YXRpb24iLCJzdGF0dXMiOiJmaW5hbCIsInN1YmplY3QiOnsiZGlzcGxheSI6IkV2ZSBFdmVyeXdvbWFuIiwicmVmZXJlbmNlIjoiaHR0cDovL2ZoaXIuaGVhbHRoaW50ZXJzZWN0aW9ucy5jb20uYXUvb3Blbi9QYXRpZW50L2QxIn0sInRleHQiOnsiZGl2IjoiPGRpdiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIj4gQWN1dGUgQXN0aG1hdGljIGF0dGFjay4gV2FzIHdoZWV6aW5nXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgZGF5cyBwcmlvciB0byBhZG1pc3Npb24uIDwvZGl2PiIsInN0YXR1cyI6ImFkZGl0aW9uYWwifSwidmFsdWVTdHJpbmciOiJBY3V0ZSBBc3RobWF0aWMgYXR0YWNrLiBXYXMgd2hlZXppbmcgZm9yIGRheXMgcHJpb3IgdG8gYWRtaXNzaW9uLiJ9fSx7ImZ1bGxVcmwiOiJ1cm46dXVpZDoxMjRhNjkxNi01ZDg0LTRiOGMtYjI1MC0xMGNlZmI4ZTZlODYiLCJyZXNvdXJjZSI6eyJkb3NhZ2VJbnN0cnVjdGlvbiI6W3siYWRkaXRpb25hbEluc3RydWN0aW9uIjpbeyJ0ZXh0IjoiVGFrZSB3aXRoIEZvb2QifV0sImRvc2VBbmRSYXRlIjpbeyJkb3NlUXVhbnRpdHkiOnsiY29kZSI6InRibCIsInN5c3RlbSI6Imh0dHA6Ly91bml0c29mbWVhc3VyZS5vcmciLCJ1bml0IjoidGFibGV0IiwidmFsdWUiOjF9LCJ0eXBlIjp7ImNvZGluZyI6W3siY29kZSI6Im9yZGVyZWQiLCJkaXNwbGF5IjoiT3JkZXJlZCIsInN5c3RlbSI6Imh0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vZG9zZS1yYXRlLXR5cGUifV19fV0sInJvdXRlIjp7ImNvZGluZyI6W3siY29kZSI6IjM5NDg5OTAwMyIsImRpc3BsYXkiOiJvcmFsIGFkbWluaXN0cmF0aW9uIG9mIHRyZWF0bWVudCIsInN5c3RlbSI6Imh0dHA6Ly9zbm9tZWQuaW5mby9zY3QifV19LCJ0aW1pbmciOnsicmVwZWF0Ijp7ImZyZXF1ZW5jeSI6MiwicGVyaW9kIjoxLCJwZXJpb2RVbml0IjoiZCJ9fX1dLCJpbnRlbnQiOiJvcmRlciIsIm1lZGljYXRpb25Db2RlYWJsZUNvbmNlcHQiOnsiY29kaW5nIjpbeyJjb2RlIjoiNjY0OTMwMDMiLCJzeXN0ZW0iOiJodHRwOi8vc25vbWVkLmluZm8vc2N0In1dLCJ0ZXh0IjoiVGhlb3BoeWxsaW5lIDIwMG1nIn0sIm1ldGEiOnsibGFzdFVwZGF0ZWQiOiIyMDEzLTA1LTA1VDE2OjEzOjAzWiJ9LCJyZWFzb25Db2RlIjpbeyJ0ZXh0IjoiTWFuYWdlbWVudCBvZiBBc3RobWEifV0sInJlcXVlc3RlciI6eyJkaXNwbGF5IjoiUGV0ZXIgUHJhY3RpdGlvbmVyIiwicmVmZXJlbmNlIjoiUHJhY3RpdGlvbmVyL2V4YW1wbGUifSwicmVzb3VyY2VUeXBlIjoiTWVkaWNhdGlvblJlcXVlc3QiLCJzdGF0dXMiOiJ1bmtub3duIiwic3ViamVjdCI6eyJkaXNwbGF5IjoiUGV0ZXIgUGF0aWVudCIsInJlZmVyZW5jZSI6Imh0dHA6Ly9maGlyLmhlYWx0aGludGVyc2VjdGlvbnMuY29tLmF1L29wZW4vUGF0aWVudC9kMSJ9LCJ0ZXh0Ijp7ImRpdiI6IjxkaXYgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI-XG5cbiAgICAgICAgICAgIDxwPlRoZW9waHlsbGluZSAyMDBtZyB0d2ljZSBhIGRheTwvcD5cblxuICAgICAgICAgIDwvZGl2PiIsInN0YXR1cyI6ImdlbmVyYXRlZCJ9fX0seyJmdWxsVXJsIjoidXJuOnV1aWQ6NjczZjhkYjUtMGZmZC00Mzk1LTk2NTctNmRhMDA0MjBiYmMxIiwicmVzb3VyY2UiOnsiZGF0ZUFzc2VydGVkIjoiMjAxMy0wNS0wNVQxNjoxMzowM1oiLCJtZWRpY2F0aW9uQ29kZWFibGVDb25jZXB0Ijp7InRleHQiOiJWZW50b2xpbiBJbmhhbGVyIn0sInJlc291cmNlVHlwZSI6Ik1lZGljYXRpb25TdGF0ZW1lbnQiLCJzdGF0dXMiOiJhY3RpdmUiLCJzdGF0dXNSZWFzb24iOlt7InRleHQiOiJNYW5hZ2VtZW50IG9mIEFzdGhtYSJ9XSwic3ViamVjdCI6eyJkaXNwbGF5IjoiUGV0ZXIgUGF0aWVudCIsInJlZmVyZW5jZSI6Imh0dHA6Ly9maGlyLmhlYWx0aGludGVyc2VjdGlvbnMuY29tLmF1L29wZW4vUGF0aWVudC9kMSJ9LCJ0ZXh0Ijp7ImRpdiI6IjxkaXYgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI-XG5cbiAgICAgICAgICAgIDxwPlZlbnRvbGluIGluaGFsZXIgZGlzY29udGludWVkPC9wPlxuXG4gICAgICAgICAgPC9kaXY-Iiwic3RhdHVzIjoiZ2VuZXJhdGVkIn19fSx7ImZ1bGxVcmwiOiJ1cm46dXVpZDo0NzYwMGUwZi1iNmI1LTQzMDgtODRiNS01ZGVjMTU3Zjc2MzciLCJyZXNvdXJjZSI6eyJjbGluaWNhbFN0YXR1cyI6eyJjb2RpbmciOlt7ImNvZGUiOiJhY3RpdmUiLCJkaXNwbGF5IjoiQWN0aXZlIiwic3lzdGVtIjoiaHR0cDovL3Rlcm1pbm9sb2d5LmhsNy5vcmcvQ29kZVN5c3RlbS9hbGxlcmd5aW50b2xlcmFuY2UtY2xpbmljYWwifV19LCJjb2RlIjp7InRleHQiOiJEb3h5Y3ljbGluZSJ9LCJjcml0aWNhbGl0eSI6ImhpZ2giLCJtZXRhIjp7Imxhc3RVcGRhdGVkIjoiMjAxMy0wNS0wNVQxNjoxMzowM1oifSwicGF0aWVudCI6eyJkaXNwbGF5IjoiRXZlIEV2ZXJ5d29tYW4iLCJyZWZlcmVuY2UiOiJodHRwOi8vZmhpci5oZWFsdGhpbnRlcnNlY3Rpb25zLmNvbS5hdS9vcGVuL1BhdGllbnQvZDEifSwicmVhY3Rpb24iOlt7Im1hbmlmZXN0YXRpb24iOlt7ImNvZGluZyI6W3siY29kZSI6Inh4eCIsImRpc3BsYXkiOiJIaXZlcyIsInN5c3RlbSI6Imh0dHA6Ly9leGFtcGxlLm9yZy9zeXN0ZW0ifV0sInRleHQiOiJIaXZlcyJ9XX1dLCJyZWNvcmRlZERhdGUiOiIyMDEyLTA5LTE3IiwicmVzb3VyY2VUeXBlIjoiQWxsZXJneUludG9sZXJhbmNlIiwidGV4dCI6eyJkaXYiOiI8ZGl2IHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiPlNlbnNpdGl2aXR5IHRvIERveHljeWNsaW5lIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIEhpdmVzPC9kaXY-Iiwic3RhdHVzIjoiZ2VuZXJhdGVkIn0sInR5cGUiOiJhbGxlcmd5IiwidmVyaWZpY2F0aW9uU3RhdHVzIjp7ImNvZGluZyI6W3siY29kZSI6ImNvbmZpcm1lZCIsImRpc3BsYXkiOiJDb25maXJtZWQiLCJzeXN0ZW0iOiJodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2FsbGVyZ3lpbnRvbGVyYW5jZS12ZXJpZmljYXRpb24ifV19fX1dLCJpZGVudGlmaWVyIjp7InN5c3RlbSI6InVybjppZXRmOnJmYzozOTg2IiwidmFsdWUiOiJ1cm46dXVpZDowYzMxNTFiZC0xY2JmLTRkNjQtYjA0ZC1jZDkxODdhNGM2ZTAifSwicmVzb3VyY2VUeXBlIjoiQnVuZGxlIiwidGltZXN0YW1wIjoiMjAxMy0wNS0yOFQyMjoxMjoyMVoiLCJ0eXBlIjoiZG9jdW1lbnQifQ.d420r0Y5pi--OkImCihlzP4_8PwPZiEQr4Py2rdDtAwnl_NaE5H1nqzvnmjSM3JHnhHQjHsx0Y9lcXHisfTmJyBiMbhHCo2pdGyLzE6km7MbY-I629yKG-D5sKhQevIXnTegWG7xzY3CB9GQ33IADqMDfG-vH77mgGlcBM9XTI_YbG6FeFjwFwLg2zv13BV727wu6EjC6xOHtbCsnKSqRvaxSYYR0Yh24ocfbniQbXxDVSgtQp5iVR7PRGo_oI4Alpz3APTrcZaEMur9Uhh6o50FXnE3e9i2C9M8pNHrcwxJ7VWguPbwPcttWtdoQapJEd0ftuXEpZxsgkwih3HfPAt7Vo8kVlRDH3IkCAA5X6qKec1HShXDZuBIj0SVUBGH1l2TOoEBwogXheL90lujz4ARzZlw_K3kBMmRMttunp7c-jYbgnmTipMLAn0yhR9AlJgT1UxgaiLNZu2mzFn0vRNE69OyrnQsFwLxVBXBqBv74rZcOld99RrtCDTGGziQ'" ] }, "execution_count": 224, "metadata": {}, "output_type": "execute_result" } ], "source": [ "recd_jws" ] }, { "cell_type": "code", "execution_count": 225, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'-----BEGIN PUBLIC KEY-----\\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA6SnEpKADOrFttfr1k3iF\\nThsddDFmrEMu1R4nes8qlwATPs53wZ13p8lNI9RU7z5kXzg6Dg11bj1MA6JoQh4f\\nm3JVvSjNqOet3MUShLwZ2h67I8OcjZsTuWIxEW4bR3UHqpLXcN1WBEUfR6MSztxZ\\nLM0dvdh0weMVt8lpVd4E5DEKMz0nCSh92xvD6qugGDyewuGASJVEnQTFZd6p3hH4\\nO37sYhX16H3U1Zu6zIohu1/c+Nz34pamnorH5rUcQJUcBDV6x9zrzgz8i9K05xvA\\nrGwF2FSDJnXR3uGRfaZYfebI+KTE4S7XCV/6PVxy44exJmcoCR1hEKuD8BcGXZm3\\nH4Qpjq/PB/AW1K7v+1es27BtTdQlpZ3ZW1c5y/tyDDq/JF2h3Gp6n3JIBVeBK534\\nxSatTiGgJrDI/OcTJI8ly8nCy/7uZ9qOgYPd/1EX6rjqEiBjgkduQ2mc6cNpN7O6\\nBPXTMBFl7X14GLYdm5Y8ubRR9Bo6TpMdO4+2U+R58Z5bAgMBAAE=\\n-----END PUBLIC KEY-----\\n'" ] }, "execution_count": 225, "metadata": {}, "output_type": "execute_result" } ], "source": [ "!openssl x509 -in recd_cert.der -inform DER -pubkey -noout > recd-public-key.pem\n", "with open('recd-public-key.pem') as f:\n", " pem_public = f.read()\n", "pem_public" ] }, { "cell_type": "code", "execution_count": 226, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "# # ### \n", "# # ###### ##### # ###### # ###### ##### ### \n", "# # # # # # # # # # # ### \n", "# # ##### # # # ##### # ##### # # # \n", " # # # ##### # # # # # # \n", " # # # # # # # # # # # ### \n", " # ###### # # # # # ###### ##### ### \n", " \n" ] } ], "source": [ "try:\n", " verify = jws.verify(recd_jws, pem_public , algorithms=['RS256'])\n", " print('# # ### ')\n", " print('# # ###### ##### # ###### # ###### ##### ### ')\n", " print('# # # # # # # # # # # ### ')\n", " print('# # ##### # # # ##### # ##### # # # ')\n", " print(' # # # ##### # # # # # # ')\n", " print(' # # # # # # # # # # # ### ')\n", " print(' # ###### # # # # # ###### ##### ### ')\n", " print(' ')\n", "\n", "except Exception as e:\n", " print('# # #### ##### # # ###### ##### # ###### # ###### ##### ### # ')\n", " print('## # # # # # # # # # # # # # # # # # ')\n", " print('# # # # # # # # ##### # # # ##### # ##### # # ##### # ')\n", " print('# # # # # # # # # ##### # # # # # # # # ')\n", " print('# ## # # # # # # # # # # # # # # ### # ')\n", " print('# # #### # ## ###### # # # # # ###### ##### # ## ')\n", " print(' ')\n", " print(f\"not verified: {e}\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.7.3 64-bit ('venv37': venv)", "language": "python", "name": "python37364bitvenv37venv2b400d68decb43d5b2206c004a019450" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" } }, "nbformat": 4, "nbformat_minor": 4 }