Da Vinci Clinical Data Exchange (CDex), published by HL7 International / Payer/Provider Information Exchange Work Group. This guide is not an authorized publication; it is the continuous build for version 2.1.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/HL7/davinci-ecdx/ and changes regularly. See the Directory of published versions
Page standards status: Informative |
This is a Jupyter Notebook which uses openSSL, Python 3.7, and the Python jcs and jose libraries to create a JSON Web Signature (JWS)(see RFC 7515), attach it to a FHIR Bundle and validate it. Its source code be found here
Although self-signed certificates are used for the purpose of these examples, they are not recommended for production systems.
1. Generate RSA256 public and private keys for signing the bundle
DO THIS STEP ONLY ONCE
2. Create a self-signed certificate for authenticating the signer
create the public and private keys and X.509 self-signed certificate for authenticating the signer using the openSSL command line tool.
[req]
default_bit = 4096
distinguished_name = req_distinguished_name
prompt = no
x509_extensions = v3_ca
# Subject details
[req_distinguished_name]
countryName = US
stateOrProvinceName = Massachusetts
localityName = Boston
organizationName = Example Organization
commonName = CDEX Example Organization
emailAddress = customer-service@example.org
[v3_ca]
basicConstraints = CA:FALSE
keyUsage=nonRepudiation, digitalSignature, keyEncipherment
# 1.2.840.113549.1.9.16.2.47 = ASN1:SEQUENCE:commitment_type # custom extensio
# SAN extension
subjectAltName = @alt_names
# SAN entries for FHIR and NPI
[alt_names]
DNS.1 = www.example.org
otherName.1 = 2.16.840.1.113883.4.6;UTF8:1234567893
URI.1 = https://example.org/fhir/Organization/123
2. generate the public and private keys and cert
!openssl genrsa -out private-key.pem 3072
!openssl rsa -in private-key.pem -pubout -out public-key.pem
!openssl req -new -x509 -key private-key.pem -outform DER -out cert.der -days 360 -config cert.config
writing RSA key
For the purpose of this example display the keys (normally would never share the private key)
!cat private-key.pem
!echo
!cat public-key.pem
-----BEGIN PRIVATE KEY----- MIIG/wIBADANBgkqhkiG9w0BAQEFAASCBukwggblAgEAAoIBgQCu3Ich4SabUyLa JHuVFb00/EDJL0GHw/ETVsUo9tGjUFZ0ViiwMAMxzF2H2O7JyyKEUSb+32dwF4F4 sjVS7MRv8r4VbVomd+T5pnMDbWmDXPStGPuJKGkrDx/RqKHNpOJoE6VKxyhgNZ4H Lul7lD94vtVG6qCVmFWTtktKnDzFtVOgU9jLYiHnrCZ3jH7Dgj0NIKyaIQTXC1a5 m15WWB5x8yxj9fOjMcFOSTgWuHw/GP/eS9hNhTnaOxzMAgsOWlQriBrtcYyjbdCi 5d0VdYjwozpd85FYKpZT7ZXgH0yeOMbyOs744IMdAcmoHGuQxhb4aRuEGrxg6eBB Af+1nwKPy9/RlcRCi7QtaahU19li6oIYMnkiDSUAOab6UHC1J4z0+mOrR9Vfj+77 6ijfotiKfA2gECbetCUE0jkxTBU6uu86GJZ1i9hKPd/AKRvVooGh8Wo8yvf+dL7d U4uAanu/tq0JN9Ybt/F/kTy+HbvLWOrcU8o9jTSs3CzpXdBm41cCAwEAAQKCAYBJ JUG3x92k8sFs+/7gLdBQdkbJgaWJW8sf+leOG7U0+jm3/4SUsvjbH3Buj63PptQh AmtsCVrVFlgX+3/32MgRRjsCbpRb7CJR1jFdWSregwds0zsBNHDNzM1UIBTTF6qH u9QUdDvtBvC8c4DCq5Bje3xu5l3XRfpiSEq1gqafU4sQUZKp/TpOlYIf1xr9wKC2 OZlJ/g7uv7T+/kGXn9PYec7zX6KTfRAuJc27H2AF6vi5bgOk5dp98eVJZ39leR3z kfuAB3lAvLbWVbMhx0piXQ7z4T4xRaKGyJ6plk6nyONhp4qIz84l6mfVhrzr1SET fdXetyUxzgHLd+lIPD4Ggx6B22u3h+0TXe12vzJYTOJASyslq0XGoqK/bl/ruplw z5EirSAV2XInZPGjCuL82KfKOZxy1iQUhV1htfowYB26wQTlQyGfB+0U5QO5YgS7 2psK0ScX5Wzo6tfC1rtN9wJpSnm/USKWtVObth4iYlshnvvIGh8fi6Zuo0XyKbUC gcEA6fTarXF2/Dt8UmkAXsrnmapO4xk5kbBHakYYkYkVBVf2D1uRrsdhCc01PSz6 q06qyvkei5PqGujOwDYYcMQ+1ZGbphdxCTXZR614NXS6fYgpEA11YEH0Wa1eR5i8 lmAvGfwOZWt9BVNPLaD45pXMOwm31Hh49z0NjfcJb8K5uxf7k1EofyjXnPgkm6Fq u92QAFLx9gwIC6/3t2Dw4SZ7tnIbCZs2s748swlibynxrSfVXM21pChAhDcm7Ej1 sUT7AoHBAL9WRboJLWJM27d8pc9sMHkajYUwOZSRLeAMcvjwE1+tVodECIotiYtG RLxzqPUF+XxLSALxdEpVzmZLAJQdxvTAwPb9kzRe7kRAOwq60Z5QcjSrZT+gLKsx zHQpDRaWzCYb+ju2YOgMyPXdV1Lm9SUbMfYa8GRgMzTSeZi0+NjrjzKko5Mc5dQG cNrcVguqnl1NhMMb8iM87vGxn3xQJwHMkTYWOS8DkqagxfSi82k+CSrYNc4FLzwf E9pf2Rg0VQKBwQCxAcAxWZdcXuVAtJDDJ2DyshfdWkhkIarmjQIpmj19PX+9PtqK Ee8pK0kMb+t3kJ1H1BN4JwEIOvuyETuMle20R+YrU7EB9uvdfzFjwF0YfNwUeRpF KaFl9/VM1hJY84yvbDS4Jwr/7HgLXa7zRoKuaDvdVQiwhlCrCCzrkbhUBWEhpFWv X4dCC7wmw4mteYRpule2gIPV09znsUCOGD+hWdN7ASPx+gySqJcA5Aslpu2WuUyk Vo/5eIDKZKj+5eECgcEAmVPjUG+mRM3ejK2AmjXSqlmS6xZ4LgwhPRf80mxguh1H 5+GnDkProwZOcs4kqSV+hhI1xNYFIMSeP+7+qbMrClukxsjxu9gPC/aE2dZXwIwq 2PY4jsImyZGAi92RtXZmZmupHUzLX2lPaWdUYQTfkjq20MdJuMY2gq/f7XWorPwn pqe0xWE087GtolVLRtIVUiOarleotIBR4rE6Yv5AI/rwqu0oKfqs/IZ928rxUHb8 Fa9pfo09CurEmAyTBgh5AoHBAL1DOIEpT0a2DCGREJrR8GwqkqpW9tiYOmc/6KQV VJ44pRd8g9xRYvReg8fnpnj2vNr8TK6OhH13CMscO1GWOydW3Fn7VqK5J9/5imkM fVHJ9la+Fh2uGCbsqK+etmaRTf+O43b8rfQtJx0HuOKugAGG7tkj4YCDB2zsP2HS l7btElZnlqgZtl0tVmT0FxLgMeLIZbtC/8+ecVWWlgsZk6q/ckeIA0TXoDQuZ/5F 2q/lprgQWdm+cxzJBhU7fD7eGQ== -----END PRIVATE KEY----- -----BEGIN PUBLIC KEY----- MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEArtyHIeEmm1Mi2iR7lRW9 NPxAyS9Bh8PxE1bFKPbRo1BWdFYosDADMcxdh9juycsihFEm/t9ncBeBeLI1UuzE b/K+FW1aJnfk+aZzA21pg1z0rRj7iShpKw8f0aihzaTiaBOlSscoYDWeBy7pe5Q/ eL7VRuqglZhVk7ZLSpw8xbVToFPYy2Ih56wmd4x+w4I9DSCsmiEE1wtWuZteVlge cfMsY/XzozHBTkk4Frh8Pxj/3kvYTYU52jsczAILDlpUK4ga7XGMo23QouXdFXWI 8KM6XfORWCqWU+2V4B9MnjjG8jrO+OCDHQHJqBxrkMYW+GkbhBq8YOngQQH/tZ8C j8vf0ZXEQou0LWmoVNfZYuqCGDJ5Ig0lADmm+lBwtSeM9Ppjq0fVX4/u++oo36LY inwNoBAm3rQlBNI5MUwVOrrvOhiWdYvYSj3fwCkb1aKBofFqPMr3/nS+3VOLgGp7 v7atCTfWG7fxf5E8vh27y1jq3FPKPY00rNws6V3QZuNXAgMBAAE= -----END PUBLIC KEY-----
Display DER Format of Certificate
!openssl x509 -in cert.der -inform DER -text
Certificate: Data: Version: 3 (0x2) Serial Number: 39:c1:6a:2c:e0:66:b7:b5:51:eb:2e:05:1a:7d:34:41:21:4c:5c:98 Signature Algorithm: sha256WithRSAEncryption Issuer: C=US, ST=Massachusetts, L=Boston, O=Example Organization, CN=CDEX Example Organization, emailAddress=customer-service@example.org Validity Not Before: Jul 24 18:14:40 2025 GMT Not After : Jul 19 18:14:40 2026 GMT Subject: C=US, ST=Massachusetts, L=Boston, O=Example Organization, CN=CDEX Example Organization, emailAddress=customer-service@example.org Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (3072 bit) Modulus: 00:ae:dc:87:21:e1:26:9b:53:22:da:24:7b:95:15: bd:34:fc:40:c9:2f:41:87:c3:f1:13:56:c5:28:f6: d1:a3:50:56:74:56:28:b0:30:03:31:cc:5d:87:d8: ee:c9:cb:22:84:51:26:fe:df:67:70:17:81:78:b2: 35:52:ec:c4:6f:f2:be:15:6d:5a:26:77:e4:f9:a6: 73:03:6d:69:83:5c:f4:ad:18:fb:89:28:69:2b:0f: 1f:d1:a8:a1:cd:a4:e2:68:13:a5:4a:c7:28:60:35: 9e:07:2e:e9:7b:94:3f:78:be:d5:46:ea:a0:95:98: 55:93:b6:4b:4a:9c:3c:c5:b5:53:a0:53:d8:cb:62: 21:e7:ac:26:77:8c:7e:c3:82:3d:0d:20:ac:9a:21: 04:d7:0b:56:b9:9b:5e:56:58:1e:71:f3:2c:63:f5: f3:a3:31:c1:4e:49:38:16:b8:7c:3f:18:ff:de:4b: d8:4d:85:39:da:3b:1c:cc:02:0b:0e:5a:54:2b:88: 1a:ed:71:8c:a3:6d:d0:a2:e5:dd:15:75:88:f0:a3: 3a:5d:f3:91:58:2a:96:53:ed:95:e0:1f:4c:9e:38: c6:f2:3a:ce:f8:e0:83:1d:01:c9:a8:1c:6b:90:c6: 16:f8:69:1b:84:1a:bc:60:e9:e0:41:01:ff:b5:9f: 02:8f:cb:df:d1:95:c4:42:8b:b4:2d:69:a8:54:d7: d9:62:ea:82:18:32:79:22:0d:25:00:39:a6:fa:50: 70:b5:27:8c:f4:fa:63:ab:47:d5:5f:8f:ee:fb:ea: 28:df:a2:d8:8a:7c:0d:a0:10:26:de:b4:25:04:d2: 39:31:4c:15:3a:ba:ef:3a:18:96:75:8b:d8:4a:3d: df:c0:29:1b:d5:a2:81:a1:f1:6a:3c:ca:f7:fe:74: be:dd:53:8b:80:6a:7b:bf:b6:ad:09:37:d6:1b:b7: f1:7f:91:3c:be:1d:bb:cb:58:ea:dc:53:ca:3d:8d: 34:ac:dc:2c:e9:5d:d0:66:e3:57 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Alternative Name: DNS:www.example.org, othername: 2.16.840.1.113883.4.6:1234567893, URI:https://example.org/fhir/Organization/123 X509v3 Subject Key Identifier: E6:EF:DB:35:0B:69:B3:69:A4:3A:E6:01:54:E1:7F:39:AC:75:EB:58 Signature Algorithm: sha256WithRSAEncryption Signature Value: 18:8b:39:4d:fd:34:4c:92:cd:94:86:cf:66:8d:85:b3:33:51: 5e:51:69:3c:2b:a4:3c:43:bd:88:c3:5f:78:c4:3f:f8:ec:9a: 3e:3f:a4:df:8b:e5:16:01:5e:c0:5f:63:14:94:b9:b4:0b:79: 5b:e4:7f:97:ef:fa:81:ab:99:e0:96:f9:f5:fc:c8:4d:6b:97: ea:bc:d4:20:8b:f9:0f:0b:38:ec:c0:64:5b:84:79:81:3d:89: e7:33:63:b7:ce:d7:c3:29:17:c9:c2:d7:80:83:41:be:83:37: 5d:10:68:0b:5b:85:31:5a:91:97:8e:a9:96:94:81:3a:03:7c: 83:6c:9f:b8:f3:6b:f6:e9:b7:52:9e:bb:9b:d4:b2:ed:6a:16: 08:c0:a7:30:3a:f8:c6:a5:20:d5:24:1e:66:b6:14:af:b3:d9: 87:f2:d1:6f:cd:86:ea:5b:2d:c5:84:9f:54:72:b9:40:53:43: 0b:2c:9b:dc:11:3c:31:3f:2e:84:94:03:7a:66:9a:a3:c3:97: ce:dd:f6:d1:85:0c:af:f2:95:04:ee:6a:a9:79:b4:5d:36:96: 3c:fc:c1:84:22:49:17:f9:9f:3c:6a:4e:6b:67:30:29:af:87: 26:b1:ef:99:f9:d2:da:3f:4e:7e:25:87:f8:f5:8a:4a:3e:c0: 20:16:4c:c0:8d:91:bf:a6:e0:6d:66:b1:da:14:62:71:18:9f: f4:e2:cd:6f:6f:2b:72:e1:55:35:b9:65:d2:3e:b9:5c:9a:b1: d0:61:44:ba:32:97:06:22:75:41:82:6a:1b:c9:7c:34:86:93: 4c:52:ef:88:54:5d:bd:b6:dc:09:b3:89:22:84:dd:31:4f:c5: 29:d9:12:fd:f3:8b:c9:8e:93:3b:0c:4a:e6:e3:9e:92:6a:ae: 74:17:a0:19:cd:23:cb:3e:8f:42:32:65:0d:bd:66:67:7c:08: b2:ea:9a:09:08:39:53:ae:69:c0:a8:91:7b:ca:0d:69:14:9a: 40:72:44:ee:8b:c0 -----BEGIN CERTIFICATE----- MIIFeTCCA+GgAwIBAgIUOcFqLOBmt7VR6y4FGn00QSFMXJgwDQYJKoZIhvcNAQEL BQAwgaYxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMQ8wDQYD VQQHDAZCb3N0b24xHTAbBgNVBAoMFEV4YW1wbGUgT3JnYW5pemF0aW9uMSIwIAYD VQQDDBlDREVYIEV4YW1wbGUgT3JnYW5pemF0aW9uMSswKQYJKoZIhvcNAQkBFhxj dXN0b21lci1zZXJ2aWNlQGV4YW1wbGUub3JnMB4XDTI1MDcyNDE4MTQ0MFoXDTI2 MDcxOTE4MTQ0MFowgaYxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNl dHRzMQ8wDQYDVQQHDAZCb3N0b24xHTAbBgNVBAoMFEV4YW1wbGUgT3JnYW5pemF0 aW9uMSIwIAYDVQQDDBlDREVYIEV4YW1wbGUgT3JnYW5pemF0aW9uMSswKQYJKoZI hvcNAQkBFhxjdXN0b21lci1zZXJ2aWNlQGV4YW1wbGUub3JnMIIBojANBgkqhkiG 9w0BAQEFAAOCAY8AMIIBigKCAYEArtyHIeEmm1Mi2iR7lRW9NPxAyS9Bh8PxE1bF KPbRo1BWdFYosDADMcxdh9juycsihFEm/t9ncBeBeLI1UuzEb/K+FW1aJnfk+aZz A21pg1z0rRj7iShpKw8f0aihzaTiaBOlSscoYDWeBy7pe5Q/eL7VRuqglZhVk7ZL Spw8xbVToFPYy2Ih56wmd4x+w4I9DSCsmiEE1wtWuZteVlgecfMsY/XzozHBTkk4 Frh8Pxj/3kvYTYU52jsczAILDlpUK4ga7XGMo23QouXdFXWI8KM6XfORWCqWU+2V 4B9MnjjG8jrO+OCDHQHJqBxrkMYW+GkbhBq8YOngQQH/tZ8Cj8vf0ZXEQou0LWmo VNfZYuqCGDJ5Ig0lADmm+lBwtSeM9Ppjq0fVX4/u++oo36LYinwNoBAm3rQlBNI5 MUwVOrrvOhiWdYvYSj3fwCkb1aKBofFqPMr3/nS+3VOLgGp7v7atCTfWG7fxf5E8 vh27y1jq3FPKPY00rNws6V3QZuNXAgMBAAGjgZwwgZkwCQYDVR0TBAIwADALBgNV HQ8EBAMCBeAwYAYDVR0RBFkwV4IPd3d3LmV4YW1wbGUub3JnoBkGCWCGSAGG+VsE BqAMDAoxMjM0NTY3ODkzhilodHRwczovL2V4YW1wbGUub3JnL2ZoaXIvT3JnYW5p emF0aW9uLzEyMzAdBgNVHQ4EFgQU5u/bNQtps2mkOuYBVOF/Oax161gwDQYJKoZI hvcNAQELBQADggGBABiLOU39NEySzZSGz2aNhbMzUV5RaTwrpDxDvYjDX3jEP/js mj4/pN+L5RYBXsBfYxSUubQLeVvkf5fv+oGrmeCW+fX8yE1rl+q81CCL+Q8LOOzA ZFuEeYE9ieczY7fO18MpF8nC14CDQb6DN10QaAtbhTFakZeOqZaUgToDfINsn7jz a/bpt1Keu5vUsu1qFgjApzA6+MalINUkHma2FK+z2Yfy0W/NhupbLcWEn1RyuUBT Qwssm9wRPDE/LoSUA3pmmqPDl87d9tGFDK/ylQTuaql5tF02ljz8wYQiSRf5nzxq TmtnMCmvhyax75n50to/Tn4lh/j1iko+wCAWTMCNkb+m4G1msdoUYnEYn/TizW9v K3LhVTW5ZdI+uVyasdBhRLoylwYidUGCahvJfDSGk0xS74hUXb223AmziSKE3TFP xSnZEv3zi8mOkzsMSubjnpJqrnQXoBnNI8s+j0IyZQ29Zmd8CLLqmgkIOVOuacCo kXvKDWkUmkByRO6LwA== -----END CERTIFICATE-----
Display PEM Format of Certificate
!openssl x509 -in cert.der -inform DER -outform PEM -out cert.pem
!cat cert.pem
-----BEGIN CERTIFICATE----- MIIFeTCCA+GgAwIBAgIUOcFqLOBmt7VR6y4FGn00QSFMXJgwDQYJKoZIhvcNAQEL BQAwgaYxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMQ8wDQYD VQQHDAZCb3N0b24xHTAbBgNVBAoMFEV4YW1wbGUgT3JnYW5pemF0aW9uMSIwIAYD VQQDDBlDREVYIEV4YW1wbGUgT3JnYW5pemF0aW9uMSswKQYJKoZIhvcNAQkBFhxj dXN0b21lci1zZXJ2aWNlQGV4YW1wbGUub3JnMB4XDTI1MDcyNDE4MTQ0MFoXDTI2 MDcxOTE4MTQ0MFowgaYxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNl dHRzMQ8wDQYDVQQHDAZCb3N0b24xHTAbBgNVBAoMFEV4YW1wbGUgT3JnYW5pemF0 aW9uMSIwIAYDVQQDDBlDREVYIEV4YW1wbGUgT3JnYW5pemF0aW9uMSswKQYJKoZI hvcNAQkBFhxjdXN0b21lci1zZXJ2aWNlQGV4YW1wbGUub3JnMIIBojANBgkqhkiG 9w0BAQEFAAOCAY8AMIIBigKCAYEArtyHIeEmm1Mi2iR7lRW9NPxAyS9Bh8PxE1bF KPbRo1BWdFYosDADMcxdh9juycsihFEm/t9ncBeBeLI1UuzEb/K+FW1aJnfk+aZz A21pg1z0rRj7iShpKw8f0aihzaTiaBOlSscoYDWeBy7pe5Q/eL7VRuqglZhVk7ZL Spw8xbVToFPYy2Ih56wmd4x+w4I9DSCsmiEE1wtWuZteVlgecfMsY/XzozHBTkk4 Frh8Pxj/3kvYTYU52jsczAILDlpUK4ga7XGMo23QouXdFXWI8KM6XfORWCqWU+2V 4B9MnjjG8jrO+OCDHQHJqBxrkMYW+GkbhBq8YOngQQH/tZ8Cj8vf0ZXEQou0LWmo VNfZYuqCGDJ5Ig0lADmm+lBwtSeM9Ppjq0fVX4/u++oo36LYinwNoBAm3rQlBNI5 MUwVOrrvOhiWdYvYSj3fwCkb1aKBofFqPMr3/nS+3VOLgGp7v7atCTfWG7fxf5E8 vh27y1jq3FPKPY00rNws6V3QZuNXAgMBAAGjgZwwgZkwCQYDVR0TBAIwADALBgNV HQ8EBAMCBeAwYAYDVR0RBFkwV4IPd3d3LmV4YW1wbGUub3JnoBkGCWCGSAGG+VsE BqAMDAoxMjM0NTY3ODkzhilodHRwczovL2V4YW1wbGUub3JnL2ZoaXIvT3JnYW5p emF0aW9uLzEyMzAdBgNVHQ4EFgQU5u/bNQtps2mkOuYBVOF/Oax161gwDQYJKoZI hvcNAQELBQADggGBABiLOU39NEySzZSGz2aNhbMzUV5RaTwrpDxDvYjDX3jEP/js mj4/pN+L5RYBXsBfYxSUubQLeVvkf5fv+oGrmeCW+fX8yE1rl+q81CCL+Q8LOOzA ZFuEeYE9ieczY7fO18MpF8nC14CDQb6DN10QaAtbhTFakZeOqZaUgToDfINsn7jz a/bpt1Keu5vUsu1qFgjApzA6+MalINUkHma2FK+z2Yfy0W/NhupbLcWEn1RyuUBT Qwssm9wRPDE/LoSUA3pmmqPDl87d9tGFDK/ylQTuaql5tF02ljz8wYQiSRf5nzxq TmtnMCmvhyax75n50to/Tn4lh/j1iko+wCAWTMCNkb+m4G1msdoUYnEYn/TizW9v K3LhVTW5ZdI+uVyasdBhRLoylwYidUGCahvJfDSGk0xS74hUXb223AmziSKE3TFP xSnZEv3zi8mOkzsMSubjnpJqrnQXoBnNI8s+j0IyZQ29Zmd8CLLqmgkIOVOuacCo kXvKDWkUmkByRO6LwA== -----END CERTIFICATE-----
3. Create JWS to Attach to Bundle
3.1. Prepare Header
note the base64 DER is Cert PEM file wihout the footer and header and line returns
with open('cert.pem') as f:
der = (f.read()) # base64 DER is PEM wihout the footer and header and line returns
der = der.replace('-----BEGIN CERTIFICATE-----','')
der = der.replace('-----END CERTIFICATE-----','')
der = der.replace('\n','')
header = {
'alg': 'RS256',
'kty': 'RS',
'srCms': [{'commId': {'id': 'urn:oid:1.2.840.10065.1.12.1.5',
'desc': 'Verification Signature'},
'commQuals': ['Verification of medical record integrity']}],
'sigT': '2020-10-23T04:54:56.048+00:00',
'kid': 'bfbe3e5c0470444576548113928d5f1e4e3f2eeb',
'x5c': [der]
}
header
{'alg': 'RS256', 'kty': 'RS', 'srCms': [{'commId': {'id': 'urn:oid:1.2.840.10065.1.12.1.5', 'desc': 'Verification Signature'}, 'commQuals': ['Verification of medical record integrity']}], 'sigT': '2020-10-23T04:54:56.048+00:00', 'kid': 'bfbe3e5c0470444576548113928d5f1e4e3f2eeb', 'x5c': ['MIIFeTCCA+GgAwIBAgIUOcFqLOBmt7VR6y4FGn00QSFMXJgwDQYJKoZIhvcNAQELBQAwgaYxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMQ8wDQYDVQQHDAZCb3N0b24xHTAbBgNVBAoMFEV4YW1wbGUgT3JnYW5pemF0aW9uMSIwIAYDVQQDDBlDREVYIEV4YW1wbGUgT3JnYW5pemF0aW9uMSswKQYJKoZIhvcNAQkBFhxjdXN0b21lci1zZXJ2aWNlQGV4YW1wbGUub3JnMB4XDTI1MDcyNDE4MTQ0MFoXDTI2MDcxOTE4MTQ0MFowgaYxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMQ8wDQYDVQQHDAZCb3N0b24xHTAbBgNVBAoMFEV4YW1wbGUgT3JnYW5pemF0aW9uMSIwIAYDVQQDDBlDREVYIEV4YW1wbGUgT3JnYW5pemF0aW9uMSswKQYJKoZIhvcNAQkBFhxjdXN0b21lci1zZXJ2aWNlQGV4YW1wbGUub3JnMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEArtyHIeEmm1Mi2iR7lRW9NPxAyS9Bh8PxE1bFKPbRo1BWdFYosDADMcxdh9juycsihFEm/t9ncBeBeLI1UuzEb/K+FW1aJnfk+aZzA21pg1z0rRj7iShpKw8f0aihzaTiaBOlSscoYDWeBy7pe5Q/eL7VRuqglZhVk7ZLSpw8xbVToFPYy2Ih56wmd4x+w4I9DSCsmiEE1wtWuZteVlgecfMsY/XzozHBTkk4Frh8Pxj/3kvYTYU52jsczAILDlpUK4ga7XGMo23QouXdFXWI8KM6XfORWCqWU+2V4B9MnjjG8jrO+OCDHQHJqBxrkMYW+GkbhBq8YOngQQH/tZ8Cj8vf0ZXEQou0LWmoVNfZYuqCGDJ5Ig0lADmm+lBwtSeM9Ppjq0fVX4/u++oo36LYinwNoBAm3rQlBNI5MUwVOrrvOhiWdYvYSj3fwCkb1aKBofFqPMr3/nS+3VOLgGp7v7atCTfWG7fxf5E8vh27y1jq3FPKPY00rNws6V3QZuNXAgMBAAGjgZwwgZkwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwYAYDVR0RBFkwV4IPd3d3LmV4YW1wbGUub3JnoBkGCWCGSAGG+VsEBqAMDAoxMjM0NTY3ODkzhilodHRwczovL2V4YW1wbGUub3JnL2ZoaXIvT3JnYW5pemF0aW9uLzEyMzAdBgNVHQ4EFgQU5u/bNQtps2mkOuYBVOF/Oax161gwDQYJKoZIhvcNAQELBQADggGBABiLOU39NEySzZSGz2aNhbMzUV5RaTwrpDxDvYjDX3jEP/jsmj4/pN+L5RYBXsBfYxSUubQLeVvkf5fv+oGrmeCW+fX8yE1rl+q81CCL+Q8LOOzAZFuEeYE9ieczY7fO18MpF8nC14CDQb6DN10QaAtbhTFakZeOqZaUgToDfINsn7jza/bpt1Keu5vUsu1qFgjApzA6+MalINUkHma2FK+z2Yfy0W/NhupbLcWEn1RyuUBTQwssm9wRPDE/LoSUA3pmmqPDl87d9tGFDK/ylQTuaql5tF02ljz8wYQiSRf5nzxqTmtnMCmvhyax75n50to/Tn4lh/j1iko+wCAWTMCNkb+m4G1msdoUYnEYn/TizW9vK3LhVTW5ZdI+uVyasdBhRLoylwYidUGCahvJfDSGk0xS74hUXb223AmziSKE3TFPxSnZEv3zi8mOkzsMSubjnpJqrnQXoBnNI8s+j0IyZQ29Zmd8CLLqmgkIOVOuacCokXvKDWkUmkByRO6LwA==']}
3.2. Prepare Payload
The payload is the base64_url form of the canonicalized version of the searchset Bundle before attaching the signature
Canonicalize the bundle using IETF JSON Canonicalization Scheme (JCS) before adding the signature element:
from jcs import canonicalize #package for a JCS (RFC 8785) compliant canonicalizer.
from json import loads
searchset_bundle = r'''{
"resourceType" : "Bundle",
"id" : "cdex-searchbundle-digital-sig-example",
"type" : "searchset",
"total" : 1,
"link" : [{
"relation" : "self",
"url" : "http://hapi.fhir.org/baseR4/Condition?patient=06e1f0dd-5fbe-4480-9bb4-6b54ec02d31b"
}],
"entry" : [{
"fullUrl" : "http://hapi.fhir.org/baseR4/Condition/4ac41715-fcbd-421c-8796-9b2c9706dd3f",
"resource" : {
"resourceType" : "Condition",
"id" : "4ac41715-fcbd-421c-8796-9b2c9706dd3f",
"meta" : {
"versionId" : "10",
"lastUpdated" : "2020-04-28T20:28:00.008+00:00"
},
"text" : {
"status" : "generated",
"div" : "<div xmlns=\"http://www.w3.org/1999/xhtml\"><a name=\"Condition_4ac41715-fcbd-421c-8796-9b2c9706dd3f\"> </a><p class=\"res-header-id\"><b>Generated Narrative: Condition 4ac41715-fcbd-421c-8796-9b2c9706dd3f</b></p><a name=\"4ac41715-fcbd-421c-8796-9b2c9706dd3f\"> </a><a name=\"hc4ac41715-fcbd-421c-8796-9b2c9706dd3f\"> </a><a name=\"4ac41715-fcbd-421c-8796-9b2c9706dd3f-en-US\"> </a><div style=\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\"><p style=\"margin-bottom: 0px\">version: 10; Last updated: 2020-04-28 20:28:00+0000; </p><p style=\"margin-bottom: 0px\">Information Source: #cabiJIK51sD2iz4N</p></div><p><b>clinicalStatus</b>: <span title=\"Codes:{http://terminology.hl7.org/CodeSystem/condition-clinical active}\">Active</span></p><p><b>verificationStatus</b>: <span title=\"Codes:{http://terminology.hl7.org/CodeSystem/condition-ver-status confirmed}\">Confirmed</span></p><p><b>category</b>: <span title=\"Codes:{http://terminology.hl7.org/CodeSystem/condition-category encounter-diagnosis}\">Encounter Diagnosis</span></p><p><b>code</b>: <span title=\"Codes:{http://snomed.info/sct 122481008}\">Hammer Toe</span></p><p><b>subject</b>: <a href=\"http://example.org/cdex/provider/fhir/Patient/06e1f0dd-5fbe-4480-9bb4-6b54ec02d31b\">http://example.org/cdex/provider/fhir/Patient/06e1f0dd-5fbe-4480-9bb4-6b54ec02d31b</a></p><p><b>encounter</b>: <a href=\"http://example.org/cdex/provider/fhir/Encounter/5fe62cd5-bfcf-4d3b-a1e9-80d6f75d6f82\">http://example.org/cdex/provider/fhir/Encounter/5fe62cd5-bfcf-4d3b-a1e9-80d6f75d6f82</a></p><p><b>onset</b>: 2018-10-21 21:22:15-0700</p><p><b>recordedDate</b>: 2018-10-21 21:22:15-0700</p></div>"
},
"clinicalStatus" : {
"coding" : [{
"system" : "http://terminology.hl7.org/CodeSystem/condition-clinical",
"code" : "active"
}]
},
"verificationStatus" : {
"coding" : [{
"system" : "http://terminology.hl7.org/CodeSystem/condition-ver-status",
"code" : "confirmed"
}]
},
"category" : [{
"coding" : [{
"system" : "http://terminology.hl7.org/CodeSystem/condition-category",
"code" : "encounter-diagnosis",
"display" : "Encounter Diagnosis"
}]
}],
"code" : {
"coding" : [{
"system" : "http://snomed.info/sct",
"code" : "122481008",
"display" : "Hammer toe (disorder)"
}],
"text" : "Hammer Toe"
},
"subject" : {
"reference" : "http://example.org/cdex/provider/fhir/Patient/06e1f0dd-5fbe-4480-9bb4-6b54ec02d31b"
},
"encounter" : {
"reference" : "http://example.org/cdex/provider/fhir/Encounter/5fe62cd5-bfcf-4d3b-a1e9-80d6f75d6f82"
},
"onsetDateTime" : "2018-10-21T21:22:15-07:00",
"recordedDate" : "2018-10-21T21:22:15-07:00"
},
"search" : {
"mode" : "match"
}
}]
}
'''
searchset_bundle = loads(searchset_bundle) #convert to Python object
searchset_bundle_id = searchset_bundle.pop("id", None) # remove id
searchset_bundle_meta = searchset_bundle.pop("meta", None) # remove meta
payload = canonicalize(searchset_bundle)
payload
<![CDATA[ b'{"entry":[{"fullUrl":"http://hapi.fhir.org/baseR4/Condition/4ac41715-fcbd-421c-8796-9b2c9706dd3f","resource":{"category":[{"coding":[{"code":"encounter-diagnosis","display":"Encounter Diagnosis","system":"http://terminology.hl7.org/CodeSystem/condition-category"}]}],"clinicalStatus":{"coding":[{"code":"active","system":"http://terminology.hl7.org/CodeSystem/condition-clinical"}]},"code":{"coding":[{"code":"122481008","display":"Hammer toe (disorder)","system":"http://snomed.info/sct"}],"text":"Hammer Toe"},"encounter":{"reference":"http://example.org/cdex/provider/fhir/Encounter/5fe62cd5-bfcf-4d3b-a1e9-80d6f75d6f82"},"id":"4ac41715-fcbd-421c-8796-9b2c9706dd3f","meta":{"lastUpdated":"2020-04-28T20:28:00.008+00:00","versionId":"10"},"onsetDateTime":"2018-10-21T21:22:15-07:00","recordedDate":"2018-10-21T21:22:15-07:00","resourceType":"Condition","subject":{"reference":"http://example.org/cdex/provider/fhir/Patient/06e1f0dd-5fbe-4480-9bb4-6b54ec02d31b"},"text":{"div":"<div xmlns=\\"http://www.w3.org/1999/xhtml\\"><a name=\\"Condition_4ac41715-fcbd-421c-8796-9b2c9706dd3f\\"> </a><p class=\\"res-header-id\\">Generated Narrative: Condition 4ac41715-fcbd-421c-8796-9b2c9706dd3f</p><a name=\\"4ac41715-fcbd-421c-8796-9b2c9706dd3f\\"> </a><a name=\\"hc4ac41715-fcbd-421c-8796-9b2c9706dd3f\\"> </a><a name=\\"4ac41715-fcbd-421c-8796-9b2c9706dd3f-en-US\\"> </a><div style=\\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\\"><p style=\\"margin-bottom: 0px\\">version: 10; Last updated: 2020-04-28 20:28:00+0000; </p><p style=\\"margin-bottom: 0px\\">Information Source: #cabiJIK51sD2iz4N</p></div>clinicalStatus: <span title=\\"Codes:{http://terminology.hl7.org/CodeSystem/condition-clinical active}\\">Active</span>
verificationStatus: <span title=\\"Codes:{http://terminology.hl7.org/CodeSystem/condition-ver-status confirmed}\\">Confirmed</span>
category: <span title=\\"Codes:{http://terminology.hl7.org/CodeSystem/condition-category encounter-diagnosis}\\">Encounter Diagnosis</span>
code: <span title=\\"Codes:{http://snomed.info/sct 122481008}\\">Hammer Toe</span>
subject: <a href=\\"http://example.org/cdex/provider/fhir/Patient/06e1f0dd-5fbe-4480-9bb4-6b54ec02d31b\\">http://example.org/cdex/provider/fhir/Patient/06e1f0dd-5fbe-4480-9bb4-6b54ec02d31b</a>
encounter: <a href=\\"http://example.org/cdex/provider/fhir/Encounter/5fe62cd5-bfcf-4d3b-a1e9-80d6f75d6f82\\">http://example.org/cdex/provider/fhir/Encounter/5fe62cd5-bfcf-4d3b-a1e9-80d6f75d6f82</a>
onset: 2018-10-21 21:22:15-0700
recordedDate: 2018-10-21 21:22:15-0700
</div>","status":"generated"},"verificationStatus":{"coding":[{"code":"confirmed","system":"http://terminology.hl7.org/CodeSystem/condition-ver-status"}]}},"search":{"mode":"match"}}],"link":[{"relation":"self","url":"http://hapi.fhir.org/baseR4/Condition?patient=06e1f0dd-5fbe-4480-9bb4-6b54ec02d31b"}],"resourceType":"Bundle","total":1,"type":"searchset"}' ]]>
3.3 Create Signature using private key and the RS256 algorithm to get the JWS compact serialization format
note the signature is displayed with the parts labeled and separated with line breaks for easier viewing.
from jose import jws
with open('private-key.pem') as f:
private_key = (f.read())
signature = jws.sign(payload,private_key,algorithm='RS256',headers=header)
labels = ['header', 'payload', 'signature']
for i,j in enumerate(signature.split('.')):
print(f'{labels[i]}:')
print(f'{j}')
print()
header: eyJhbGciOiJSUzI1NiIsImtpZCI6ImJmYmUzZTVjMDQ3MDQ0NDU3NjU0ODExMzkyOGQ1ZjFlNGUzZjJlZWIiLCJrdHkiOiJSUyIsInNpZ1QiOiIyMDIwLTEwLTIzVDA0OjU0OjU2LjA0OCswMDowMCIsInNyQ21zIjpbeyJjb21tSWQiOnsiZGVzYyI6IlZlcmlmaWNhdGlvbiBTaWduYXR1cmUiLCJpZCI6InVybjpvaWQ6MS4yLjg0MC4xMDA2NS4xLjEyLjEuNSJ9LCJjb21tUXVhbHMiOlsiVmVyaWZpY2F0aW9uIG9mIG1lZGljYWwgcmVjb3JkIGludGVncml0eSJdfV0sInR5cCI6IkpXVCIsIng1YyI6WyJNSUlGZVRDQ0ErR2dBd0lCQWdJVU9jRnFMT0JtdDdWUjZ5NEZHbjAwUVNGTVhKZ3dEUVlKS29aSWh2Y05BUUVMQlFBd2dhWXhDekFKQmdOVkJBWVRBbFZUTVJZd0ZBWURWUVFJREExTllYTnpZV05vZFhObGRIUnpNUTh3RFFZRFZRUUhEQVpDYjNOMGIyNHhIVEFiQmdOVkJBb01GRVY0WVcxd2JHVWdUM0puWVc1cGVtRjBhVzl1TVNJd0lBWURWUVFEREJsRFJFVllJRVY0WVcxd2JHVWdUM0puWVc1cGVtRjBhVzl1TVNzd0tRWUpLb1pJaHZjTkFRa0JGaHhqZFhOMGIyMWxjaTF6WlhKMmFXTmxRR1Y0WVcxd2JHVXViM0puTUI0WERUSTFNRGN5TkRFNE1UUTBNRm9YRFRJMk1EY3hPVEU0TVRRME1Gb3dnYVl4Q3pBSkJnTlZCQVlUQWxWVE1SWXdGQVlEVlFRSURBMU5ZWE56WVdOb2RYTmxkSFJ6TVE4d0RRWURWUVFIREFaQ2IzTjBiMjR4SFRBYkJnTlZCQW9NRkVWNFlXMXdiR1VnVDNKbllXNXBlbUYwYVc5dU1TSXdJQVlEVlFRRERCbERSRVZZSUVWNFlXMXdiR1VnVDNKbllXNXBlbUYwYVc5dU1Tc3dLUVlKS29aSWh2Y05BUWtCRmh4amRYTjBiMjFsY2kxelpYSjJhV05sUUdWNFlXMXdiR1V1YjNKbk1JSUJvakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBWThBTUlJQmlnS0NBWUVBcnR5SEllRW1tMU1pMmlSN2xSVzlOUHhBeVM5Qmg4UHhFMWJGS1BiUm8xQldkRllvc0RBRE1jeGRoOWp1eWNzaWhGRW0vdDluY0JlQmVMSTFVdXpFYi9LK0ZXMWFKbmZrK2FaekEyMXBnMXowclJqN2lTaHBLdzhmMGFpaHphVGlhQk9sU3Njb1lEV2VCeTdwZTVRL2VMN1ZSdXFnbFpoVms3WkxTcHc4eGJWVG9GUFl5MkloNTZ3bWQ0eCt3NEk5RFNDc21pRUUxd3RXdVp0ZVZsZ2VjZk1zWS9Yem96SEJUa2s0RnJoOFB4ai8za3ZZVFlVNTJqc2N6QUlMRGxwVUs0Z2E3WEdNbzIzUW91WGRGWFdJOEtNNlhmT1JXQ3FXVSsyVjRCOU1uampHOGpyTytPQ0RIUUhKcUJ4cmtNWVcrR2tiaEJxOFlPbmdRUUgvdFo4Q2o4dmYwWlhFUW91MExXbW9WTmZaWXVxQ0dESjVJZzBsQURtbStsQnd0U2VNOVBwanEwZlZYNC91KytvbzM2TFlpbndOb0JBbTNyUWxCTkk1TVV3Vk9ycnZPaGlXZFl2WVNqM2Z3Q2tiMWFLQm9mRnFQTXIzL25TKzNWT0xnR3A3djdhdENUZldHN2Z4ZjVFOHZoMjd5MWpxM0ZQS1BZMDByTndzNlYzUVp1TlhBZ01CQUFHamdad3dnWmt3Q1FZRFZSMFRCQUl3QURBTEJnTlZIUThFQkFNQ0JlQXdZQVlEVlIwUkJGa3dWNElQZDNkM0xtVjRZVzF3YkdVdWIzSm5vQmtHQ1dDR1NBR0crVnNFQnFBTURBb3hNak0wTlRZM09Ea3poaWxvZEhSd2N6b3ZMMlY0WVcxd2JHVXViM0puTDJab2FYSXZUM0puWVc1cGVtRjBhVzl1THpFeU16QWRCZ05WSFE0RUZnUVU1dS9iTlF0cHMybWtPdVlCVk9GL09heDE2MWd3RFFZSktvWklodmNOQVFFTEJRQURnZ0dCQUJpTE9VMzlORXlTelpTR3oyYU5oYk16VVY1UmFUd3JwRHhEdllqRFgzakVQL2pzbWo0L3BOK0w1UllCWHNCZll4U1V1YlFMZVZ2a2Y1ZnYrb0dybWVDVytmWDh5RTFybCtxODFDQ0wrUThMT096QVpGdUVlWUU5aWVjelk3Zk8xOE1wRjhuQzE0Q0RRYjZETjEwUWFBdGJoVEZha1plT3FaYVVnVG9EZklOc243anphL2JwdDFLZXU1dlVzdTFxRmdqQXB6QTYrTWFsSU5Va0htYTJGSyt6MllmeTBXL05odXBiTGNXRW4xUnl1VUJUUXdzc205d1JQREUvTG9TVUEzcG1tcVBEbDg3ZDl0R0ZESy95bFFUdWFxbDV0RjAybGp6OHdZUWlTUmY1bnp4cVRtdG5NQ212aHlheDc1bjUwdG8vVG40bGgvajFpa28rd0NBV1RNQ05rYittNEcxbXNkb1VZbkVZbi9UaXpXOXZLM0xoVlRXNVpkSSt1Vnlhc2RCaFJMb3lsd1lpZFVHQ2FodkpmRFNHazB4Uzc0aFVYYjIyM0FtemlTS0UzVEZQeFNuWkV2M3ppOG1Pa3pzTVN1YmpucEpxcm5RWG9Cbk5JOHMrajBJeVpRMjlabWQ4Q0xMcW1na0lPVk91YWNDb2tYdktEV2tVbWtCeVJPNkx3QT09Il19 payload: eyJlbnRyeSI6W3siZnVsbFVybCI6Imh0dHA6Ly9oYXBpLmZoaXIub3JnL2Jhc2VSNC9Db25kaXRpb24vNGFjNDE3MTUtZmNiZC00MjFjLTg3OTYtOWIyYzk3MDZkZDNmIiwicmVzb3VyY2UiOnsiY2F0ZWdvcnkiOlt7ImNvZGluZyI6W3siY29kZSI6ImVuY291bnRlci1kaWFnbm9zaXMiLCJkaXNwbGF5IjoiRW5jb3VudGVyIERpYWdub3NpcyIsInN5c3RlbSI6Imh0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vY29uZGl0aW9uLWNhdGVnb3J5In1dfV0sImNsaW5pY2FsU3RhdHVzIjp7ImNvZGluZyI6W3siY29kZSI6ImFjdGl2ZSIsInN5c3RlbSI6Imh0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vY29uZGl0aW9uLWNsaW5pY2FsIn1dfSwiY29kZSI6eyJjb2RpbmciOlt7ImNvZGUiOiIxMjI0ODEwMDgiLCJkaXNwbGF5IjoiSGFtbWVyIHRvZSAoZGlzb3JkZXIpIiwic3lzdGVtIjoiaHR0cDovL3Nub21lZC5pbmZvL3NjdCJ9XSwidGV4dCI6IkhhbW1lciBUb2UifSwiZW5jb3VudGVyIjp7InJlZmVyZW5jZSI6Imh0dHA6Ly9leGFtcGxlLm9yZy9jZGV4L3Byb3ZpZGVyL2ZoaXIvRW5jb3VudGVyLzVmZTYyY2Q1LWJmY2YtNGQzYi1hMWU5LTgwZDZmNzVkNmY4MiJ9LCJpZCI6IjRhYzQxNzE1LWZjYmQtNDIxYy04Nzk2LTliMmM5NzA2ZGQzZiIsIm1ldGEiOnsibGFzdFVwZGF0ZWQiOiIyMDIwLTA0LTI4VDIwOjI4OjAwLjAwOCswMDowMCIsInZlcnNpb25JZCI6IjEwIn0sIm9uc2V0RGF0ZVRpbWUiOiIyMDE4LTEwLTIxVDIxOjIyOjE1LTA3OjAwIiwicmVjb3JkZWREYXRlIjoiMjAxOC0xMC0yMVQyMToyMjoxNS0wNzowMCIsInJlc291cmNlVHlwZSI6IkNvbmRpdGlvbiIsInN1YmplY3QiOnsicmVmZXJlbmNlIjoiaHR0cDovL2V4YW1wbGUub3JnL2NkZXgvcHJvdmlkZXIvZmhpci9QYXRpZW50LzA2ZTFmMGRkLTVmYmUtNDQ4MC05YmI0LTZiNTRlYzAyZDMxYiJ9LCJ0ZXh0Ijp7ImRpdiI6IjxkaXYgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI-PGEgbmFtZT1cIkNvbmRpdGlvbl80YWM0MTcxNS1mY2JkLTQyMWMtODc5Ni05YjJjOTcwNmRkM2ZcIj4gPC9hPjxwIGNsYXNzPVwicmVzLWhlYWRlci1pZFwiPjxiPkdlbmVyYXRlZCBOYXJyYXRpdmU6IENvbmRpdGlvbiA0YWM0MTcxNS1mY2JkLTQyMWMtODc5Ni05YjJjOTcwNmRkM2Y8L2I-PC9wPjxhIG5hbWU9XCI0YWM0MTcxNS1mY2JkLTQyMWMtODc5Ni05YjJjOTcwNmRkM2ZcIj4gPC9hPjxhIG5hbWU9XCJoYzRhYzQxNzE1LWZjYmQtNDIxYy04Nzk2LTliMmM5NzA2ZGQzZlwiPiA8L2E-PGEgbmFtZT1cIjRhYzQxNzE1LWZjYmQtNDIxYy04Nzk2LTliMmM5NzA2ZGQzZi1lbi1VU1wiPiA8L2E-PGRpdiBzdHlsZT1cImRpc3BsYXk6IGlubGluZS1ibG9jazsgYmFja2dyb3VuZC1jb2xvcjogI2Q5ZTBlNzsgcGFkZGluZzogNnB4OyBtYXJnaW46IDRweDsgYm9yZGVyOiAxcHggc29saWQgIzhkYTFiNDsgYm9yZGVyLXJhZGl1czogNXB4OyBsaW5lLWhlaWdodDogNjAlXCI-PHAgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAwcHhcIj52ZXJzaW9uOiAxMDsgTGFzdCB1cGRhdGVkOiAyMDIwLTA0LTI4IDIwOjI4OjAwKzAwMDA7IDwvcD48cCBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDBweFwiPkluZm9ybWF0aW9uIFNvdXJjZTogI2NhYmlKSUs1MXNEMml6NE48L3A-PC9kaXY-PHA-PGI-Y2xpbmljYWxTdGF0dXM8L2I-OiA8c3BhbiB0aXRsZT1cIkNvZGVzOntodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2NvbmRpdGlvbi1jbGluaWNhbCBhY3RpdmV9XCI-QWN0aXZlPC9zcGFuPjwvcD48cD48Yj52ZXJpZmljYXRpb25TdGF0dXM8L2I-OiA8c3BhbiB0aXRsZT1cIkNvZGVzOntodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2NvbmRpdGlvbi12ZXItc3RhdHVzIGNvbmZpcm1lZH1cIj5Db25maXJtZWQ8L3NwYW4-PC9wPjxwPjxiPmNhdGVnb3J5PC9iPjogPHNwYW4gdGl0bGU9XCJDb2Rlczp7aHR0cDovL3Rlcm1pbm9sb2d5LmhsNy5vcmcvQ29kZVN5c3RlbS9jb25kaXRpb24tY2F0ZWdvcnkgZW5jb3VudGVyLWRpYWdub3Npc31cIj5FbmNvdW50ZXIgRGlhZ25vc2lzPC9zcGFuPjwvcD48cD48Yj5jb2RlPC9iPjogPHNwYW4gdGl0bGU9XCJDb2Rlczp7aHR0cDovL3Nub21lZC5pbmZvL3NjdCAxMjI0ODEwMDh9XCI-SGFtbWVyIFRvZTwvc3Bhbj48L3A-PHA-PGI-c3ViamVjdDwvYj46IDxhIGhyZWY9XCJodHRwOi8vZXhhbXBsZS5vcmcvY2RleC9wcm92aWRlci9maGlyL1BhdGllbnQvMDZlMWYwZGQtNWZiZS00NDgwLTliYjQtNmI1NGVjMDJkMzFiXCI-aHR0cDovL2V4YW1wbGUub3JnL2NkZXgvcHJvdmlkZXIvZmhpci9QYXRpZW50LzA2ZTFmMGRkLTVmYmUtNDQ4MC05YmI0LTZiNTRlYzAyZDMxYjwvYT48L3A-PHA-PGI-ZW5jb3VudGVyPC9iPjogPGEgaHJlZj1cImh0dHA6Ly9leGFtcGxlLm9yZy9jZGV4L3Byb3ZpZGVyL2ZoaXIvRW5jb3VudGVyLzVmZTYyY2Q1LWJmY2YtNGQzYi1hMWU5LTgwZDZmNzVkNmY4MlwiPmh0dHA6Ly9leGFtcGxlLm9yZy9jZGV4L3Byb3ZpZGVyL2ZoaXIvRW5jb3VudGVyLzVmZTYyY2Q1LWJmY2YtNGQzYi1hMWU5LTgwZDZmNzVkNmY4MjwvYT48L3A-PHA-PGI-b25zZXQ8L2I-OiAyMDE4LTEwLTIxIDIxOjIyOjE1LTA3MDA8L3A-PHA-PGI-cmVjb3JkZWREYXRlPC9iPjogMjAxOC0xMC0yMSAyMToyMjoxNS0wNzAwPC9wPjwvZGl2PiIsInN0YXR1cyI6ImdlbmVyYXRlZCJ9LCJ2ZXJpZmljYXRpb25TdGF0dXMiOnsiY29kaW5nIjpbeyJjb2RlIjoiY29uZmlybWVkIiwic3lzdGVtIjoiaHR0cDovL3Rlcm1pbm9sb2d5LmhsNy5vcmcvQ29kZVN5c3RlbS9jb25kaXRpb24tdmVyLXN0YXR1cyJ9XX19LCJzZWFyY2giOnsibW9kZSI6Im1hdGNoIn19XSwibGluayI6W3sicmVsYXRpb24iOiJzZWxmIiwidXJsIjoiaHR0cDovL2hhcGkuZmhpci5vcmcvYmFzZVI0L0NvbmRpdGlvbj9wYXRpZW50PTA2ZTFmMGRkLTVmYmUtNDQ4MC05YmI0LTZiNTRlYzAyZDMxYiJ9XSwicmVzb3VyY2VUeXBlIjoiQnVuZGxlIiwidG90YWwiOjEsInR5cGUiOiJzZWFyY2hzZXQifQ signature: aN36yZ0ON-BErPZdkPGONYvW6zHkXnDSNpxos5Z8Az78nq3SAofs4THFzrPPiqll_k7NGbI1nh6gqK0QcCWWrbT1PWKwYNqUSoxyAD4h_jM3lL8zlwYBJlrl_eQK8bh2HtRC7Kwo96wyzLTGJ5cP6wyTilWTluxG8GQcYoKuT8xvFRUm8Vjpe-R_SNn9OjexmyF9jLJQq3adYpX7ybKp1JkgWClVDNXOsi9GdvdX1v-aaHvnvmW9YK_OEjoNk3ozq3XWTVRkbarTYmG3SSpsvMA0KCSyvUkk5uRO6-bYTNHx1pe1aIDeRF6LPJlyXGjQhlNjGCKqk8usI8BS37uY7XQGWHTzUtaEtEg_HmveMVlYvmGp7BjEl3mPZmOQ2GeZAfQAqHjk5jBNEWc-YMJNuzLYuAOLZiF3ehpa7jPH6a2VNbb1sKDjE7fC7MoJEiagklhZFHhw_wdE4qMlt6psDxy5OAn7DRg9d-192x0_TstuXhu5mp6nJhBlLa-2UBGm
3.4. Create detached payload by removing the payload from the JWS
note the signature is displayed with the parts labeled and separated with line breaks for easier viewing then as compact serialization format
split_sig = signature.split('.')
split_sig[1] = ''
signature = '.'.join(split_sig)
for i,j in enumerate(signature.split('.')):
print(f'{labels[i]}:')
print(f'{j}')
print()
print(f'\nSignature in compact serialization format:\n{"="*80}\n{signature}')
header: eyJhbGciOiJSUzI1NiIsImtpZCI6ImJmYmUzZTVjMDQ3MDQ0NDU3NjU0ODExMzkyOGQ1ZjFlNGUzZjJlZWIiLCJrdHkiOiJSUyIsInNpZ1QiOiIyMDIwLTEwLTIzVDA0OjU0OjU2LjA0OCswMDowMCIsInNyQ21zIjpbeyJjb21tSWQiOnsiZGVzYyI6IlZlcmlmaWNhdGlvbiBTaWduYXR1cmUiLCJpZCI6InVybjpvaWQ6MS4yLjg0MC4xMDA2NS4xLjEyLjEuNSJ9LCJjb21tUXVhbHMiOlsiVmVyaWZpY2F0aW9uIG9mIG1lZGljYWwgcmVjb3JkIGludGVncml0eSJdfV0sInR5cCI6IkpXVCIsIng1YyI6WyJNSUlGZVRDQ0ErR2dBd0lCQWdJVU9jRnFMT0JtdDdWUjZ5NEZHbjAwUVNGTVhKZ3dEUVlKS29aSWh2Y05BUUVMQlFBd2dhWXhDekFKQmdOVkJBWVRBbFZUTVJZd0ZBWURWUVFJREExTllYTnpZV05vZFhObGRIUnpNUTh3RFFZRFZRUUhEQVpDYjNOMGIyNHhIVEFiQmdOVkJBb01GRVY0WVcxd2JHVWdUM0puWVc1cGVtRjBhVzl1TVNJd0lBWURWUVFEREJsRFJFVllJRVY0WVcxd2JHVWdUM0puWVc1cGVtRjBhVzl1TVNzd0tRWUpLb1pJaHZjTkFRa0JGaHhqZFhOMGIyMWxjaTF6WlhKMmFXTmxRR1Y0WVcxd2JHVXViM0puTUI0WERUSTFNRGN5TkRFNE1UUTBNRm9YRFRJMk1EY3hPVEU0TVRRME1Gb3dnYVl4Q3pBSkJnTlZCQVlUQWxWVE1SWXdGQVlEVlFRSURBMU5ZWE56WVdOb2RYTmxkSFJ6TVE4d0RRWURWUVFIREFaQ2IzTjBiMjR4SFRBYkJnTlZCQW9NRkVWNFlXMXdiR1VnVDNKbllXNXBlbUYwYVc5dU1TSXdJQVlEVlFRRERCbERSRVZZSUVWNFlXMXdiR1VnVDNKbllXNXBlbUYwYVc5dU1Tc3dLUVlKS29aSWh2Y05BUWtCRmh4amRYTjBiMjFsY2kxelpYSjJhV05sUUdWNFlXMXdiR1V1YjNKbk1JSUJvakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBWThBTUlJQmlnS0NBWUVBcnR5SEllRW1tMU1pMmlSN2xSVzlOUHhBeVM5Qmg4UHhFMWJGS1BiUm8xQldkRllvc0RBRE1jeGRoOWp1eWNzaWhGRW0vdDluY0JlQmVMSTFVdXpFYi9LK0ZXMWFKbmZrK2FaekEyMXBnMXowclJqN2lTaHBLdzhmMGFpaHphVGlhQk9sU3Njb1lEV2VCeTdwZTVRL2VMN1ZSdXFnbFpoVms3WkxTcHc4eGJWVG9GUFl5MkloNTZ3bWQ0eCt3NEk5RFNDc21pRUUxd3RXdVp0ZVZsZ2VjZk1zWS9Yem96SEJUa2s0RnJoOFB4ai8za3ZZVFlVNTJqc2N6QUlMRGxwVUs0Z2E3WEdNbzIzUW91WGRGWFdJOEtNNlhmT1JXQ3FXVSsyVjRCOU1uampHOGpyTytPQ0RIUUhKcUJ4cmtNWVcrR2tiaEJxOFlPbmdRUUgvdFo4Q2o4dmYwWlhFUW91MExXbW9WTmZaWXVxQ0dESjVJZzBsQURtbStsQnd0U2VNOVBwanEwZlZYNC91KytvbzM2TFlpbndOb0JBbTNyUWxCTkk1TVV3Vk9ycnZPaGlXZFl2WVNqM2Z3Q2tiMWFLQm9mRnFQTXIzL25TKzNWT0xnR3A3djdhdENUZldHN2Z4ZjVFOHZoMjd5MWpxM0ZQS1BZMDByTndzNlYzUVp1TlhBZ01CQUFHamdad3dnWmt3Q1FZRFZSMFRCQUl3QURBTEJnTlZIUThFQkFNQ0JlQXdZQVlEVlIwUkJGa3dWNElQZDNkM0xtVjRZVzF3YkdVdWIzSm5vQmtHQ1dDR1NBR0crVnNFQnFBTURBb3hNak0wTlRZM09Ea3poaWxvZEhSd2N6b3ZMMlY0WVcxd2JHVXViM0puTDJab2FYSXZUM0puWVc1cGVtRjBhVzl1THpFeU16QWRCZ05WSFE0RUZnUVU1dS9iTlF0cHMybWtPdVlCVk9GL09heDE2MWd3RFFZSktvWklodmNOQVFFTEJRQURnZ0dCQUJpTE9VMzlORXlTelpTR3oyYU5oYk16VVY1UmFUd3JwRHhEdllqRFgzakVQL2pzbWo0L3BOK0w1UllCWHNCZll4U1V1YlFMZVZ2a2Y1ZnYrb0dybWVDVytmWDh5RTFybCtxODFDQ0wrUThMT096QVpGdUVlWUU5aWVjelk3Zk8xOE1wRjhuQzE0Q0RRYjZETjEwUWFBdGJoVEZha1plT3FaYVVnVG9EZklOc243anphL2JwdDFLZXU1dlVzdTFxRmdqQXB6QTYrTWFsSU5Va0htYTJGSyt6MllmeTBXL05odXBiTGNXRW4xUnl1VUJUUXdzc205d1JQREUvTG9TVUEzcG1tcVBEbDg3ZDl0R0ZESy95bFFUdWFxbDV0RjAybGp6OHdZUWlTUmY1bnp4cVRtdG5NQ212aHlheDc1bjUwdG8vVG40bGgvajFpa28rd0NBV1RNQ05rYittNEcxbXNkb1VZbkVZbi9UaXpXOXZLM0xoVlRXNVpkSSt1Vnlhc2RCaFJMb3lsd1lpZFVHQ2FodkpmRFNHazB4Uzc0aFVYYjIyM0FtemlTS0UzVEZQeFNuWkV2M3ppOG1Pa3pzTVN1YmpucEpxcm5RWG9Cbk5JOHMrajBJeVpRMjlabWQ4Q0xMcW1na0lPVk91YWNDb2tYdktEV2tVbWtCeVJPNkx3QT09Il19 payload: signature: aN36yZ0ON-BErPZdkPGONYvW6zHkXnDSNpxos5Z8Az78nq3SAofs4THFzrPPiqll_k7NGbI1nh6gqK0QcCWWrbT1PWKwYNqUSoxyAD4h_jM3lL8zlwYBJlrl_eQK8bh2HtRC7Kwo96wyzLTGJ5cP6wyTilWTluxG8GQcYoKuT8xvFRUm8Vjpe-R_SNn9OjexmyF9jLJQq3adYpX7ybKp1JkgWClVDNXOsi9GdvdX1v-aaHvnvmW9YK_OEjoNk3ozq3XWTVRkbarTYmG3SSpsvMA0KCSyvUkk5uRO6-bYTNHx1pe1aIDeRF6LPJlyXGjQhlNjGCKqk8usI8BS37uY7XQGWHTzUtaEtEg_HmveMVlYvmGp7BjEl3mPZmOQ2GeZAfQAqHjk5jBNEWc-YMJNuzLYuAOLZiF3ehpa7jPH6a2VNbb1sKDjE7fC7MoJEiagklhZFHhw_wdE4qMlt6psDxy5OAn7DRg9d-192x0_TstuXhu5mp6nJhBlLa-2UBGm Signature in compact serialization format: ================================================================================ eyJhbGciOiJSUzI1NiIsImtpZCI6ImJmYmUzZTVjMDQ3MDQ0NDU3NjU0ODExMzkyOGQ1ZjFlNGUzZjJlZWIiLCJrdHkiOiJSUyIsInNpZ1QiOiIyMDIwLTEwLTIzVDA0OjU0OjU2LjA0OCswMDowMCIsInNyQ21zIjpbeyJjb21tSWQiOnsiZGVzYyI6IlZlcmlmaWNhdGlvbiBTaWduYXR1cmUiLCJpZCI6InVybjpvaWQ6MS4yLjg0MC4xMDA2NS4xLjEyLjEuNSJ9LCJjb21tUXVhbHMiOlsiVmVyaWZpY2F0aW9uIG9mIG1lZGljYWwgcmVjb3JkIGludGVncml0eSJdfV0sInR5cCI6IkpXVCIsIng1YyI6WyJNSUlGZVRDQ0ErR2dBd0lCQWdJVU9jRnFMT0JtdDdWUjZ5NEZHbjAwUVNGTVhKZ3dEUVlKS29aSWh2Y05BUUVMQlFBd2dhWXhDekFKQmdOVkJBWVRBbFZUTVJZd0ZBWURWUVFJREExTllYTnpZV05vZFhObGRIUnpNUTh3RFFZRFZRUUhEQVpDYjNOMGIyNHhIVEFiQmdOVkJBb01GRVY0WVcxd2JHVWdUM0puWVc1cGVtRjBhVzl1TVNJd0lBWURWUVFEREJsRFJFVllJRVY0WVcxd2JHVWdUM0puWVc1cGVtRjBhVzl1TVNzd0tRWUpLb1pJaHZjTkFRa0JGaHhqZFhOMGIyMWxjaTF6WlhKMmFXTmxRR1Y0WVcxd2JHVXViM0puTUI0WERUSTFNRGN5TkRFNE1UUTBNRm9YRFRJMk1EY3hPVEU0TVRRME1Gb3dnYVl4Q3pBSkJnTlZCQVlUQWxWVE1SWXdGQVlEVlFRSURBMU5ZWE56WVdOb2RYTmxkSFJ6TVE4d0RRWURWUVFIREFaQ2IzTjBiMjR4SFRBYkJnTlZCQW9NRkVWNFlXMXdiR1VnVDNKbllXNXBlbUYwYVc5dU1TSXdJQVlEVlFRRERCbERSRVZZSUVWNFlXMXdiR1VnVDNKbllXNXBlbUYwYVc5dU1Tc3dLUVlKS29aSWh2Y05BUWtCRmh4amRYTjBiMjFsY2kxelpYSjJhV05sUUdWNFlXMXdiR1V1YjNKbk1JSUJvakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBWThBTUlJQmlnS0NBWUVBcnR5SEllRW1tMU1pMmlSN2xSVzlOUHhBeVM5Qmg4UHhFMWJGS1BiUm8xQldkRllvc0RBRE1jeGRoOWp1eWNzaWhGRW0vdDluY0JlQmVMSTFVdXpFYi9LK0ZXMWFKbmZrK2FaekEyMXBnMXowclJqN2lTaHBLdzhmMGFpaHphVGlhQk9sU3Njb1lEV2VCeTdwZTVRL2VMN1ZSdXFnbFpoVms3WkxTcHc4eGJWVG9GUFl5MkloNTZ3bWQ0eCt3NEk5RFNDc21pRUUxd3RXdVp0ZVZsZ2VjZk1zWS9Yem96SEJUa2s0RnJoOFB4ai8za3ZZVFlVNTJqc2N6QUlMRGxwVUs0Z2E3WEdNbzIzUW91WGRGWFdJOEtNNlhmT1JXQ3FXVSsyVjRCOU1uampHOGpyTytPQ0RIUUhKcUJ4cmtNWVcrR2tiaEJxOFlPbmdRUUgvdFo4Q2o4dmYwWlhFUW91MExXbW9WTmZaWXVxQ0dESjVJZzBsQURtbStsQnd0U2VNOVBwanEwZlZYNC91KytvbzM2TFlpbndOb0JBbTNyUWxCTkk1TVV3Vk9ycnZPaGlXZFl2WVNqM2Z3Q2tiMWFLQm9mRnFQTXIzL25TKzNWT0xnR3A3djdhdENUZldHN2Z4ZjVFOHZoMjd5MWpxM0ZQS1BZMDByTndzNlYzUVp1TlhBZ01CQUFHamdad3dnWmt3Q1FZRFZSMFRCQUl3QURBTEJnTlZIUThFQkFNQ0JlQXdZQVlEVlIwUkJGa3dWNElQZDNkM0xtVjRZVzF3YkdVdWIzSm5vQmtHQ1dDR1NBR0crVnNFQnFBTURBb3hNak0wTlRZM09Ea3poaWxvZEhSd2N6b3ZMMlY0WVcxd2JHVXViM0puTDJab2FYSXZUM0puWVc1cGVtRjBhVzl1THpFeU16QWRCZ05WSFE0RUZnUVU1dS9iTlF0cHMybWtPdVlCVk9GL09heDE2MWd3RFFZSktvWklodmNOQVFFTEJRQURnZ0dCQUJpTE9VMzlORXlTelpTR3oyYU5oYk16VVY1UmFUd3JwRHhEdllqRFgzakVQL2pzbWo0L3BOK0w1UllCWHNCZll4U1V1YlFMZVZ2a2Y1ZnYrb0dybWVDVytmWDh5RTFybCtxODFDQ0wrUThMT096QVpGdUVlWUU5aWVjelk3Zk8xOE1wRjhuQzE0Q0RRYjZETjEwUWFBdGJoVEZha1plT3FaYVVnVG9EZklOc243anphL2JwdDFLZXU1dlVzdTFxRmdqQXB6QTYrTWFsSU5Va0htYTJGSyt6MllmeTBXL05odXBiTGNXRW4xUnl1VUJUUXdzc205d1JQREUvTG9TVUEzcG1tcVBEbDg3ZDl0R0ZESy95bFFUdWFxbDV0RjAybGp6OHdZUWlTUmY1bnp4cVRtdG5NQ212aHlheDc1bjUwdG8vVG40bGgvajFpa28rd0NBV1RNQ05rYittNEcxbXNkb1VZbkVZbi9UaXpXOXZLM0xoVlRXNVpkSSt1Vnlhc2RCaFJMb3lsd1lpZFVHQ2FodkpmRFNHazB4Uzc0aFVYYjIyM0FtemlTS0UzVEZQeFNuWkV2M3ppOG1Pa3pzTVN1YmpucEpxcm5RWG9Cbk5JOHMrajBJeVpRMjlabWQ4Q0xMcW1na0lPVk91YWNDb2tYdktEV2tVbWtCeVJPNkx3QT09Il19..aN36yZ0ON-BErPZdkPGONYvW6zHkXnDSNpxos5Z8Az78nq3SAofs4THFzrPPiqll_k7NGbI1nh6gqK0QcCWWrbT1PWKwYNqUSoxyAD4h_jM3lL8zlwYBJlrl_eQK8bh2HtRC7Kwo96wyzLTGJ5cP6wyTilWTluxG8GQcYoKuT8xvFRUm8Vjpe-R_SNn9OjexmyF9jLJQq3adYpX7ybKp1JkgWClVDNXOsi9GdvdX1v-aaHvnvmW9YK_OEjoNk3ozq3XWTVRkbarTYmG3SSpsvMA0KCSyvUkk5uRO6-bYTNHx1pe1aIDeRF6LPJlyXGjQhlNjGCKqk8usI8BS37uY7XQGWHTzUtaEtEg_HmveMVlYvmGp7BjEl3mPZmOQ2GeZAfQAqHjk5jBNEWc-YMJNuzLYuAOLZiF3ehpa7jPH6a2VNbb1sKDjE7fC7MoJEiagklhZFHhw_wdE4qMlt6psDxy5OAn7DRg9d-192x0_TstuXhu5mp6nJhBlLa-2UBGm
4. base64 the JWS and add the Signature element to the Bundle
Signature.type.code
elements SHALL contain the same values as the "srCms" header ids.Signature.when
SHALL match the "Sigt" header timestampSignature.who
SHALL match the "srCms" Signer Commitments header id.application/fhir+json;canonicalization=http://hl7.org/fhir/canonicalization/json#document
SHALL be indicated in the Signature.targetFormat
element.application/jose
SHALL be indicated in the Signature.sigFormat
element.Signature.data
element is the base64 signature valuethis is what would be returned in response to a direct query over-the-wire
from base64 import b64encode
from json import loads,dumps
b64_jws = b64encode(signature.encode()).decode()
sig_element = {
"type": [ # Signature.type = Verification Signature
{
"system": "urn:iso-astm:E1762-95:2013",
"code": "1.2.840.10065.1.12.1.5",
"display": "Verification Signature"
}
],
"when": "2021-10-05T22:42:19-07:00", #system timestamp when signature created
"who" : {
"identifier" : {
"type" : {
"coding" : [{
"system" : "http://terminology.hl7.org/CodeSystem/v2-0203",
"code" : "NPI"
}]
},
"system" : "http://hl7.org/fhir/sid/us-npi",
"value" : "1234567893"
},
"display" : "CDEX Example Organization"
},
"targetFormat" : "application/fhir+json;canonicalization=http://hl7.org/fhir/canonicalization/json#document",
"sigFormat" : "application/jose",
"data": b64_jws,
}
searchset_bundle = loads(payload)
searchset_bundle['id'] = searchset_bundle_id # add id back in
searchset_bundle['meta'] = searchset_bundle_meta # add meta back in
searchset_bundle['signature'] = sig_element
print(dumps(searchset_bundle, indent=2))
<![CDATA[ { "entry": [ { "fullUrl": "http://hapi.fhir.org/baseR4/Condition/4ac41715-fcbd-421c-8796-9b2c9706dd3f", "resource": { "category": [ { "coding": [ { "code": "encounter-diagnosis", "display": "Encounter Diagnosis", "system": "http://terminology.hl7.org/CodeSystem/condition-category" } ] } ], "clinicalStatus": { "coding": [ { "code": "active", "system": "http://terminology.hl7.org/CodeSystem/condition-clinical" } ] }, "code": { "coding": [ { "code": "122481008", "display": "Hammer toe (disorder)", "system": "http://snomed.info/sct" } ], "text": "Hammer Toe" }, "encounter": { "reference": "http://example.org/cdex/provider/fhir/Encounter/5fe62cd5-bfcf-4d3b-a1e9-80d6f75d6f82" }, "id": "4ac41715-fcbd-421c-8796-9b2c9706dd3f", "meta": { "lastUpdated": "2020-04-28T20:28:00.008+00:00", "versionId": "10" }, "onsetDateTime": "2018-10-21T21:22:15-07:00", "recordedDate": "2018-10-21T21:22:15-07:00", "resourceType": "Condition", "subject": { "reference": "http://example.org/cdex/provider/fhir/Patient/06e1f0dd-5fbe-4480-9bb4-6b54ec02d31b" }, "text": { "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><a name=\"Condition_4ac41715-fcbd-421c-8796-9b2c9706dd3f\"> </a><p class=\"res-header-id\">Generated Narrative: Condition 4ac41715-fcbd-421c-8796-9b2c9706dd3f</p><a name=\"4ac41715-fcbd-421c-8796-9b2c9706dd3f\"> </a><a name=\"hc4ac41715-fcbd-421c-8796-9b2c9706dd3f\"> </a><a name=\"4ac41715-fcbd-421c-8796-9b2c9706dd3f-en-US\"> </a><div style=\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\"><p style=\"margin-bottom: 0px\">version: 10; Last updated: 2020-04-28 20:28:00+0000; </p><p style=\"margin-bottom: 0px\">Information Source: #cabiJIK51sD2iz4N</p></div>clinicalStatus: <span title=\"Codes:{http://terminology.hl7.org/CodeSystem/condition-clinical active}\">Active</span>
verificationStatus: <span title=\"Codes:{http://terminology.hl7.org/CodeSystem/condition-ver-status confirmed}\">Confirmed</span>
category: <span title=\"Codes:{http://terminology.hl7.org/CodeSystem/condition-category encounter-diagnosis}\">Encounter Diagnosis</span>
code: <span title=\"Codes:{http://snomed.info/sct 122481008}\">Hammer Toe</span>
subject: <a href=\"http://example.org/cdex/provider/fhir/Patient/06e1f0dd-5fbe-4480-9bb4-6b54ec02d31b\">http://example.org/cdex/provider/fhir/Patient/06e1f0dd-5fbe-4480-9bb4-6b54ec02d31b</a>
encounter: <a href=\"http://example.org/cdex/provider/fhir/Encounter/5fe62cd5-bfcf-4d3b-a1e9-80d6f75d6f82\">http://example.org/cdex/provider/fhir/Encounter/5fe62cd5-bfcf-4d3b-a1e9-80d6f75d6f82</a>
onset: 2018-10-21 21:22:15-0700
recordedDate: 2018-10-21 21:22:15-0700
</div>", "status": "generated" }, "verificationStatus": { "coding": [ { "code": "confirmed", "system": "http://terminology.hl7.org/CodeSystem/condition-ver-status" } ] } }, "search": { "mode": "match" } } ], "link": [ { "relation": "self", "url": "http://hapi.fhir.org/baseR4/Condition?patient=06e1f0dd-5fbe-4480-9bb4-6b54ec02d31b" } ], "resourceType": "Bundle", "total": 1, "type": "searchset", "id": "cdex-searchbundle-digital-sig-example", "meta": null, "signature": { "type": [ { "system": "urn:iso-astm:E1762-95:2013", "code": "1.2.840.10065.1.12.1.5", "display": "Verification Signature" } ], "when": "2021-10-05T22:42:19-07:00", "who": { "identifier": { "type": { "coding": [ { "system": "http://terminology.hl7.org/CodeSystem/v2-0203", "code": "NPI" } ] }, "system": "http://hl7.org/fhir/sid/us-npi", "value": "1234567893" }, "display": "CDEX Example Organization" }, "targetFormat": "application/fhir+json;canonicalization=http://hl7.org/fhir/canonicalization/json#document", "sigFormat": "application/jose", "data": "ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNkltSm1ZbVV6WlRWak1EUTNNRFEwTkRVM05qVTBPREV4TXpreU9HUTFaakZsTkdVelpqSmxaV0lpTENKcmRIa2lPaUpTVXlJc0luTnBaMVFpT2lJeU1ESXdMVEV3TFRJelZEQTBPalUwT2pVMkxqQTBPQ3N3TURvd01DSXNJbk55UTIxeklqcGJleUpqYjIxdFNXUWlPbnNpWkdWell5STZJbFpsY21sbWFXTmhkR2x2YmlCVGFXZHVZWFIxY21VaUxDSnBaQ0k2SW5WeWJqcHZhV1E2TVM0eUxqZzBNQzR4TURBMk5TNHhMakV5TGpFdU5TSjlMQ0pqYjIxdFVYVmhiSE1pT2xzaVZtVnlhV1pwWTJGMGFXOXVJRzltSUcxbFpHbGpZV3dnY21WamIzSmtJR2x1ZEdWbmNtbDBlU0pkZlYwc0luUjVjQ0k2SWtwWFZDSXNJbmcxWXlJNld5Sk5TVWxHWlZSRFEwRXJSMmRCZDBsQ1FXZEpWVTlqUm5GTVQwSnRkRGRXVWpaNU5FWkhiakF3VVZOR1RWaEtaM2RFVVZsS1MyOWFTV2gyWTA1QlVVVk1RbEZCZDJkaFdYaERla0ZLUW1kT1ZrSkJXVlJCYkZaVVRWSlpkMFpCV1VSV1VWRkpSRUV4VGxsWVRucFpWMDV2WkZoT2JHUklVbnBOVVRoM1JGRlpSRlpSVVVoRVFWcERZak5PTUdJeU5IaElWRUZpUW1kT1ZrSkJiMDFHUlZZMFdWY3hkMkpIVldkVU0wcHVXVmMxY0dWdFJqQmhWemwxVFZOSmQwbEJXVVJXVVZGRVJFSnNSRkpGVmxsSlJWWTBXVmN4ZDJKSFZXZFVNMHB1V1ZjMWNHVnRSakJoVnpsMVRWTnpkMHRSV1VwTGIxcEphSFpqVGtGUmEwSkdhSGhxWkZoT01HSXlNV3hqYVRGNldsaEtNbUZYVG14UlIxWTBXVmN4ZDJKSFZYVmlNMHB1VFVJMFdFUlVTVEZOUkdONVRrUkZORTFVVVRCTlJtOVlSRlJKTWsxRVkzaFBWRVUwVFZSUk1FMUdiM2RuWVZsNFEzcEJTa0puVGxaQ1FWbFVRV3hXVkUxU1dYZEdRVmxFVmxGUlNVUkJNVTVaV0U1NldWZE9iMlJZVG14a1NGSjZUVkU0ZDBSUldVUldVVkZJUkVGYVEySXpUakJpTWpSNFNGUkJZa0puVGxaQ1FXOU5Sa1ZXTkZsWE1YZGlSMVZuVkROS2JsbFhOWEJsYlVZd1lWYzVkVTFUU1hkSlFWbEVWbEZSUkVSQ2JFUlNSVlpaU1VWV05GbFhNWGRpUjFWblZETktibGxYTlhCbGJVWXdZVmM1ZFUxVGMzZExVVmxLUzI5YVNXaDJZMDVCVVd0Q1JtaDRhbVJZVGpCaU1qRnNZMmt4ZWxwWVNqSmhWMDVzVVVkV05GbFhNWGRpUjFWMVlqTktiazFKU1VKdmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CV1RoQlRVbEpRbWxuUzBOQldVVkJjblI1U0VsbFJXMXRNVTFwTW1sU04yeFNWemxPVUhoQmVWTTVRbWc0VUhoRk1XSkdTMUJpVW04eFFsZGtSbGx2YzBSQlJFMWplR1JvT1dwMWVXTnphV2hHUlcwdmREbHVZMEpsUW1WTVNURlZkWHBGWWk5TEswWlhNV0ZLYm1acksyRmFla0V5TVhCbk1Yb3djbEpxTjJsVGFIQkxkemhtTUdGcGFIcGhWR2xoUWs5c1UzTmpiMWxFVjJWQ2VUZHdaVFZSTDJWTU4xWlNkWEZuYkZwb1ZtczNXa3hUY0hjNGVHSldWRzlHVUZsNU1rbG9OVFozYldRMGVDdDNORWs1UkZORGMyMXBSVVV4ZDNSWGRWcDBaVlpzWjJWalprMXpXUzlZZW05NlNFSlVhMnMwUm5Kb09GQjRhaTh6YTNaWlZGbFZOVEpxYzJONlFVbE1SR3h3VlVzMFoyRTNXRWROYnpJelVXOTFXR1JHV0ZkSk9FdE5ObGhtVDFKWFEzRlhWU3N5VmpSQ09VMXVhbXBIT0dweVR5dFBRMFJJVVVoS2NVSjRjbXROV1ZjclIydGlhRUp4T0ZsUGJtZFJVVWd2ZEZvNFEybzRkbVl3V2xoRlVXOTFNRXhYYlc5V1RtWmFXWFZ4UTBkRVNqVkpaekJzUVVSdGJTdHNRbmQwVTJWTk9WQndhbkV3WmxaWU5DOTFLeXR2YnpNMlRGbHBibmRPYjBKQmJUTnlVV3hDVGtrMVRWVjNWazl5Y25aUGFHbFhaRmwyV1ZOcU0yWjNRMnRpTVdGTFFtOW1SbkZRVFhJekwyNVRLek5XVDB4blIzQTNkamRoZEVOVVpsZEhOMlo0WmpWRk9IWm9NamQ1TVdweE0wWlFTMUJaTURCeVRuZHpObFl6VVZwMVRsaEJaMDFDUVVGSGFtZGFkM2RuV210M1ExRlpSRlpTTUZSQ1FVbDNRVVJCVEVKblRsWklVVGhGUWtGTlEwSmxRWGRaUVZsRVZsSXdVa0pHYTNkV05FbFFaRE5rTTB4dFZqUlpWekYzWWtkVmRXSXpTbTV2UW10SFExZERSMU5CUjBjclZuTkZRbkZCVFVSQmIzaE5hazB3VGxSWk0wOUVhM3BvYVd4dlpFaFNkMk42YjNaTU1sWTBXVmN4ZDJKSFZYVmlNMHB1VERKYWIyRllTWFpVTTBwdVdWYzFjR1Z0UmpCaFZ6bDFUSHBGZVUxNlFXUkNaMDVXU0ZFMFJVWm5VVlUxZFM5aVRsRjBjSE15Yld0UGRWbENWazlHTDA5aGVERTJNV2QzUkZGWlNrdHZXa2xvZG1OT1FWRkZURUpSUVVSblowZENRVUpwVEU5Vk16bE9SWGxUZWxwVFIzb3lZVTVvWWsxNlZWWTFVbUZVZDNKd1JIaEVkbGxxUkZnemFrVlFMMnB6YldvMEwzQk9LMHcxVWxsQ1dITkNabGw0VTFWMVlsRk1aVloyYTJZMVpuWXJiMGR5YldWRFZ5dG1XRGg1UlRGeWJDdHhPREZEUTB3clVUaE1UMDk2UVZwR2RVVmxXVVU1YVdWamVsazNaazh4T0Uxd1JqaHVRekUwUTBSUllqWkVUakV3VVdGQmRHSm9WRVpoYTFwbFQzRmFZVlZuVkc5RVprbE9jMjQzYW5waEwySndkREZMWlhVMWRsVnpkVEZ4Um1kcVFYQjZRVFlyVFdGc1NVNVZhMGh0WVRKR1N5dDZNbGxtZVRCWEwwNW9kWEJpVEdOWFJXNHhVbmwxVlVKVVVYZHpjMjA1ZDFKUVJFVXZURzlUVlVFemNHMXRjVkJFYkRnM1pEbDBSMFpFU3k5NWJGRlVkV0Z4YkRWMFJqQXliR3A2T0hkWlVXbFRVbVkxYm5wNGNWUnRkRzVOUTIxMmFIbGhlRGMxYmpVd2RHOHZWRzQwYkdndmFqRnBhMjhyZDBOQlYxUk5RMDVyWWl0dE5FY3hiWE5rYjFWWmJrVlpiaTlVYVhwWE9YWkxNMHhvVmxSWE5WcGtTU3QxVm5saGMyUkNhRkpNYjNsc2QxbHBaRlZIUTJGb2RrcG1SRk5IYXpCNFV6YzBhRlZZWWpJeU0wRnRlbWxUUzBVelZFWlFlRk51V2tWMk0zcHBPRzFQYTNwelRWTjFZbXB1Y0VweGNtNVJXRzlDYms1Sk9ITXJhakJKZVZwUk1qbGFiV1E0UTB4TWNXMW5hMGxQVms5MVlXTkRiMnRZZGt0RVYydFZiV3RDZVZKUE5reDNRVDA5SWwxOS4uYU4zNnlaME9OLUJFclBaZGtQR09OWXZXNnpIa1huRFNOcHhvczVaOEF6NzhucTNTQW9mczRUSEZ6clBQaXFsbF9rN05HYkkxbmg2Z3FLMFFjQ1dXcmJUMVBXS3dZTnFVU294eUFENGhfak0zbEw4emx3WUJKbHJsX2VRSzhiaDJIdFJDN0t3bzk2d3l6TFRHSjVjUDZ3eVRpbFdUbHV4RzhHUWNZb0t1VDh4dkZSVW04VmpwZS1SX1NObjlPamV4bXlGOWpMSlFxM2FkWXBYN3liS3AxSmtnV0NsVkROWE9zaTlHZHZkWDF2LWFhSHZudm1XOVlLX09Fam9OazNvenEzWFdUVlJrYmFyVFltRzNTU3Bzdk1BMEtDU3l2VWtrNXVSTzYtYllUTkh4MXBlMWFJRGVSRjZMUEpseVhHalFobE5qR0NLcWs4dXNJOEJTMzd1WTdYUUdXSFR6VXRhRXRFZ19IbXZlTVZsWXZtR3A3QmpFbDNtUFptT1EyR2VaQWZRQXFIams1akJORVdjLVlNSk51ekxZdUFPTFppRjNlaHBhN2pQSDZhMlZOYmIxc0tEakU3ZkM3TW9KRWlhZ2tsaFpGSGh3X3dkRTRxTWx0NnBzRHh5NU9BbjdEUmc5ZC0xOTJ4MF9Uc3R1WGh1NW1wNm5KaEJsTGEtMlVCR20=" } } ]]>
1. Remove the Bundle.signature
element from the Search Bundle resource
try:
recd_signature = searchset_bundle.pop("signature")
except:
pass
recd_signature
{'type': [{'system': 'urn:iso-astm:E1762-95:2013', 'code': '1.2.840.10065.1.12.1.5', 'display': 'Verification Signature'}], 'when': '2021-10-05T22:42:19-07:00', 'who': {'identifier': {'type': {'coding': [{'system': 'http://terminology.hl7.org/CodeSystem/v2-0203', 'code': 'NPI'}]}, 'system': 'http://hl7.org/fhir/sid/us-npi', 'value': '1234567893'}, 'display': 'CDEX Example Organization'}, 'targetFormat': 'application/fhir+json;canonicalization=http://hl7.org/fhir/canonicalization/json#document', 'sigFormat': 'application/jose', 'data': 'ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNkltSm1ZbVV6WlRWak1EUTNNRFEwTkRVM05qVTBPREV4TXpreU9HUTFaakZsTkdVelpqSmxaV0lpTENKcmRIa2lPaUpTVXlJc0luTnBaMVFpT2lJeU1ESXdMVEV3TFRJelZEQTBPalUwT2pVMkxqQTBPQ3N3TURvd01DSXNJbk55UTIxeklqcGJleUpqYjIxdFNXUWlPbnNpWkdWell5STZJbFpsY21sbWFXTmhkR2x2YmlCVGFXZHVZWFIxY21VaUxDSnBaQ0k2SW5WeWJqcHZhV1E2TVM0eUxqZzBNQzR4TURBMk5TNHhMakV5TGpFdU5TSjlMQ0pqYjIxdFVYVmhiSE1pT2xzaVZtVnlhV1pwWTJGMGFXOXVJRzltSUcxbFpHbGpZV3dnY21WamIzSmtJR2x1ZEdWbmNtbDBlU0pkZlYwc0luUjVjQ0k2SWtwWFZDSXNJbmcxWXlJNld5Sk5TVWxHWlZSRFEwRXJSMmRCZDBsQ1FXZEpWVTlqUm5GTVQwSnRkRGRXVWpaNU5FWkhiakF3VVZOR1RWaEtaM2RFVVZsS1MyOWFTV2gyWTA1QlVVVk1RbEZCZDJkaFdYaERla0ZLUW1kT1ZrSkJXVlJCYkZaVVRWSlpkMFpCV1VSV1VWRkpSRUV4VGxsWVRucFpWMDV2WkZoT2JHUklVbnBOVVRoM1JGRlpSRlpSVVVoRVFWcERZak5PTUdJeU5IaElWRUZpUW1kT1ZrSkJiMDFHUlZZMFdWY3hkMkpIVldkVU0wcHVXVmMxY0dWdFJqQmhWemwxVFZOSmQwbEJXVVJXVVZGRVJFSnNSRkpGVmxsSlJWWTBXVmN4ZDJKSFZXZFVNMHB1V1ZjMWNHVnRSakJoVnpsMVRWTnpkMHRSV1VwTGIxcEphSFpqVGtGUmEwSkdhSGhxWkZoT01HSXlNV3hqYVRGNldsaEtNbUZYVG14UlIxWTBXVmN4ZDJKSFZYVmlNMHB1VFVJMFdFUlVTVEZOUkdONVRrUkZORTFVVVRCTlJtOVlSRlJKTWsxRVkzaFBWRVUwVFZSUk1FMUdiM2RuWVZsNFEzcEJTa0puVGxaQ1FWbFVRV3hXVkUxU1dYZEdRVmxFVmxGUlNVUkJNVTVaV0U1NldWZE9iMlJZVG14a1NGSjZUVkU0ZDBSUldVUldVVkZJUkVGYVEySXpUakJpTWpSNFNGUkJZa0puVGxaQ1FXOU5Sa1ZXTkZsWE1YZGlSMVZuVkROS2JsbFhOWEJsYlVZd1lWYzVkVTFUU1hkSlFWbEVWbEZSUkVSQ2JFUlNSVlpaU1VWV05GbFhNWGRpUjFWblZETktibGxYTlhCbGJVWXdZVmM1ZFUxVGMzZExVVmxLUzI5YVNXaDJZMDVCVVd0Q1JtaDRhbVJZVGpCaU1qRnNZMmt4ZWxwWVNqSmhWMDVzVVVkV05GbFhNWGRpUjFWMVlqTktiazFKU1VKdmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CV1RoQlRVbEpRbWxuUzBOQldVVkJjblI1U0VsbFJXMXRNVTFwTW1sU04yeFNWemxPVUhoQmVWTTVRbWc0VUhoRk1XSkdTMUJpVW04eFFsZGtSbGx2YzBSQlJFMWplR1JvT1dwMWVXTnphV2hHUlcwdmREbHVZMEpsUW1WTVNURlZkWHBGWWk5TEswWlhNV0ZLYm1acksyRmFla0V5TVhCbk1Yb3djbEpxTjJsVGFIQkxkemhtTUdGcGFIcGhWR2xoUWs5c1UzTmpiMWxFVjJWQ2VUZHdaVFZSTDJWTU4xWlNkWEZuYkZwb1ZtczNXa3hUY0hjNGVHSldWRzlHVUZsNU1rbG9OVFozYldRMGVDdDNORWs1UkZORGMyMXBSVVV4ZDNSWGRWcDBaVlpzWjJWalprMXpXUzlZZW05NlNFSlVhMnMwUm5Kb09GQjRhaTh6YTNaWlZGbFZOVEpxYzJONlFVbE1SR3h3VlVzMFoyRTNXRWROYnpJelVXOTFXR1JHV0ZkSk9FdE5ObGhtVDFKWFEzRlhWU3N5VmpSQ09VMXVhbXBIT0dweVR5dFBRMFJJVVVoS2NVSjRjbXROV1ZjclIydGlhRUp4T0ZsUGJtZFJVVWd2ZEZvNFEybzRkbVl3V2xoRlVXOTFNRXhYYlc5V1RtWmFXWFZ4UTBkRVNqVkpaekJzUVVSdGJTdHNRbmQwVTJWTk9WQndhbkV3WmxaWU5DOTFLeXR2YnpNMlRGbHBibmRPYjBKQmJUTnlVV3hDVGtrMVRWVjNWazl5Y25aUGFHbFhaRmwyV1ZOcU0yWjNRMnRpTVdGTFFtOW1SbkZRVFhJekwyNVRLek5XVDB4blIzQTNkamRoZEVOVVpsZEhOMlo0WmpWRk9IWm9NamQ1TVdweE0wWlFTMUJaTURCeVRuZHpObFl6VVZwMVRsaEJaMDFDUVVGSGFtZGFkM2RuV210M1ExRlpSRlpTTUZSQ1FVbDNRVVJCVEVKblRsWklVVGhGUWtGTlEwSmxRWGRaUVZsRVZsSXdVa0pHYTNkV05FbFFaRE5rTTB4dFZqUlpWekYzWWtkVmRXSXpTbTV2UW10SFExZERSMU5CUjBjclZuTkZRbkZCVFVSQmIzaE5hazB3VGxSWk0wOUVhM3BvYVd4dlpFaFNkMk42YjNaTU1sWTBXVmN4ZDJKSFZYVmlNMHB1VERKYWIyRllTWFpVTTBwdVdWYzFjR1Z0UmpCaFZ6bDFUSHBGZVUxNlFXUkNaMDVXU0ZFMFJVWm5VVlUxZFM5aVRsRjBjSE15Yld0UGRWbENWazlHTDA5aGVERTJNV2QzUkZGWlNrdHZXa2xvZG1OT1FWRkZURUpSUVVSblowZENRVUpwVEU5Vk16bE9SWGxUZWxwVFIzb3lZVTVvWWsxNlZWWTFVbUZVZDNKd1JIaEVkbGxxUkZnemFrVlFMMnB6YldvMEwzQk9LMHcxVWxsQ1dITkNabGw0VTFWMVlsRk1aVloyYTJZMVpuWXJiMGR5YldWRFZ5dG1XRGg1UlRGeWJDdHhPREZEUTB3clVUaE1UMDk2UVZwR2RVVmxXVVU1YVdWamVsazNaazh4T0Uxd1JqaHVRekUwUTBSUllqWkVUakV3VVdGQmRHSm9WRVpoYTFwbFQzRmFZVlZuVkc5RVprbE9jMjQzYW5waEwySndkREZMWlhVMWRsVnpkVEZ4Um1kcVFYQjZRVFlyVFdGc1NVNVZhMGh0WVRKR1N5dDZNbGxtZVRCWEwwNW9kWEJpVEdOWFJXNHhVbmwxVlVKVVVYZHpjMjA1ZDFKUVJFVXZURzlUVlVFemNHMXRjVkJFYkRnM1pEbDBSMFpFU3k5NWJGRlVkV0Z4YkRWMFJqQXliR3A2T0hkWlVXbFRVbVkxYm5wNGNWUnRkRzVOUTIxMmFIbGhlRGMxYmpVd2RHOHZWRzQwYkdndmFqRnBhMjhyZDBOQlYxUk5RMDVyWWl0dE5FY3hiWE5rYjFWWmJrVlpiaTlVYVhwWE9YWkxNMHhvVmxSWE5WcGtTU3QxVm5saGMyUkNhRkpNYjNsc2QxbHBaRlZIUTJGb2RrcG1SRk5IYXpCNFV6YzBhRlZZWWpJeU0wRnRlbWxUUzBVelZFWlFlRk51V2tWMk0zcHBPRzFQYTNwelRWTjFZbXB1Y0VweGNtNVJXRzlDYms1Sk9ITXJhakJKZVZwUk1qbGFiV1E0UTB4TWNXMW5hMGxQVms5MVlXTkRiMnRZZGt0RVYydFZiV3RDZVZKUE5reDNRVDA5SWwxOS4uYU4zNnlaME9OLUJFclBaZGtQR09OWXZXNnpIa1huRFNOcHhvczVaOEF6NzhucTNTQW9mczRUSEZ6clBQaXFsbF9rN05HYkkxbmg2Z3FLMFFjQ1dXcmJUMVBXS3dZTnFVU294eUFENGhfak0zbEw4emx3WUJKbHJsX2VRSzhiaDJIdFJDN0t3bzk2d3l6TFRHSjVjUDZ3eVRpbFdUbHV4RzhHUWNZb0t1VDh4dkZSVW04VmpwZS1SX1NObjlPamV4bXlGOWpMSlFxM2FkWXBYN3liS3AxSmtnV0NsVkROWE9zaTlHZHZkWDF2LWFhSHZudm1XOVlLX09Fam9OazNvenEzWFdUVlJrYmFyVFltRzNTU3Bzdk1BMEtDU3l2VWtrNXVSTzYtYllUTkh4MXBlMWFJRGVSRjZMUEpseVhHalFobE5qR0NLcWs4dXNJOEJTMzd1WTdYUUdXSFR6VXRhRXRFZ19IbXZlTVZsWXZtR3A3QmpFbDNtUFptT1EyR2VaQWZRQXFIams1akJORVdjLVlNSk51ekxZdUFPTFppRjNlaHBhN2pQSDZhMlZOYmIxc0tEakU3ZkM3TW9KRWlhZ2tsaFpGSGh3X3dkRTRxTWx0NnBzRHh5NU9BbjdEUmc5ZC0xOTJ4MF9Uc3R1WGh1NW1wNm5KaEJsTGEtMlVCR20='}
2. Canonicalize the bundle using IETF JSON Canonicalization Scheme (JCS):
searchset_bundle_id = searchset_bundle.pop("id", None) # remove id
searchset_bundle_meta = searchset_bundle.pop("meta", None ) # remove meta
canonical_bundle = canonicalize(searchset_bundle)
canonical_bundle
<![CDATA[ b'{"entry":[{"fullUrl":"http://hapi.fhir.org/baseR4/Condition/4ac41715-fcbd-421c-8796-9b2c9706dd3f","resource":{"category":[{"coding":[{"code":"encounter-diagnosis","display":"Encounter Diagnosis","system":"http://terminology.hl7.org/CodeSystem/condition-category"}]}],"clinicalStatus":{"coding":[{"code":"active","system":"http://terminology.hl7.org/CodeSystem/condition-clinical"}]},"code":{"coding":[{"code":"122481008","display":"Hammer toe (disorder)","system":"http://snomed.info/sct"}],"text":"Hammer Toe"},"encounter":{"reference":"http://example.org/cdex/provider/fhir/Encounter/5fe62cd5-bfcf-4d3b-a1e9-80d6f75d6f82"},"id":"4ac41715-fcbd-421c-8796-9b2c9706dd3f","meta":{"lastUpdated":"2020-04-28T20:28:00.008+00:00","versionId":"10"},"onsetDateTime":"2018-10-21T21:22:15-07:00","recordedDate":"2018-10-21T21:22:15-07:00","resourceType":"Condition","subject":{"reference":"http://example.org/cdex/provider/fhir/Patient/06e1f0dd-5fbe-4480-9bb4-6b54ec02d31b"},"text":{"div":"<div xmlns=\\"http://www.w3.org/1999/xhtml\\"><a name=\\"Condition_4ac41715-fcbd-421c-8796-9b2c9706dd3f\\"> </a><p class=\\"res-header-id\\">Generated Narrative: Condition 4ac41715-fcbd-421c-8796-9b2c9706dd3f</p><a name=\\"4ac41715-fcbd-421c-8796-9b2c9706dd3f\\"> </a><a name=\\"hc4ac41715-fcbd-421c-8796-9b2c9706dd3f\\"> </a><a name=\\"4ac41715-fcbd-421c-8796-9b2c9706dd3f-en-US\\"> </a><div style=\\"display: inline-block; background-color: #d9e0e7; padding: 6px; margin: 4px; border: 1px solid #8da1b4; border-radius: 5px; line-height: 60%\\"><p style=\\"margin-bottom: 0px\\">version: 10; Last updated: 2020-04-28 20:28:00+0000; </p><p style=\\"margin-bottom: 0px\\">Information Source: #cabiJIK51sD2iz4N</p></div>clinicalStatus: <span title=\\"Codes:{http://terminology.hl7.org/CodeSystem/condition-clinical active}\\">Active</span>
verificationStatus: <span title=\\"Codes:{http://terminology.hl7.org/CodeSystem/condition-ver-status confirmed}\\">Confirmed</span>
category: <span title=\\"Codes:{http://terminology.hl7.org/CodeSystem/condition-category encounter-diagnosis}\\">Encounter Diagnosis</span>
code: <span title=\\"Codes:{http://snomed.info/sct 122481008}\\">Hammer Toe</span>
subject: <a href=\\"http://example.org/cdex/provider/fhir/Patient/06e1f0dd-5fbe-4480-9bb4-6b54ec02d31b\\">http://example.org/cdex/provider/fhir/Patient/06e1f0dd-5fbe-4480-9bb4-6b54ec02d31b</a>
encounter: <a href=\\"http://example.org/cdex/provider/fhir/Encounter/5fe62cd5-bfcf-4d3b-a1e9-80d6f75d6f82\\">http://example.org/cdex/provider/fhir/Encounter/5fe62cd5-bfcf-4d3b-a1e9-80d6f75d6f82</a>
onset: 2018-10-21 21:22:15-0700
recordedDate: 2018-10-21 21:22:15-0700
</div>","status":"generated"},"verificationStatus":{"coding":[{"code":"confirmed","system":"http://terminology.hl7.org/CodeSystem/condition-ver-status"}]}},"search":{"mode":"match"}}],"link":[{"relation":"self","url":"http://hapi.fhir.org/baseR4/Condition?patient=06e1f0dd-5fbe-4480-9bb4-6b54ec02d31b"}],"resourceType":"Bundle","total":1,"type":"searchset"}' ]]>
3. Transform canonicalize Bundle to a base64 format using the Base64-URL algorithm.
from base64 import urlsafe_b64encode
recd_b64_canonical_bundle = urlsafe_b64encode(canonical_bundle).decode()
recd_b64_canonical_bundle = recd_b64_canonical_bundle.replace("=","") #remove end padding to normalize
recd_b64_canonical_bundle
'eyJlbnRyeSI6W3siZnVsbFVybCI6Imh0dHA6Ly9oYXBpLmZoaXIub3JnL2Jhc2VSNC9Db25kaXRpb24vNGFjNDE3MTUtZmNiZC00MjFjLTg3OTYtOWIyYzk3MDZkZDNmIiwicmVzb3VyY2UiOnsiY2F0ZWdvcnkiOlt7ImNvZGluZyI6W3siY29kZSI6ImVuY291bnRlci1kaWFnbm9zaXMiLCJkaXNwbGF5IjoiRW5jb3VudGVyIERpYWdub3NpcyIsInN5c3RlbSI6Imh0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vY29uZGl0aW9uLWNhdGVnb3J5In1dfV0sImNsaW5pY2FsU3RhdHVzIjp7ImNvZGluZyI6W3siY29kZSI6ImFjdGl2ZSIsInN5c3RlbSI6Imh0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vY29uZGl0aW9uLWNsaW5pY2FsIn1dfSwiY29kZSI6eyJjb2RpbmciOlt7ImNvZGUiOiIxMjI0ODEwMDgiLCJkaXNwbGF5IjoiSGFtbWVyIHRvZSAoZGlzb3JkZXIpIiwic3lzdGVtIjoiaHR0cDovL3Nub21lZC5pbmZvL3NjdCJ9XSwidGV4dCI6IkhhbW1lciBUb2UifSwiZW5jb3VudGVyIjp7InJlZmVyZW5jZSI6Imh0dHA6Ly9leGFtcGxlLm9yZy9jZGV4L3Byb3ZpZGVyL2ZoaXIvRW5jb3VudGVyLzVmZTYyY2Q1LWJmY2YtNGQzYi1hMWU5LTgwZDZmNzVkNmY4MiJ9LCJpZCI6IjRhYzQxNzE1LWZjYmQtNDIxYy04Nzk2LTliMmM5NzA2ZGQzZiIsIm1ldGEiOnsibGFzdFVwZGF0ZWQiOiIyMDIwLTA0LTI4VDIwOjI4OjAwLjAwOCswMDowMCIsInZlcnNpb25JZCI6IjEwIn0sIm9uc2V0RGF0ZVRpbWUiOiIyMDE4LTEwLTIxVDIxOjIyOjE1LTA3OjAwIiwicmVjb3JkZWREYXRlIjoiMjAxOC0xMC0yMVQyMToyMjoxNS0wNzowMCIsInJlc291cmNlVHlwZSI6IkNvbmRpdGlvbiIsInN1YmplY3QiOnsicmVmZXJlbmNlIjoiaHR0cDovL2V4YW1wbGUub3JnL2NkZXgvcHJvdmlkZXIvZmhpci9QYXRpZW50LzA2ZTFmMGRkLTVmYmUtNDQ4MC05YmI0LTZiNTRlYzAyZDMxYiJ9LCJ0ZXh0Ijp7ImRpdiI6IjxkaXYgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI-PGEgbmFtZT1cIkNvbmRpdGlvbl80YWM0MTcxNS1mY2JkLTQyMWMtODc5Ni05YjJjOTcwNmRkM2ZcIj4gPC9hPjxwIGNsYXNzPVwicmVzLWhlYWRlci1pZFwiPjxiPkdlbmVyYXRlZCBOYXJyYXRpdmU6IENvbmRpdGlvbiA0YWM0MTcxNS1mY2JkLTQyMWMtODc5Ni05YjJjOTcwNmRkM2Y8L2I-PC9wPjxhIG5hbWU9XCI0YWM0MTcxNS1mY2JkLTQyMWMtODc5Ni05YjJjOTcwNmRkM2ZcIj4gPC9hPjxhIG5hbWU9XCJoYzRhYzQxNzE1LWZjYmQtNDIxYy04Nzk2LTliMmM5NzA2ZGQzZlwiPiA8L2E-PGEgbmFtZT1cIjRhYzQxNzE1LWZjYmQtNDIxYy04Nzk2LTliMmM5NzA2ZGQzZi1lbi1VU1wiPiA8L2E-PGRpdiBzdHlsZT1cImRpc3BsYXk6IGlubGluZS1ibG9jazsgYmFja2dyb3VuZC1jb2xvcjogI2Q5ZTBlNzsgcGFkZGluZzogNnB4OyBtYXJnaW46IDRweDsgYm9yZGVyOiAxcHggc29saWQgIzhkYTFiNDsgYm9yZGVyLXJhZGl1czogNXB4OyBsaW5lLWhlaWdodDogNjAlXCI-PHAgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAwcHhcIj52ZXJzaW9uOiAxMDsgTGFzdCB1cGRhdGVkOiAyMDIwLTA0LTI4IDIwOjI4OjAwKzAwMDA7IDwvcD48cCBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDBweFwiPkluZm9ybWF0aW9uIFNvdXJjZTogI2NhYmlKSUs1MXNEMml6NE48L3A-PC9kaXY-PHA-PGI-Y2xpbmljYWxTdGF0dXM8L2I-OiA8c3BhbiB0aXRsZT1cIkNvZGVzOntodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2NvbmRpdGlvbi1jbGluaWNhbCBhY3RpdmV9XCI-QWN0aXZlPC9zcGFuPjwvcD48cD48Yj52ZXJpZmljYXRpb25TdGF0dXM8L2I-OiA8c3BhbiB0aXRsZT1cIkNvZGVzOntodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2NvbmRpdGlvbi12ZXItc3RhdHVzIGNvbmZpcm1lZH1cIj5Db25maXJtZWQ8L3NwYW4-PC9wPjxwPjxiPmNhdGVnb3J5PC9iPjogPHNwYW4gdGl0bGU9XCJDb2Rlczp7aHR0cDovL3Rlcm1pbm9sb2d5LmhsNy5vcmcvQ29kZVN5c3RlbS9jb25kaXRpb24tY2F0ZWdvcnkgZW5jb3VudGVyLWRpYWdub3Npc31cIj5FbmNvdW50ZXIgRGlhZ25vc2lzPC9zcGFuPjwvcD48cD48Yj5jb2RlPC9iPjogPHNwYW4gdGl0bGU9XCJDb2Rlczp7aHR0cDovL3Nub21lZC5pbmZvL3NjdCAxMjI0ODEwMDh9XCI-SGFtbWVyIFRvZTwvc3Bhbj48L3A-PHA-PGI-c3ViamVjdDwvYj46IDxhIGhyZWY9XCJodHRwOi8vZXhhbXBsZS5vcmcvY2RleC9wcm92aWRlci9maGlyL1BhdGllbnQvMDZlMWYwZGQtNWZiZS00NDgwLTliYjQtNmI1NGVjMDJkMzFiXCI-aHR0cDovL2V4YW1wbGUub3JnL2NkZXgvcHJvdmlkZXIvZmhpci9QYXRpZW50LzA2ZTFmMGRkLTVmYmUtNDQ4MC05YmI0LTZiNTRlYzAyZDMxYjwvYT48L3A-PHA-PGI-ZW5jb3VudGVyPC9iPjogPGEgaHJlZj1cImh0dHA6Ly9leGFtcGxlLm9yZy9jZGV4L3Byb3ZpZGVyL2ZoaXIvRW5jb3VudGVyLzVmZTYyY2Q1LWJmY2YtNGQzYi1hMWU5LTgwZDZmNzVkNmY4MlwiPmh0dHA6Ly9leGFtcGxlLm9yZy9jZGV4L3Byb3ZpZGVyL2ZoaXIvRW5jb3VudGVyLzVmZTYyY2Q1LWJmY2YtNGQzYi1hMWU5LTgwZDZmNzVkNmY4MjwvYT48L3A-PHA-PGI-b25zZXQ8L2I-OiAyMDE4LTEwLTIxIDIxOjIyOjE1LTA3MDA8L3A-PHA-PGI-cmVjb3JkZWREYXRlPC9iPjogMjAxOC0xMC0yMSAyMToyMjoxNS0wNzAwPC9wPjwvZGl2PiIsInN0YXR1cyI6ImdlbmVyYXRlZCJ9LCJ2ZXJpZmljYXRpb25TdGF0dXMiOnsiY29kaW5nIjpbeyJjb2RlIjoiY29uZmlybWVkIiwic3lzdGVtIjoiaHR0cDovL3Rlcm1pbm9sb2d5LmhsNy5vcmcvQ29kZVN5c3RlbS9jb25kaXRpb24tdmVyLXN0YXR1cyJ9XX19LCJzZWFyY2giOnsibW9kZSI6Im1hdGNoIn19XSwibGluayI6W3sicmVsYXRpb24iOiJzZWxmIiwidXJsIjoiaHR0cDovL2hhcGkuZmhpci5vcmcvYmFzZVI0L0NvbmRpdGlvbj9wYXRpZW50PTA2ZTFmMGRkLTVmYmUtNDQ4MC05YmI0LTZiNTRlYzAyZDMxYiJ9XSwicmVzb3VyY2VUeXBlIjoiQnVuZGxlIiwidG90YWwiOjEsInR5cGUiOiJzZWFyY2hzZXQifQ'
4. Get the base64 encoded JWS from the Bundle.signature.data
element
recd_b64_jws = recd_signature['data']
recd_b64_jws
'ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNkltSm1ZbVV6WlRWak1EUTNNRFEwTkRVM05qVTBPREV4TXpreU9HUTFaakZsTkdVelpqSmxaV0lpTENKcmRIa2lPaUpTVXlJc0luTnBaMVFpT2lJeU1ESXdMVEV3TFRJelZEQTBPalUwT2pVMkxqQTBPQ3N3TURvd01DSXNJbk55UTIxeklqcGJleUpqYjIxdFNXUWlPbnNpWkdWell5STZJbFpsY21sbWFXTmhkR2x2YmlCVGFXZHVZWFIxY21VaUxDSnBaQ0k2SW5WeWJqcHZhV1E2TVM0eUxqZzBNQzR4TURBMk5TNHhMakV5TGpFdU5TSjlMQ0pqYjIxdFVYVmhiSE1pT2xzaVZtVnlhV1pwWTJGMGFXOXVJRzltSUcxbFpHbGpZV3dnY21WamIzSmtJR2x1ZEdWbmNtbDBlU0pkZlYwc0luUjVjQ0k2SWtwWFZDSXNJbmcxWXlJNld5Sk5TVWxHWlZSRFEwRXJSMmRCZDBsQ1FXZEpWVTlqUm5GTVQwSnRkRGRXVWpaNU5FWkhiakF3VVZOR1RWaEtaM2RFVVZsS1MyOWFTV2gyWTA1QlVVVk1RbEZCZDJkaFdYaERla0ZLUW1kT1ZrSkJXVlJCYkZaVVRWSlpkMFpCV1VSV1VWRkpSRUV4VGxsWVRucFpWMDV2WkZoT2JHUklVbnBOVVRoM1JGRlpSRlpSVVVoRVFWcERZak5PTUdJeU5IaElWRUZpUW1kT1ZrSkJiMDFHUlZZMFdWY3hkMkpIVldkVU0wcHVXVmMxY0dWdFJqQmhWemwxVFZOSmQwbEJXVVJXVVZGRVJFSnNSRkpGVmxsSlJWWTBXVmN4ZDJKSFZXZFVNMHB1V1ZjMWNHVnRSakJoVnpsMVRWTnpkMHRSV1VwTGIxcEphSFpqVGtGUmEwSkdhSGhxWkZoT01HSXlNV3hqYVRGNldsaEtNbUZYVG14UlIxWTBXVmN4ZDJKSFZYVmlNMHB1VFVJMFdFUlVTVEZOUkdONVRrUkZORTFVVVRCTlJtOVlSRlJKTWsxRVkzaFBWRVUwVFZSUk1FMUdiM2RuWVZsNFEzcEJTa0puVGxaQ1FWbFVRV3hXVkUxU1dYZEdRVmxFVmxGUlNVUkJNVTVaV0U1NldWZE9iMlJZVG14a1NGSjZUVkU0ZDBSUldVUldVVkZJUkVGYVEySXpUakJpTWpSNFNGUkJZa0puVGxaQ1FXOU5Sa1ZXTkZsWE1YZGlSMVZuVkROS2JsbFhOWEJsYlVZd1lWYzVkVTFUU1hkSlFWbEVWbEZSUkVSQ2JFUlNSVlpaU1VWV05GbFhNWGRpUjFWblZETktibGxYTlhCbGJVWXdZVmM1ZFUxVGMzZExVVmxLUzI5YVNXaDJZMDVCVVd0Q1JtaDRhbVJZVGpCaU1qRnNZMmt4ZWxwWVNqSmhWMDVzVVVkV05GbFhNWGRpUjFWMVlqTktiazFKU1VKdmFrRk9RbWRyY1docmFVYzVkekJDUVZGRlJrRkJUME5CV1RoQlRVbEpRbWxuUzBOQldVVkJjblI1U0VsbFJXMXRNVTFwTW1sU04yeFNWemxPVUhoQmVWTTVRbWc0VUhoRk1XSkdTMUJpVW04eFFsZGtSbGx2YzBSQlJFMWplR1JvT1dwMWVXTnphV2hHUlcwdmREbHVZMEpsUW1WTVNURlZkWHBGWWk5TEswWlhNV0ZLYm1acksyRmFla0V5TVhCbk1Yb3djbEpxTjJsVGFIQkxkemhtTUdGcGFIcGhWR2xoUWs5c1UzTmpiMWxFVjJWQ2VUZHdaVFZSTDJWTU4xWlNkWEZuYkZwb1ZtczNXa3hUY0hjNGVHSldWRzlHVUZsNU1rbG9OVFozYldRMGVDdDNORWs1UkZORGMyMXBSVVV4ZDNSWGRWcDBaVlpzWjJWalprMXpXUzlZZW05NlNFSlVhMnMwUm5Kb09GQjRhaTh6YTNaWlZGbFZOVEpxYzJONlFVbE1SR3h3VlVzMFoyRTNXRWROYnpJelVXOTFXR1JHV0ZkSk9FdE5ObGhtVDFKWFEzRlhWU3N5VmpSQ09VMXVhbXBIT0dweVR5dFBRMFJJVVVoS2NVSjRjbXROV1ZjclIydGlhRUp4T0ZsUGJtZFJVVWd2ZEZvNFEybzRkbVl3V2xoRlVXOTFNRXhYYlc5V1RtWmFXWFZ4UTBkRVNqVkpaekJzUVVSdGJTdHNRbmQwVTJWTk9WQndhbkV3WmxaWU5DOTFLeXR2YnpNMlRGbHBibmRPYjBKQmJUTnlVV3hDVGtrMVRWVjNWazl5Y25aUGFHbFhaRmwyV1ZOcU0yWjNRMnRpTVdGTFFtOW1SbkZRVFhJekwyNVRLek5XVDB4blIzQTNkamRoZEVOVVpsZEhOMlo0WmpWRk9IWm9NamQ1TVdweE0wWlFTMUJaTURCeVRuZHpObFl6VVZwMVRsaEJaMDFDUVVGSGFtZGFkM2RuV210M1ExRlpSRlpTTUZSQ1FVbDNRVVJCVEVKblRsWklVVGhGUWtGTlEwSmxRWGRaUVZsRVZsSXdVa0pHYTNkV05FbFFaRE5rTTB4dFZqUlpWekYzWWtkVmRXSXpTbTV2UW10SFExZERSMU5CUjBjclZuTkZRbkZCVFVSQmIzaE5hazB3VGxSWk0wOUVhM3BvYVd4dlpFaFNkMk42YjNaTU1sWTBXVmN4ZDJKSFZYVmlNMHB1VERKYWIyRllTWFpVTTBwdVdWYzFjR1Z0UmpCaFZ6bDFUSHBGZVUxNlFXUkNaMDVXU0ZFMFJVWm5VVlUxZFM5aVRsRjBjSE15Yld0UGRWbENWazlHTDA5aGVERTJNV2QzUkZGWlNrdHZXa2xvZG1OT1FWRkZURUpSUVVSblowZENRVUpwVEU5Vk16bE9SWGxUZWxwVFIzb3lZVTVvWWsxNlZWWTFVbUZVZDNKd1JIaEVkbGxxUkZnemFrVlFMMnB6YldvMEwzQk9LMHcxVWxsQ1dITkNabGw0VTFWMVlsRk1aVloyYTJZMVpuWXJiMGR5YldWRFZ5dG1XRGg1UlRGeWJDdHhPREZEUTB3clVUaE1UMDk2UVZwR2RVVmxXVVU1YVdWamVsazNaazh4T0Uxd1JqaHVRekUwUTBSUllqWkVUakV3VVdGQmRHSm9WRVpoYTFwbFQzRmFZVlZuVkc5RVprbE9jMjQzYW5waEwySndkREZMWlhVMWRsVnpkVEZ4Um1kcVFYQjZRVFlyVFdGc1NVNVZhMGh0WVRKR1N5dDZNbGxtZVRCWEwwNW9kWEJpVEdOWFJXNHhVbmwxVlVKVVVYZHpjMjA1ZDFKUVJFVXZURzlUVlVFemNHMXRjVkJFYkRnM1pEbDBSMFpFU3k5NWJGRlVkV0Z4YkRWMFJqQXliR3A2T0hkWlVXbFRVbVkxYm5wNGNWUnRkRzVOUTIxMmFIbGhlRGMxYmpVd2RHOHZWRzQwYkdndmFqRnBhMjhyZDBOQlYxUk5RMDVyWWl0dE5FY3hiWE5rYjFWWmJrVlpiaTlVYVhwWE9YWkxNMHhvVmxSWE5WcGtTU3QxVm5saGMyUkNhRkpNYjNsc2QxbHBaRlZIUTJGb2RrcG1SRk5IYXpCNFV6YzBhRlZZWWpJeU0wRnRlbWxUUzBVelZFWlFlRk51V2tWMk0zcHBPRzFQYTNwelRWTjFZbXB1Y0VweGNtNVJXRzlDYms1Sk9ITXJhakJKZVZwUk1qbGFiV1E0UTB4TWNXMW5hMGxQVms5MVlXTkRiMnRZZGt0RVYydFZiV3RDZVZKUE5reDNRVDA5SWwxOS4uYU4zNnlaME9OLUJFclBaZGtQR09OWXZXNnpIa1huRFNOcHhvczVaOEF6NzhucTNTQW9mczRUSEZ6clBQaXFsbF9rN05HYkkxbmg2Z3FLMFFjQ1dXcmJUMVBXS3dZTnFVU294eUFENGhfak0zbEw4emx3WUJKbHJsX2VRSzhiaDJIdFJDN0t3bzk2d3l6TFRHSjVjUDZ3eVRpbFdUbHV4RzhHUWNZb0t1VDh4dkZSVW04VmpwZS1SX1NObjlPamV4bXlGOWpMSlFxM2FkWXBYN3liS3AxSmtnV0NsVkROWE9zaTlHZHZkWDF2LWFhSHZudm1XOVlLX09Fam9OazNvenEzWFdUVlJrYmFyVFltRzNTU3Bzdk1BMEtDU3l2VWtrNXVSTzYtYllUTkh4MXBlMWFJRGVSRjZMUEpseVhHalFobE5qR0NLcWs4dXNJOEJTMzd1WTdYUUdXSFR6VXRhRXRFZ19IbXZlTVZsWXZtR3A3QmpFbDNtUFptT1EyR2VaQWZRQXFIams1akJORVdjLVlNSk51ekxZdUFPTFppRjNlaHBhN2pQSDZhMlZOYmIxc0tEakU3ZkM3TW9KRWlhZ2tsaFpGSGh3X3dkRTRxTWx0NnBzRHh5NU9BbjdEUmc5ZC0xOTJ4MF9Uc3R1WGh1NW1wNm5KaEJsTGEtMlVCR20='
5. Base64 decode the encoded JWS
note the signature is displayed with the parts labeled and separated with line breaks for easier viewing
from base64 import b64decode
recd_jws = b64decode(recd_b64_jws.encode()).decode()
for i,j in enumerate(recd_jws.split('.')):
print(f'{labels[i]}:')
print(f'{j}')
print()
header: eyJhbGciOiJSUzI1NiIsImtpZCI6ImJmYmUzZTVjMDQ3MDQ0NDU3NjU0ODExMzkyOGQ1ZjFlNGUzZjJlZWIiLCJrdHkiOiJSUyIsInNpZ1QiOiIyMDIwLTEwLTIzVDA0OjU0OjU2LjA0OCswMDowMCIsInNyQ21zIjpbeyJjb21tSWQiOnsiZGVzYyI6IlZlcmlmaWNhdGlvbiBTaWduYXR1cmUiLCJpZCI6InVybjpvaWQ6MS4yLjg0MC4xMDA2NS4xLjEyLjEuNSJ9LCJjb21tUXVhbHMiOlsiVmVyaWZpY2F0aW9uIG9mIG1lZGljYWwgcmVjb3JkIGludGVncml0eSJdfV0sInR5cCI6IkpXVCIsIng1YyI6WyJNSUlGZVRDQ0ErR2dBd0lCQWdJVU9jRnFMT0JtdDdWUjZ5NEZHbjAwUVNGTVhKZ3dEUVlKS29aSWh2Y05BUUVMQlFBd2dhWXhDekFKQmdOVkJBWVRBbFZUTVJZd0ZBWURWUVFJREExTllYTnpZV05vZFhObGRIUnpNUTh3RFFZRFZRUUhEQVpDYjNOMGIyNHhIVEFiQmdOVkJBb01GRVY0WVcxd2JHVWdUM0puWVc1cGVtRjBhVzl1TVNJd0lBWURWUVFEREJsRFJFVllJRVY0WVcxd2JHVWdUM0puWVc1cGVtRjBhVzl1TVNzd0tRWUpLb1pJaHZjTkFRa0JGaHhqZFhOMGIyMWxjaTF6WlhKMmFXTmxRR1Y0WVcxd2JHVXViM0puTUI0WERUSTFNRGN5TkRFNE1UUTBNRm9YRFRJMk1EY3hPVEU0TVRRME1Gb3dnYVl4Q3pBSkJnTlZCQVlUQWxWVE1SWXdGQVlEVlFRSURBMU5ZWE56WVdOb2RYTmxkSFJ6TVE4d0RRWURWUVFIREFaQ2IzTjBiMjR4SFRBYkJnTlZCQW9NRkVWNFlXMXdiR1VnVDNKbllXNXBlbUYwYVc5dU1TSXdJQVlEVlFRRERCbERSRVZZSUVWNFlXMXdiR1VnVDNKbllXNXBlbUYwYVc5dU1Tc3dLUVlKS29aSWh2Y05BUWtCRmh4amRYTjBiMjFsY2kxelpYSjJhV05sUUdWNFlXMXdiR1V1YjNKbk1JSUJvakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBWThBTUlJQmlnS0NBWUVBcnR5SEllRW1tMU1pMmlSN2xSVzlOUHhBeVM5Qmg4UHhFMWJGS1BiUm8xQldkRllvc0RBRE1jeGRoOWp1eWNzaWhGRW0vdDluY0JlQmVMSTFVdXpFYi9LK0ZXMWFKbmZrK2FaekEyMXBnMXowclJqN2lTaHBLdzhmMGFpaHphVGlhQk9sU3Njb1lEV2VCeTdwZTVRL2VMN1ZSdXFnbFpoVms3WkxTcHc4eGJWVG9GUFl5MkloNTZ3bWQ0eCt3NEk5RFNDc21pRUUxd3RXdVp0ZVZsZ2VjZk1zWS9Yem96SEJUa2s0RnJoOFB4ai8za3ZZVFlVNTJqc2N6QUlMRGxwVUs0Z2E3WEdNbzIzUW91WGRGWFdJOEtNNlhmT1JXQ3FXVSsyVjRCOU1uampHOGpyTytPQ0RIUUhKcUJ4cmtNWVcrR2tiaEJxOFlPbmdRUUgvdFo4Q2o4dmYwWlhFUW91MExXbW9WTmZaWXVxQ0dESjVJZzBsQURtbStsQnd0U2VNOVBwanEwZlZYNC91KytvbzM2TFlpbndOb0JBbTNyUWxCTkk1TVV3Vk9ycnZPaGlXZFl2WVNqM2Z3Q2tiMWFLQm9mRnFQTXIzL25TKzNWT0xnR3A3djdhdENUZldHN2Z4ZjVFOHZoMjd5MWpxM0ZQS1BZMDByTndzNlYzUVp1TlhBZ01CQUFHamdad3dnWmt3Q1FZRFZSMFRCQUl3QURBTEJnTlZIUThFQkFNQ0JlQXdZQVlEVlIwUkJGa3dWNElQZDNkM0xtVjRZVzF3YkdVdWIzSm5vQmtHQ1dDR1NBR0crVnNFQnFBTURBb3hNak0wTlRZM09Ea3poaWxvZEhSd2N6b3ZMMlY0WVcxd2JHVXViM0puTDJab2FYSXZUM0puWVc1cGVtRjBhVzl1THpFeU16QWRCZ05WSFE0RUZnUVU1dS9iTlF0cHMybWtPdVlCVk9GL09heDE2MWd3RFFZSktvWklodmNOQVFFTEJRQURnZ0dCQUJpTE9VMzlORXlTelpTR3oyYU5oYk16VVY1UmFUd3JwRHhEdllqRFgzakVQL2pzbWo0L3BOK0w1UllCWHNCZll4U1V1YlFMZVZ2a2Y1ZnYrb0dybWVDVytmWDh5RTFybCtxODFDQ0wrUThMT096QVpGdUVlWUU5aWVjelk3Zk8xOE1wRjhuQzE0Q0RRYjZETjEwUWFBdGJoVEZha1plT3FaYVVnVG9EZklOc243anphL2JwdDFLZXU1dlVzdTFxRmdqQXB6QTYrTWFsSU5Va0htYTJGSyt6MllmeTBXL05odXBiTGNXRW4xUnl1VUJUUXdzc205d1JQREUvTG9TVUEzcG1tcVBEbDg3ZDl0R0ZESy95bFFUdWFxbDV0RjAybGp6OHdZUWlTUmY1bnp4cVRtdG5NQ212aHlheDc1bjUwdG8vVG40bGgvajFpa28rd0NBV1RNQ05rYittNEcxbXNkb1VZbkVZbi9UaXpXOXZLM0xoVlRXNVpkSSt1Vnlhc2RCaFJMb3lsd1lpZFVHQ2FodkpmRFNHazB4Uzc0aFVYYjIyM0FtemlTS0UzVEZQeFNuWkV2M3ppOG1Pa3pzTVN1YmpucEpxcm5RWG9Cbk5JOHMrajBJeVpRMjlabWQ4Q0xMcW1na0lPVk91YWNDb2tYdktEV2tVbWtCeVJPNkx3QT09Il19 payload: signature: aN36yZ0ON-BErPZdkPGONYvW6zHkXnDSNpxos5Z8Az78nq3SAofs4THFzrPPiqll_k7NGbI1nh6gqK0QcCWWrbT1PWKwYNqUSoxyAD4h_jM3lL8zlwYBJlrl_eQK8bh2HtRC7Kwo96wyzLTGJ5cP6wyTilWTluxG8GQcYoKuT8xvFRUm8Vjpe-R_SNn9OjexmyF9jLJQq3adYpX7ybKp1JkgWClVDNXOsi9GdvdX1v-aaHvnvmW9YK_OEjoNk3ozq3XWTVRkbarTYmG3SSpsvMA0KCSyvUkk5uRO6-bYTNHx1pe1aIDeRF6LPJlyXGjQhlNjGCKqk8usI8BS37uY7XQGWHTzUtaEtEg_HmveMVlYvmGp7BjEl3mPZmOQ2GeZAfQAqHjk5jBNEWc-YMJNuzLYuAOLZiF3ehpa7jPH6a2VNbb1sKDjE7fC7MoJEiagklhZFHhw_wdE4qMlt6psDxy5OAn7DRg9d-192x0_TstuXhu5mp6nJhBlLa-2UBGm
6. reattach the payload - the base64 encoded Bundle - into the JWS payload element.
note the signature is displayed with the parts labeled and separated with line breaks for easier viewing
split_sig = recd_jws.split('.')
split_sig[1] = recd_b64_canonical_bundle
recd_jws = '.'.join(split_sig)
for i,j in enumerate(recd_jws.split('.')):
print(f'{labels[i]}:')
print(f'{j}')
print()
header: eyJhbGciOiJSUzI1NiIsImtpZCI6ImJmYmUzZTVjMDQ3MDQ0NDU3NjU0ODExMzkyOGQ1ZjFlNGUzZjJlZWIiLCJrdHkiOiJSUyIsInNpZ1QiOiIyMDIwLTEwLTIzVDA0OjU0OjU2LjA0OCswMDowMCIsInNyQ21zIjpbeyJjb21tSWQiOnsiZGVzYyI6IlZlcmlmaWNhdGlvbiBTaWduYXR1cmUiLCJpZCI6InVybjpvaWQ6MS4yLjg0MC4xMDA2NS4xLjEyLjEuNSJ9LCJjb21tUXVhbHMiOlsiVmVyaWZpY2F0aW9uIG9mIG1lZGljYWwgcmVjb3JkIGludGVncml0eSJdfV0sInR5cCI6IkpXVCIsIng1YyI6WyJNSUlGZVRDQ0ErR2dBd0lCQWdJVU9jRnFMT0JtdDdWUjZ5NEZHbjAwUVNGTVhKZ3dEUVlKS29aSWh2Y05BUUVMQlFBd2dhWXhDekFKQmdOVkJBWVRBbFZUTVJZd0ZBWURWUVFJREExTllYTnpZV05vZFhObGRIUnpNUTh3RFFZRFZRUUhEQVpDYjNOMGIyNHhIVEFiQmdOVkJBb01GRVY0WVcxd2JHVWdUM0puWVc1cGVtRjBhVzl1TVNJd0lBWURWUVFEREJsRFJFVllJRVY0WVcxd2JHVWdUM0puWVc1cGVtRjBhVzl1TVNzd0tRWUpLb1pJaHZjTkFRa0JGaHhqZFhOMGIyMWxjaTF6WlhKMmFXTmxRR1Y0WVcxd2JHVXViM0puTUI0WERUSTFNRGN5TkRFNE1UUTBNRm9YRFRJMk1EY3hPVEU0TVRRME1Gb3dnYVl4Q3pBSkJnTlZCQVlUQWxWVE1SWXdGQVlEVlFRSURBMU5ZWE56WVdOb2RYTmxkSFJ6TVE4d0RRWURWUVFIREFaQ2IzTjBiMjR4SFRBYkJnTlZCQW9NRkVWNFlXMXdiR1VnVDNKbllXNXBlbUYwYVc5dU1TSXdJQVlEVlFRRERCbERSRVZZSUVWNFlXMXdiR1VnVDNKbllXNXBlbUYwYVc5dU1Tc3dLUVlKS29aSWh2Y05BUWtCRmh4amRYTjBiMjFsY2kxelpYSjJhV05sUUdWNFlXMXdiR1V1YjNKbk1JSUJvakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBWThBTUlJQmlnS0NBWUVBcnR5SEllRW1tMU1pMmlSN2xSVzlOUHhBeVM5Qmg4UHhFMWJGS1BiUm8xQldkRllvc0RBRE1jeGRoOWp1eWNzaWhGRW0vdDluY0JlQmVMSTFVdXpFYi9LK0ZXMWFKbmZrK2FaekEyMXBnMXowclJqN2lTaHBLdzhmMGFpaHphVGlhQk9sU3Njb1lEV2VCeTdwZTVRL2VMN1ZSdXFnbFpoVms3WkxTcHc4eGJWVG9GUFl5MkloNTZ3bWQ0eCt3NEk5RFNDc21pRUUxd3RXdVp0ZVZsZ2VjZk1zWS9Yem96SEJUa2s0RnJoOFB4ai8za3ZZVFlVNTJqc2N6QUlMRGxwVUs0Z2E3WEdNbzIzUW91WGRGWFdJOEtNNlhmT1JXQ3FXVSsyVjRCOU1uampHOGpyTytPQ0RIUUhKcUJ4cmtNWVcrR2tiaEJxOFlPbmdRUUgvdFo4Q2o4dmYwWlhFUW91MExXbW9WTmZaWXVxQ0dESjVJZzBsQURtbStsQnd0U2VNOVBwanEwZlZYNC91KytvbzM2TFlpbndOb0JBbTNyUWxCTkk1TVV3Vk9ycnZPaGlXZFl2WVNqM2Z3Q2tiMWFLQm9mRnFQTXIzL25TKzNWT0xnR3A3djdhdENUZldHN2Z4ZjVFOHZoMjd5MWpxM0ZQS1BZMDByTndzNlYzUVp1TlhBZ01CQUFHamdad3dnWmt3Q1FZRFZSMFRCQUl3QURBTEJnTlZIUThFQkFNQ0JlQXdZQVlEVlIwUkJGa3dWNElQZDNkM0xtVjRZVzF3YkdVdWIzSm5vQmtHQ1dDR1NBR0crVnNFQnFBTURBb3hNak0wTlRZM09Ea3poaWxvZEhSd2N6b3ZMMlY0WVcxd2JHVXViM0puTDJab2FYSXZUM0puWVc1cGVtRjBhVzl1THpFeU16QWRCZ05WSFE0RUZnUVU1dS9iTlF0cHMybWtPdVlCVk9GL09heDE2MWd3RFFZSktvWklodmNOQVFFTEJRQURnZ0dCQUJpTE9VMzlORXlTelpTR3oyYU5oYk16VVY1UmFUd3JwRHhEdllqRFgzakVQL2pzbWo0L3BOK0w1UllCWHNCZll4U1V1YlFMZVZ2a2Y1ZnYrb0dybWVDVytmWDh5RTFybCtxODFDQ0wrUThMT096QVpGdUVlWUU5aWVjelk3Zk8xOE1wRjhuQzE0Q0RRYjZETjEwUWFBdGJoVEZha1plT3FaYVVnVG9EZklOc243anphL2JwdDFLZXU1dlVzdTFxRmdqQXB6QTYrTWFsSU5Va0htYTJGSyt6MllmeTBXL05odXBiTGNXRW4xUnl1VUJUUXdzc205d1JQREUvTG9TVUEzcG1tcVBEbDg3ZDl0R0ZESy95bFFUdWFxbDV0RjAybGp6OHdZUWlTUmY1bnp4cVRtdG5NQ212aHlheDc1bjUwdG8vVG40bGgvajFpa28rd0NBV1RNQ05rYittNEcxbXNkb1VZbkVZbi9UaXpXOXZLM0xoVlRXNVpkSSt1Vnlhc2RCaFJMb3lsd1lpZFVHQ2FodkpmRFNHazB4Uzc0aFVYYjIyM0FtemlTS0UzVEZQeFNuWkV2M3ppOG1Pa3pzTVN1YmpucEpxcm5RWG9Cbk5JOHMrajBJeVpRMjlabWQ4Q0xMcW1na0lPVk91YWNDb2tYdktEV2tVbWtCeVJPNkx3QT09Il19 payload: eyJlbnRyeSI6W3siZnVsbFVybCI6Imh0dHA6Ly9oYXBpLmZoaXIub3JnL2Jhc2VSNC9Db25kaXRpb24vNGFjNDE3MTUtZmNiZC00MjFjLTg3OTYtOWIyYzk3MDZkZDNmIiwicmVzb3VyY2UiOnsiY2F0ZWdvcnkiOlt7ImNvZGluZyI6W3siY29kZSI6ImVuY291bnRlci1kaWFnbm9zaXMiLCJkaXNwbGF5IjoiRW5jb3VudGVyIERpYWdub3NpcyIsInN5c3RlbSI6Imh0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vY29uZGl0aW9uLWNhdGVnb3J5In1dfV0sImNsaW5pY2FsU3RhdHVzIjp7ImNvZGluZyI6W3siY29kZSI6ImFjdGl2ZSIsInN5c3RlbSI6Imh0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vY29uZGl0aW9uLWNsaW5pY2FsIn1dfSwiY29kZSI6eyJjb2RpbmciOlt7ImNvZGUiOiIxMjI0ODEwMDgiLCJkaXNwbGF5IjoiSGFtbWVyIHRvZSAoZGlzb3JkZXIpIiwic3lzdGVtIjoiaHR0cDovL3Nub21lZC5pbmZvL3NjdCJ9XSwidGV4dCI6IkhhbW1lciBUb2UifSwiZW5jb3VudGVyIjp7InJlZmVyZW5jZSI6Imh0dHA6Ly9leGFtcGxlLm9yZy9jZGV4L3Byb3ZpZGVyL2ZoaXIvRW5jb3VudGVyLzVmZTYyY2Q1LWJmY2YtNGQzYi1hMWU5LTgwZDZmNzVkNmY4MiJ9LCJpZCI6IjRhYzQxNzE1LWZjYmQtNDIxYy04Nzk2LTliMmM5NzA2ZGQzZiIsIm1ldGEiOnsibGFzdFVwZGF0ZWQiOiIyMDIwLTA0LTI4VDIwOjI4OjAwLjAwOCswMDowMCIsInZlcnNpb25JZCI6IjEwIn0sIm9uc2V0RGF0ZVRpbWUiOiIyMDE4LTEwLTIxVDIxOjIyOjE1LTA3OjAwIiwicmVjb3JkZWREYXRlIjoiMjAxOC0xMC0yMVQyMToyMjoxNS0wNzowMCIsInJlc291cmNlVHlwZSI6IkNvbmRpdGlvbiIsInN1YmplY3QiOnsicmVmZXJlbmNlIjoiaHR0cDovL2V4YW1wbGUub3JnL2NkZXgvcHJvdmlkZXIvZmhpci9QYXRpZW50LzA2ZTFmMGRkLTVmYmUtNDQ4MC05YmI0LTZiNTRlYzAyZDMxYiJ9LCJ0ZXh0Ijp7ImRpdiI6IjxkaXYgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI-PGEgbmFtZT1cIkNvbmRpdGlvbl80YWM0MTcxNS1mY2JkLTQyMWMtODc5Ni05YjJjOTcwNmRkM2ZcIj4gPC9hPjxwIGNsYXNzPVwicmVzLWhlYWRlci1pZFwiPjxiPkdlbmVyYXRlZCBOYXJyYXRpdmU6IENvbmRpdGlvbiA0YWM0MTcxNS1mY2JkLTQyMWMtODc5Ni05YjJjOTcwNmRkM2Y8L2I-PC9wPjxhIG5hbWU9XCI0YWM0MTcxNS1mY2JkLTQyMWMtODc5Ni05YjJjOTcwNmRkM2ZcIj4gPC9hPjxhIG5hbWU9XCJoYzRhYzQxNzE1LWZjYmQtNDIxYy04Nzk2LTliMmM5NzA2ZGQzZlwiPiA8L2E-PGEgbmFtZT1cIjRhYzQxNzE1LWZjYmQtNDIxYy04Nzk2LTliMmM5NzA2ZGQzZi1lbi1VU1wiPiA8L2E-PGRpdiBzdHlsZT1cImRpc3BsYXk6IGlubGluZS1ibG9jazsgYmFja2dyb3VuZC1jb2xvcjogI2Q5ZTBlNzsgcGFkZGluZzogNnB4OyBtYXJnaW46IDRweDsgYm9yZGVyOiAxcHggc29saWQgIzhkYTFiNDsgYm9yZGVyLXJhZGl1czogNXB4OyBsaW5lLWhlaWdodDogNjAlXCI-PHAgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAwcHhcIj52ZXJzaW9uOiAxMDsgTGFzdCB1cGRhdGVkOiAyMDIwLTA0LTI4IDIwOjI4OjAwKzAwMDA7IDwvcD48cCBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDBweFwiPkluZm9ybWF0aW9uIFNvdXJjZTogI2NhYmlKSUs1MXNEMml6NE48L3A-PC9kaXY-PHA-PGI-Y2xpbmljYWxTdGF0dXM8L2I-OiA8c3BhbiB0aXRsZT1cIkNvZGVzOntodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2NvbmRpdGlvbi1jbGluaWNhbCBhY3RpdmV9XCI-QWN0aXZlPC9zcGFuPjwvcD48cD48Yj52ZXJpZmljYXRpb25TdGF0dXM8L2I-OiA8c3BhbiB0aXRsZT1cIkNvZGVzOntodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2NvbmRpdGlvbi12ZXItc3RhdHVzIGNvbmZpcm1lZH1cIj5Db25maXJtZWQ8L3NwYW4-PC9wPjxwPjxiPmNhdGVnb3J5PC9iPjogPHNwYW4gdGl0bGU9XCJDb2Rlczp7aHR0cDovL3Rlcm1pbm9sb2d5LmhsNy5vcmcvQ29kZVN5c3RlbS9jb25kaXRpb24tY2F0ZWdvcnkgZW5jb3VudGVyLWRpYWdub3Npc31cIj5FbmNvdW50ZXIgRGlhZ25vc2lzPC9zcGFuPjwvcD48cD48Yj5jb2RlPC9iPjogPHNwYW4gdGl0bGU9XCJDb2Rlczp7aHR0cDovL3Nub21lZC5pbmZvL3NjdCAxMjI0ODEwMDh9XCI-SGFtbWVyIFRvZTwvc3Bhbj48L3A-PHA-PGI-c3ViamVjdDwvYj46IDxhIGhyZWY9XCJodHRwOi8vZXhhbXBsZS5vcmcvY2RleC9wcm92aWRlci9maGlyL1BhdGllbnQvMDZlMWYwZGQtNWZiZS00NDgwLTliYjQtNmI1NGVjMDJkMzFiXCI-aHR0cDovL2V4YW1wbGUub3JnL2NkZXgvcHJvdmlkZXIvZmhpci9QYXRpZW50LzA2ZTFmMGRkLTVmYmUtNDQ4MC05YmI0LTZiNTRlYzAyZDMxYjwvYT48L3A-PHA-PGI-ZW5jb3VudGVyPC9iPjogPGEgaHJlZj1cImh0dHA6Ly9leGFtcGxlLm9yZy9jZGV4L3Byb3ZpZGVyL2ZoaXIvRW5jb3VudGVyLzVmZTYyY2Q1LWJmY2YtNGQzYi1hMWU5LTgwZDZmNzVkNmY4MlwiPmh0dHA6Ly9leGFtcGxlLm9yZy9jZGV4L3Byb3ZpZGVyL2ZoaXIvRW5jb3VudGVyLzVmZTYyY2Q1LWJmY2YtNGQzYi1hMWU5LTgwZDZmNzVkNmY4MjwvYT48L3A-PHA-PGI-b25zZXQ8L2I-OiAyMDE4LTEwLTIxIDIxOjIyOjE1LTA3MDA8L3A-PHA-PGI-cmVjb3JkZWREYXRlPC9iPjogMjAxOC0xMC0yMSAyMToyMjoxNS0wNzAwPC9wPjwvZGl2PiIsInN0YXR1cyI6ImdlbmVyYXRlZCJ9LCJ2ZXJpZmljYXRpb25TdGF0dXMiOnsiY29kaW5nIjpbeyJjb2RlIjoiY29uZmlybWVkIiwic3lzdGVtIjoiaHR0cDovL3Rlcm1pbm9sb2d5LmhsNy5vcmcvQ29kZVN5c3RlbS9jb25kaXRpb24tdmVyLXN0YXR1cyJ9XX19LCJzZWFyY2giOnsibW9kZSI6Im1hdGNoIn19XSwibGluayI6W3sicmVsYXRpb24iOiJzZWxmIiwidXJsIjoiaHR0cDovL2hhcGkuZmhpci5vcmcvYmFzZVI0L0NvbmRpdGlvbj9wYXRpZW50PTA2ZTFmMGRkLTVmYmUtNDQ4MC05YmI0LTZiNTRlYzAyZDMxYiJ9XSwicmVzb3VyY2VUeXBlIjoiQnVuZGxlIiwidG90YWwiOjEsInR5cGUiOiJzZWFyY2hzZXQifQ signature: aN36yZ0ON-BErPZdkPGONYvW6zHkXnDSNpxos5Z8Az78nq3SAofs4THFzrPPiqll_k7NGbI1nh6gqK0QcCWWrbT1PWKwYNqUSoxyAD4h_jM3lL8zlwYBJlrl_eQK8bh2HtRC7Kwo96wyzLTGJ5cP6wyTilWTluxG8GQcYoKuT8xvFRUm8Vjpe-R_SNn9OjexmyF9jLJQq3adYpX7ybKp1JkgWClVDNXOsi9GdvdX1v-aaHvnvmW9YK_OEjoNk3ozq3XWTVRkbarTYmG3SSpsvMA0KCSyvUkk5uRO6-bYTNHx1pe1aIDeRF6LPJlyXGjQhlNjGCKqk8usI8BS37uY7XQGWHTzUtaEtEg_HmveMVlYvmGp7BjEl3mPZmOQ2GeZAfQAqHjk5jBNEWc-YMJNuzLYuAOLZiF3ehpa7jPH6a2VNbb1sKDjE7fC7MoJEiagklhZFHhw_wdE4qMlt6psDxy5OAn7DRg9d-192x0_TstuXhu5mp6nJhBlLa-2UBGm
7. Obtain public Key from the first certificate in JWS header "x5c"
key
Signature.type.code
elements SHALL contain the same values as the "srCms" header ids.Signature.when
SHALL match the "Sigt" header timestampSignature.who
SHALL match the "srCms" Signer Commitments header id.recd_header = jws.get_unverified_header(recd_jws)
recd_header
{'alg': 'RS256', 'kid': 'bfbe3e5c0470444576548113928d5f1e4e3f2eeb', 'kty': 'RS', 'sigT': '2020-10-23T04:54:56.048+00:00', 'srCms': [{'commId': {'desc': 'Verification Signature', 'id': 'urn:oid:1.2.840.10065.1.12.1.5'}, 'commQuals': ['Verification of medical record integrity']}], 'typ': 'JWT', 'x5c': ['MIIFeTCCA+GgAwIBAgIUOcFqLOBmt7VR6y4FGn00QSFMXJgwDQYJKoZIhvcNAQELBQAwgaYxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMQ8wDQYDVQQHDAZCb3N0b24xHTAbBgNVBAoMFEV4YW1wbGUgT3JnYW5pemF0aW9uMSIwIAYDVQQDDBlDREVYIEV4YW1wbGUgT3JnYW5pemF0aW9uMSswKQYJKoZIhvcNAQkBFhxjdXN0b21lci1zZXJ2aWNlQGV4YW1wbGUub3JnMB4XDTI1MDcyNDE4MTQ0MFoXDTI2MDcxOTE4MTQ0MFowgaYxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMQ8wDQYDVQQHDAZCb3N0b24xHTAbBgNVBAoMFEV4YW1wbGUgT3JnYW5pemF0aW9uMSIwIAYDVQQDDBlDREVYIEV4YW1wbGUgT3JnYW5pemF0aW9uMSswKQYJKoZIhvcNAQkBFhxjdXN0b21lci1zZXJ2aWNlQGV4YW1wbGUub3JnMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEArtyHIeEmm1Mi2iR7lRW9NPxAyS9Bh8PxE1bFKPbRo1BWdFYosDADMcxdh9juycsihFEm/t9ncBeBeLI1UuzEb/K+FW1aJnfk+aZzA21pg1z0rRj7iShpKw8f0aihzaTiaBOlSscoYDWeBy7pe5Q/eL7VRuqglZhVk7ZLSpw8xbVToFPYy2Ih56wmd4x+w4I9DSCsmiEE1wtWuZteVlgecfMsY/XzozHBTkk4Frh8Pxj/3kvYTYU52jsczAILDlpUK4ga7XGMo23QouXdFXWI8KM6XfORWCqWU+2V4B9MnjjG8jrO+OCDHQHJqBxrkMYW+GkbhBq8YOngQQH/tZ8Cj8vf0ZXEQou0LWmoVNfZYuqCGDJ5Ig0lADmm+lBwtSeM9Ppjq0fVX4/u++oo36LYinwNoBAm3rQlBNI5MUwVOrrvOhiWdYvYSj3fwCkb1aKBofFqPMr3/nS+3VOLgGp7v7atCTfWG7fxf5E8vh27y1jq3FPKPY00rNws6V3QZuNXAgMBAAGjgZwwgZkwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwYAYDVR0RBFkwV4IPd3d3LmV4YW1wbGUub3JnoBkGCWCGSAGG+VsEBqAMDAoxMjM0NTY3ODkzhilodHRwczovL2V4YW1wbGUub3JnL2ZoaXIvT3JnYW5pemF0aW9uLzEyMzAdBgNVHQ4EFgQU5u/bNQtps2mkOuYBVOF/Oax161gwDQYJKoZIhvcNAQELBQADggGBABiLOU39NEySzZSGz2aNhbMzUV5RaTwrpDxDvYjDX3jEP/jsmj4/pN+L5RYBXsBfYxSUubQLeVvkf5fv+oGrmeCW+fX8yE1rl+q81CCL+Q8LOOzAZFuEeYE9ieczY7fO18MpF8nC14CDQb6DN10QaAtbhTFakZeOqZaUgToDfINsn7jza/bpt1Keu5vUsu1qFgjApzA6+MalINUkHma2FK+z2Yfy0W/NhupbLcWEn1RyuUBTQwssm9wRPDE/LoSUA3pmmqPDl87d9tGFDK/ylQTuaql5tF02ljz8wYQiSRf5nzxqTmtnMCmvhyax75n50to/Tn4lh/j1iko+wCAWTMCNkb+m4G1msdoUYnEYn/TizW9vK3LhVTW5ZdI+uVyasdBhRLoylwYidUGCahvJfDSGk0xS74hUXb223AmziSKE3TFPxSnZEv3zi8mOkzsMSubjnpJqrnQXoBnNI8s+j0IyZQ29Zmd8CLLqmgkIOVOuacCokXvKDWkUmkByRO6LwA==']}
recd_cert = b64decode(recd_header['x5c'][0])
with open('recd_cert.der', 'wb') as f:
f.write(recd_cert)
!openssl x509 -in recd_cert.der -inform DER -text
Certificate: Data: Version: 3 (0x2) Serial Number: 39:c1:6a:2c:e0:66:b7:b5:51:eb:2e:05:1a:7d:34:41:21:4c:5c:98 Signature Algorithm: sha256WithRSAEncryption Issuer: C=US, ST=Massachusetts, L=Boston, O=Example Organization, CN=CDEX Example Organization, emailAddress=customer-service@example.org Validity Not Before: Jul 24 18:14:40 2025 GMT Not After : Jul 19 18:14:40 2026 GMT Subject: C=US, ST=Massachusetts, L=Boston, O=Example Organization, CN=CDEX Example Organization, emailAddress=customer-service@example.org Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (3072 bit) Modulus: 00:ae:dc:87:21:e1:26:9b:53:22:da:24:7b:95:15: bd:34:fc:40:c9:2f:41:87:c3:f1:13:56:c5:28:f6: d1:a3:50:56:74:56:28:b0:30:03:31:cc:5d:87:d8: ee:c9:cb:22:84:51:26:fe:df:67:70:17:81:78:b2: 35:52:ec:c4:6f:f2:be:15:6d:5a:26:77:e4:f9:a6: 73:03:6d:69:83:5c:f4:ad:18:fb:89:28:69:2b:0f: 1f:d1:a8:a1:cd:a4:e2:68:13:a5:4a:c7:28:60:35: 9e:07:2e:e9:7b:94:3f:78:be:d5:46:ea:a0:95:98: 55:93:b6:4b:4a:9c:3c:c5:b5:53:a0:53:d8:cb:62: 21:e7:ac:26:77:8c:7e:c3:82:3d:0d:20:ac:9a:21: 04:d7:0b:56:b9:9b:5e:56:58:1e:71:f3:2c:63:f5: f3:a3:31:c1:4e:49:38:16:b8:7c:3f:18:ff:de:4b: d8:4d:85:39:da:3b:1c:cc:02:0b:0e:5a:54:2b:88: 1a:ed:71:8c:a3:6d:d0:a2:e5:dd:15:75:88:f0:a3: 3a:5d:f3:91:58:2a:96:53:ed:95:e0:1f:4c:9e:38: c6:f2:3a:ce:f8:e0:83:1d:01:c9:a8:1c:6b:90:c6: 16:f8:69:1b:84:1a:bc:60:e9:e0:41:01:ff:b5:9f: 02:8f:cb:df:d1:95:c4:42:8b:b4:2d:69:a8:54:d7: d9:62:ea:82:18:32:79:22:0d:25:00:39:a6:fa:50: 70:b5:27:8c:f4:fa:63:ab:47:d5:5f:8f:ee:fb:ea: 28:df:a2:d8:8a:7c:0d:a0:10:26:de:b4:25:04:d2: 39:31:4c:15:3a:ba:ef:3a:18:96:75:8b:d8:4a:3d: df:c0:29:1b:d5:a2:81:a1:f1:6a:3c:ca:f7:fe:74: be:dd:53:8b:80:6a:7b:bf:b6:ad:09:37:d6:1b:b7: f1:7f:91:3c:be:1d:bb:cb:58:ea:dc:53:ca:3d:8d: 34:ac:dc:2c:e9:5d:d0:66:e3:57 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Alternative Name: DNS:www.example.org, othername: 2.16.840.1.113883.4.6:1234567893, URI:https://example.org/fhir/Organization/123 X509v3 Subject Key Identifier: E6:EF:DB:35:0B:69:B3:69:A4:3A:E6:01:54:E1:7F:39:AC:75:EB:58 Signature Algorithm: sha256WithRSAEncryption Signature Value: 18:8b:39:4d:fd:34:4c:92:cd:94:86:cf:66:8d:85:b3:33:51: 5e:51:69:3c:2b:a4:3c:43:bd:88:c3:5f:78:c4:3f:f8:ec:9a: 3e:3f:a4:df:8b:e5:16:01:5e:c0:5f:63:14:94:b9:b4:0b:79: 5b:e4:7f:97:ef:fa:81:ab:99:e0:96:f9:f5:fc:c8:4d:6b:97: ea:bc:d4:20:8b:f9:0f:0b:38:ec:c0:64:5b:84:79:81:3d:89: e7:33:63:b7:ce:d7:c3:29:17:c9:c2:d7:80:83:41:be:83:37: 5d:10:68:0b:5b:85:31:5a:91:97:8e:a9:96:94:81:3a:03:7c: 83:6c:9f:b8:f3:6b:f6:e9:b7:52:9e:bb:9b:d4:b2:ed:6a:16: 08:c0:a7:30:3a:f8:c6:a5:20:d5:24:1e:66:b6:14:af:b3:d9: 87:f2:d1:6f:cd:86:ea:5b:2d:c5:84:9f:54:72:b9:40:53:43: 0b:2c:9b:dc:11:3c:31:3f:2e:84:94:03:7a:66:9a:a3:c3:97: ce:dd:f6:d1:85:0c:af:f2:95:04:ee:6a:a9:79:b4:5d:36:96: 3c:fc:c1:84:22:49:17:f9:9f:3c:6a:4e:6b:67:30:29:af:87: 26:b1:ef:99:f9:d2:da:3f:4e:7e:25:87:f8:f5:8a:4a:3e:c0: 20:16:4c:c0:8d:91:bf:a6:e0:6d:66:b1:da:14:62:71:18:9f: f4:e2:cd:6f:6f:2b:72:e1:55:35:b9:65:d2:3e:b9:5c:9a:b1: d0:61:44:ba:32:97:06:22:75:41:82:6a:1b:c9:7c:34:86:93: 4c:52:ef:88:54:5d:bd:b6:dc:09:b3:89:22:84:dd:31:4f:c5: 29:d9:12:fd:f3:8b:c9:8e:93:3b:0c:4a:e6:e3:9e:92:6a:ae: 74:17:a0:19:cd:23:cb:3e:8f:42:32:65:0d:bd:66:67:7c:08: b2:ea:9a:09:08:39:53:ae:69:c0:a8:91:7b:ca:0d:69:14:9a: 40:72:44:ee:8b:c0 -----BEGIN CERTIFICATE----- MIIFeTCCA+GgAwIBAgIUOcFqLOBmt7VR6y4FGn00QSFMXJgwDQYJKoZIhvcNAQEL BQAwgaYxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMQ8wDQYD VQQHDAZCb3N0b24xHTAbBgNVBAoMFEV4YW1wbGUgT3JnYW5pemF0aW9uMSIwIAYD VQQDDBlDREVYIEV4YW1wbGUgT3JnYW5pemF0aW9uMSswKQYJKoZIhvcNAQkBFhxj dXN0b21lci1zZXJ2aWNlQGV4YW1wbGUub3JnMB4XDTI1MDcyNDE4MTQ0MFoXDTI2 MDcxOTE4MTQ0MFowgaYxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNl dHRzMQ8wDQYDVQQHDAZCb3N0b24xHTAbBgNVBAoMFEV4YW1wbGUgT3JnYW5pemF0 aW9uMSIwIAYDVQQDDBlDREVYIEV4YW1wbGUgT3JnYW5pemF0aW9uMSswKQYJKoZI hvcNAQkBFhxjdXN0b21lci1zZXJ2aWNlQGV4YW1wbGUub3JnMIIBojANBgkqhkiG 9w0BAQEFAAOCAY8AMIIBigKCAYEArtyHIeEmm1Mi2iR7lRW9NPxAyS9Bh8PxE1bF KPbRo1BWdFYosDADMcxdh9juycsihFEm/t9ncBeBeLI1UuzEb/K+FW1aJnfk+aZz A21pg1z0rRj7iShpKw8f0aihzaTiaBOlSscoYDWeBy7pe5Q/eL7VRuqglZhVk7ZL Spw8xbVToFPYy2Ih56wmd4x+w4I9DSCsmiEE1wtWuZteVlgecfMsY/XzozHBTkk4 Frh8Pxj/3kvYTYU52jsczAILDlpUK4ga7XGMo23QouXdFXWI8KM6XfORWCqWU+2V 4B9MnjjG8jrO+OCDHQHJqBxrkMYW+GkbhBq8YOngQQH/tZ8Cj8vf0ZXEQou0LWmo VNfZYuqCGDJ5Ig0lADmm+lBwtSeM9Ppjq0fVX4/u++oo36LYinwNoBAm3rQlBNI5 MUwVOrrvOhiWdYvYSj3fwCkb1aKBofFqPMr3/nS+3VOLgGp7v7atCTfWG7fxf5E8 vh27y1jq3FPKPY00rNws6V3QZuNXAgMBAAGjgZwwgZkwCQYDVR0TBAIwADALBgNV HQ8EBAMCBeAwYAYDVR0RBFkwV4IPd3d3LmV4YW1wbGUub3JnoBkGCWCGSAGG+VsE BqAMDAoxMjM0NTY3ODkzhilodHRwczovL2V4YW1wbGUub3JnL2ZoaXIvT3JnYW5p emF0aW9uLzEyMzAdBgNVHQ4EFgQU5u/bNQtps2mkOuYBVOF/Oax161gwDQYJKoZI hvcNAQELBQADggGBABiLOU39NEySzZSGz2aNhbMzUV5RaTwrpDxDvYjDX3jEP/js mj4/pN+L5RYBXsBfYxSUubQLeVvkf5fv+oGrmeCW+fX8yE1rl+q81CCL+Q8LOOzA ZFuEeYE9ieczY7fO18MpF8nC14CDQb6DN10QaAtbhTFakZeOqZaUgToDfINsn7jz a/bpt1Keu5vUsu1qFgjApzA6+MalINUkHma2FK+z2Yfy0W/NhupbLcWEn1RyuUBT Qwssm9wRPDE/LoSUA3pmmqPDl87d9tGFDK/ylQTuaql5tF02ljz8wYQiSRf5nzxq TmtnMCmvhyax75n50to/Tn4lh/j1iko+wCAWTMCNkb+m4G1msdoUYnEYn/TizW9v K3LhVTW5ZdI+uVyasdBhRLoylwYidUGCahvJfDSGk0xS74hUXb223AmziSKE3TFP xSnZEv3zi8mOkzsMSubjnpJqrnQXoBnNI8s+j0IyZQ29Zmd8CLLqmgkIOVOuacCo kXvKDWkUmkByRO6LwA== -----END CERTIFICATE-----
10. Verify Signature using the public key or the X.509 Certificate
Alternatively:
recd_jws
'eyJhbGciOiJSUzI1NiIsImtpZCI6ImJmYmUzZTVjMDQ3MDQ0NDU3NjU0ODExMzkyOGQ1ZjFlNGUzZjJlZWIiLCJrdHkiOiJSUyIsInNpZ1QiOiIyMDIwLTEwLTIzVDA0OjU0OjU2LjA0OCswMDowMCIsInNyQ21zIjpbeyJjb21tSWQiOnsiZGVzYyI6IlZlcmlmaWNhdGlvbiBTaWduYXR1cmUiLCJpZCI6InVybjpvaWQ6MS4yLjg0MC4xMDA2NS4xLjEyLjEuNSJ9LCJjb21tUXVhbHMiOlsiVmVyaWZpY2F0aW9uIG9mIG1lZGljYWwgcmVjb3JkIGludGVncml0eSJdfV0sInR5cCI6IkpXVCIsIng1YyI6WyJNSUlGZVRDQ0ErR2dBd0lCQWdJVU9jRnFMT0JtdDdWUjZ5NEZHbjAwUVNGTVhKZ3dEUVlKS29aSWh2Y05BUUVMQlFBd2dhWXhDekFKQmdOVkJBWVRBbFZUTVJZd0ZBWURWUVFJREExTllYTnpZV05vZFhObGRIUnpNUTh3RFFZRFZRUUhEQVpDYjNOMGIyNHhIVEFiQmdOVkJBb01GRVY0WVcxd2JHVWdUM0puWVc1cGVtRjBhVzl1TVNJd0lBWURWUVFEREJsRFJFVllJRVY0WVcxd2JHVWdUM0puWVc1cGVtRjBhVzl1TVNzd0tRWUpLb1pJaHZjTkFRa0JGaHhqZFhOMGIyMWxjaTF6WlhKMmFXTmxRR1Y0WVcxd2JHVXViM0puTUI0WERUSTFNRGN5TkRFNE1UUTBNRm9YRFRJMk1EY3hPVEU0TVRRME1Gb3dnYVl4Q3pBSkJnTlZCQVlUQWxWVE1SWXdGQVlEVlFRSURBMU5ZWE56WVdOb2RYTmxkSFJ6TVE4d0RRWURWUVFIREFaQ2IzTjBiMjR4SFRBYkJnTlZCQW9NRkVWNFlXMXdiR1VnVDNKbllXNXBlbUYwYVc5dU1TSXdJQVlEVlFRRERCbERSRVZZSUVWNFlXMXdiR1VnVDNKbllXNXBlbUYwYVc5dU1Tc3dLUVlKS29aSWh2Y05BUWtCRmh4amRYTjBiMjFsY2kxelpYSjJhV05sUUdWNFlXMXdiR1V1YjNKbk1JSUJvakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBWThBTUlJQmlnS0NBWUVBcnR5SEllRW1tMU1pMmlSN2xSVzlOUHhBeVM5Qmg4UHhFMWJGS1BiUm8xQldkRllvc0RBRE1jeGRoOWp1eWNzaWhGRW0vdDluY0JlQmVMSTFVdXpFYi9LK0ZXMWFKbmZrK2FaekEyMXBnMXowclJqN2lTaHBLdzhmMGFpaHphVGlhQk9sU3Njb1lEV2VCeTdwZTVRL2VMN1ZSdXFnbFpoVms3WkxTcHc4eGJWVG9GUFl5MkloNTZ3bWQ0eCt3NEk5RFNDc21pRUUxd3RXdVp0ZVZsZ2VjZk1zWS9Yem96SEJUa2s0RnJoOFB4ai8za3ZZVFlVNTJqc2N6QUlMRGxwVUs0Z2E3WEdNbzIzUW91WGRGWFdJOEtNNlhmT1JXQ3FXVSsyVjRCOU1uampHOGpyTytPQ0RIUUhKcUJ4cmtNWVcrR2tiaEJxOFlPbmdRUUgvdFo4Q2o4dmYwWlhFUW91MExXbW9WTmZaWXVxQ0dESjVJZzBsQURtbStsQnd0U2VNOVBwanEwZlZYNC91KytvbzM2TFlpbndOb0JBbTNyUWxCTkk1TVV3Vk9ycnZPaGlXZFl2WVNqM2Z3Q2tiMWFLQm9mRnFQTXIzL25TKzNWT0xnR3A3djdhdENUZldHN2Z4ZjVFOHZoMjd5MWpxM0ZQS1BZMDByTndzNlYzUVp1TlhBZ01CQUFHamdad3dnWmt3Q1FZRFZSMFRCQUl3QURBTEJnTlZIUThFQkFNQ0JlQXdZQVlEVlIwUkJGa3dWNElQZDNkM0xtVjRZVzF3YkdVdWIzSm5vQmtHQ1dDR1NBR0crVnNFQnFBTURBb3hNak0wTlRZM09Ea3poaWxvZEhSd2N6b3ZMMlY0WVcxd2JHVXViM0puTDJab2FYSXZUM0puWVc1cGVtRjBhVzl1THpFeU16QWRCZ05WSFE0RUZnUVU1dS9iTlF0cHMybWtPdVlCVk9GL09heDE2MWd3RFFZSktvWklodmNOQVFFTEJRQURnZ0dCQUJpTE9VMzlORXlTelpTR3oyYU5oYk16VVY1UmFUd3JwRHhEdllqRFgzakVQL2pzbWo0L3BOK0w1UllCWHNCZll4U1V1YlFMZVZ2a2Y1ZnYrb0dybWVDVytmWDh5RTFybCtxODFDQ0wrUThMT096QVpGdUVlWUU5aWVjelk3Zk8xOE1wRjhuQzE0Q0RRYjZETjEwUWFBdGJoVEZha1plT3FaYVVnVG9EZklOc243anphL2JwdDFLZXU1dlVzdTFxRmdqQXB6QTYrTWFsSU5Va0htYTJGSyt6MllmeTBXL05odXBiTGNXRW4xUnl1VUJUUXdzc205d1JQREUvTG9TVUEzcG1tcVBEbDg3ZDl0R0ZESy95bFFUdWFxbDV0RjAybGp6OHdZUWlTUmY1bnp4cVRtdG5NQ212aHlheDc1bjUwdG8vVG40bGgvajFpa28rd0NBV1RNQ05rYittNEcxbXNkb1VZbkVZbi9UaXpXOXZLM0xoVlRXNVpkSSt1Vnlhc2RCaFJMb3lsd1lpZFVHQ2FodkpmRFNHazB4Uzc0aFVYYjIyM0FtemlTS0UzVEZQeFNuWkV2M3ppOG1Pa3pzTVN1YmpucEpxcm5RWG9Cbk5JOHMrajBJeVpRMjlabWQ4Q0xMcW1na0lPVk91YWNDb2tYdktEV2tVbWtCeVJPNkx3QT09Il19.eyJlbnRyeSI6W3siZnVsbFVybCI6Imh0dHA6Ly9oYXBpLmZoaXIub3JnL2Jhc2VSNC9Db25kaXRpb24vNGFjNDE3MTUtZmNiZC00MjFjLTg3OTYtOWIyYzk3MDZkZDNmIiwicmVzb3VyY2UiOnsiY2F0ZWdvcnkiOlt7ImNvZGluZyI6W3siY29kZSI6ImVuY291bnRlci1kaWFnbm9zaXMiLCJkaXNwbGF5IjoiRW5jb3VudGVyIERpYWdub3NpcyIsInN5c3RlbSI6Imh0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vY29uZGl0aW9uLWNhdGVnb3J5In1dfV0sImNsaW5pY2FsU3RhdHVzIjp7ImNvZGluZyI6W3siY29kZSI6ImFjdGl2ZSIsInN5c3RlbSI6Imh0dHA6Ly90ZXJtaW5vbG9neS5obDcub3JnL0NvZGVTeXN0ZW0vY29uZGl0aW9uLWNsaW5pY2FsIn1dfSwiY29kZSI6eyJjb2RpbmciOlt7ImNvZGUiOiIxMjI0ODEwMDgiLCJkaXNwbGF5IjoiSGFtbWVyIHRvZSAoZGlzb3JkZXIpIiwic3lzdGVtIjoiaHR0cDovL3Nub21lZC5pbmZvL3NjdCJ9XSwidGV4dCI6IkhhbW1lciBUb2UifSwiZW5jb3VudGVyIjp7InJlZmVyZW5jZSI6Imh0dHA6Ly9leGFtcGxlLm9yZy9jZGV4L3Byb3ZpZGVyL2ZoaXIvRW5jb3VudGVyLzVmZTYyY2Q1LWJmY2YtNGQzYi1hMWU5LTgwZDZmNzVkNmY4MiJ9LCJpZCI6IjRhYzQxNzE1LWZjYmQtNDIxYy04Nzk2LTliMmM5NzA2ZGQzZiIsIm1ldGEiOnsibGFzdFVwZGF0ZWQiOiIyMDIwLTA0LTI4VDIwOjI4OjAwLjAwOCswMDowMCIsInZlcnNpb25JZCI6IjEwIn0sIm9uc2V0RGF0ZVRpbWUiOiIyMDE4LTEwLTIxVDIxOjIyOjE1LTA3OjAwIiwicmVjb3JkZWREYXRlIjoiMjAxOC0xMC0yMVQyMToyMjoxNS0wNzowMCIsInJlc291cmNlVHlwZSI6IkNvbmRpdGlvbiIsInN1YmplY3QiOnsicmVmZXJlbmNlIjoiaHR0cDovL2V4YW1wbGUub3JnL2NkZXgvcHJvdmlkZXIvZmhpci9QYXRpZW50LzA2ZTFmMGRkLTVmYmUtNDQ4MC05YmI0LTZiNTRlYzAyZDMxYiJ9LCJ0ZXh0Ijp7ImRpdiI6IjxkaXYgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI-PGEgbmFtZT1cIkNvbmRpdGlvbl80YWM0MTcxNS1mY2JkLTQyMWMtODc5Ni05YjJjOTcwNmRkM2ZcIj4gPC9hPjxwIGNsYXNzPVwicmVzLWhlYWRlci1pZFwiPjxiPkdlbmVyYXRlZCBOYXJyYXRpdmU6IENvbmRpdGlvbiA0YWM0MTcxNS1mY2JkLTQyMWMtODc5Ni05YjJjOTcwNmRkM2Y8L2I-PC9wPjxhIG5hbWU9XCI0YWM0MTcxNS1mY2JkLTQyMWMtODc5Ni05YjJjOTcwNmRkM2ZcIj4gPC9hPjxhIG5hbWU9XCJoYzRhYzQxNzE1LWZjYmQtNDIxYy04Nzk2LTliMmM5NzA2ZGQzZlwiPiA8L2E-PGEgbmFtZT1cIjRhYzQxNzE1LWZjYmQtNDIxYy04Nzk2LTliMmM5NzA2ZGQzZi1lbi1VU1wiPiA8L2E-PGRpdiBzdHlsZT1cImRpc3BsYXk6IGlubGluZS1ibG9jazsgYmFja2dyb3VuZC1jb2xvcjogI2Q5ZTBlNzsgcGFkZGluZzogNnB4OyBtYXJnaW46IDRweDsgYm9yZGVyOiAxcHggc29saWQgIzhkYTFiNDsgYm9yZGVyLXJhZGl1czogNXB4OyBsaW5lLWhlaWdodDogNjAlXCI-PHAgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAwcHhcIj52ZXJzaW9uOiAxMDsgTGFzdCB1cGRhdGVkOiAyMDIwLTA0LTI4IDIwOjI4OjAwKzAwMDA7IDwvcD48cCBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDBweFwiPkluZm9ybWF0aW9uIFNvdXJjZTogI2NhYmlKSUs1MXNEMml6NE48L3A-PC9kaXY-PHA-PGI-Y2xpbmljYWxTdGF0dXM8L2I-OiA8c3BhbiB0aXRsZT1cIkNvZGVzOntodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2NvbmRpdGlvbi1jbGluaWNhbCBhY3RpdmV9XCI-QWN0aXZlPC9zcGFuPjwvcD48cD48Yj52ZXJpZmljYXRpb25TdGF0dXM8L2I-OiA8c3BhbiB0aXRsZT1cIkNvZGVzOntodHRwOi8vdGVybWlub2xvZ3kuaGw3Lm9yZy9Db2RlU3lzdGVtL2NvbmRpdGlvbi12ZXItc3RhdHVzIGNvbmZpcm1lZH1cIj5Db25maXJtZWQ8L3NwYW4-PC9wPjxwPjxiPmNhdGVnb3J5PC9iPjogPHNwYW4gdGl0bGU9XCJDb2Rlczp7aHR0cDovL3Rlcm1pbm9sb2d5LmhsNy5vcmcvQ29kZVN5c3RlbS9jb25kaXRpb24tY2F0ZWdvcnkgZW5jb3VudGVyLWRpYWdub3Npc31cIj5FbmNvdW50ZXIgRGlhZ25vc2lzPC9zcGFuPjwvcD48cD48Yj5jb2RlPC9iPjogPHNwYW4gdGl0bGU9XCJDb2Rlczp7aHR0cDovL3Nub21lZC5pbmZvL3NjdCAxMjI0ODEwMDh9XCI-SGFtbWVyIFRvZTwvc3Bhbj48L3A-PHA-PGI-c3ViamVjdDwvYj46IDxhIGhyZWY9XCJodHRwOi8vZXhhbXBsZS5vcmcvY2RleC9wcm92aWRlci9maGlyL1BhdGllbnQvMDZlMWYwZGQtNWZiZS00NDgwLTliYjQtNmI1NGVjMDJkMzFiXCI-aHR0cDovL2V4YW1wbGUub3JnL2NkZXgvcHJvdmlkZXIvZmhpci9QYXRpZW50LzA2ZTFmMGRkLTVmYmUtNDQ4MC05YmI0LTZiNTRlYzAyZDMxYjwvYT48L3A-PHA-PGI-ZW5jb3VudGVyPC9iPjogPGEgaHJlZj1cImh0dHA6Ly9leGFtcGxlLm9yZy9jZGV4L3Byb3ZpZGVyL2ZoaXIvRW5jb3VudGVyLzVmZTYyY2Q1LWJmY2YtNGQzYi1hMWU5LTgwZDZmNzVkNmY4MlwiPmh0dHA6Ly9leGFtcGxlLm9yZy9jZGV4L3Byb3ZpZGVyL2ZoaXIvRW5jb3VudGVyLzVmZTYyY2Q1LWJmY2YtNGQzYi1hMWU5LTgwZDZmNzVkNmY4MjwvYT48L3A-PHA-PGI-b25zZXQ8L2I-OiAyMDE4LTEwLTIxIDIxOjIyOjE1LTA3MDA8L3A-PHA-PGI-cmVjb3JkZWREYXRlPC9iPjogMjAxOC0xMC0yMSAyMToyMjoxNS0wNzAwPC9wPjwvZGl2PiIsInN0YXR1cyI6ImdlbmVyYXRlZCJ9LCJ2ZXJpZmljYXRpb25TdGF0dXMiOnsiY29kaW5nIjpbeyJjb2RlIjoiY29uZmlybWVkIiwic3lzdGVtIjoiaHR0cDovL3Rlcm1pbm9sb2d5LmhsNy5vcmcvQ29kZVN5c3RlbS9jb25kaXRpb24tdmVyLXN0YXR1cyJ9XX19LCJzZWFyY2giOnsibW9kZSI6Im1hdGNoIn19XSwibGluayI6W3sicmVsYXRpb24iOiJzZWxmIiwidXJsIjoiaHR0cDovL2hhcGkuZmhpci5vcmcvYmFzZVI0L0NvbmRpdGlvbj9wYXRpZW50PTA2ZTFmMGRkLTVmYmUtNDQ4MC05YmI0LTZiNTRlYzAyZDMxYiJ9XSwicmVzb3VyY2VUeXBlIjoiQnVuZGxlIiwidG90YWwiOjEsInR5cGUiOiJzZWFyY2hzZXQifQ.aN36yZ0ON-BErPZdkPGONYvW6zHkXnDSNpxos5Z8Az78nq3SAofs4THFzrPPiqll_k7NGbI1nh6gqK0QcCWWrbT1PWKwYNqUSoxyAD4h_jM3lL8zlwYBJlrl_eQK8bh2HtRC7Kwo96wyzLTGJ5cP6wyTilWTluxG8GQcYoKuT8xvFRUm8Vjpe-R_SNn9OjexmyF9jLJQq3adYpX7ybKp1JkgWClVDNXOsi9GdvdX1v-aaHvnvmW9YK_OEjoNk3ozq3XWTVRkbarTYmG3SSpsvMA0KCSyvUkk5uRO6-bYTNHx1pe1aIDeRF6LPJlyXGjQhlNjGCKqk8usI8BS37uY7XQGWHTzUtaEtEg_HmveMVlYvmGp7BjEl3mPZmOQ2GeZAfQAqHjk5jBNEWc-YMJNuzLYuAOLZiF3ehpa7jPH6a2VNbb1sKDjE7fC7MoJEiagklhZFHhw_wdE4qMlt6psDxy5OAn7DRg9d-192x0_TstuXhu5mp6nJhBlLa-2UBGm'
!openssl x509 -in recd_cert.der -inform DER -pubkey -noout > recd-public-key.pem
with open('recd-public-key.pem') as f:
pem_public = f.read()
pem_public
'-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEArtyHIeEmm1Mi2iR7lRW9\nNPxAyS9Bh8PxE1bFKPbRo1BWdFYosDADMcxdh9juycsihFEm/t9ncBeBeLI1UuzE\nb/K+FW1aJnfk+aZzA21pg1z0rRj7iShpKw8f0aihzaTiaBOlSscoYDWeBy7pe5Q/\neL7VRuqglZhVk7ZLSpw8xbVToFPYy2Ih56wmd4x+w4I9DSCsmiEE1wtWuZteVlge\ncfMsY/XzozHBTkk4Frh8Pxj/3kvYTYU52jsczAILDlpUK4ga7XGMo23QouXdFXWI\n8KM6XfORWCqWU+2V4B9MnjjG8jrO+OCDHQHJqBxrkMYW+GkbhBq8YOngQQH/tZ8C\nj8vf0ZXEQou0LWmoVNfZYuqCGDJ5Ig0lADmm+lBwtSeM9Ppjq0fVX4/u++oo36LY\ninwNoBAm3rQlBNI5MUwVOrrvOhiWdYvYSj3fwCkb1aKBofFqPMr3/nS+3VOLgGp7\nv7atCTfWG7fxf5E8vh27y1jq3FPKPY00rNws6V3QZuNXAgMBAAE=\n-----END PUBLIC KEY-----\n'
try:
verify = jws.verify(recd_jws, pem_public , algorithms=['RS256'])
print('# # ### ')
print('# # ###### ##### # ###### # ###### ##### ### ')
print('# # # # # # # # # # # ### ')
print('# # ##### # # # ##### # ##### # # # ')
print(' # # # ##### # # # # # # ')
print(' # # # # # # # # # # # ### ')
print(' # ###### # # # # # ###### ##### ### ')
print(' ')
except Exception as e:
print('# # #### ##### # # ###### ##### # ###### # ###### ##### ### # ')
print('## # # # # # # # # # # # # # # # # # ')
print('# # # # # # # # ##### # # # ##### # ##### # # ##### # ')
print('# # # # # # # # # ##### # # # # # # # # ')
print('# ## # # # # # # # # # # # # # # ### # ')
print('# # #### # ## ###### # # # # # ###### ##### # ## ')
print(' ')
print(f"not verified: {e}")
# # ### # # ###### ##### # ###### # ###### ##### ### # # # # # # # # # # # ### # # ##### # # # ##### # ##### # # # # # # ##### # # # # # # # # # # # # # # # # # ### # ###### # # # # # ###### ##### ###