App

Monocle Assessment Decryption

In order to use the Monocle Assessment directly (as outlined in the previous section), you must decrypt the encrypted Monocle Assessment in one of two ways.

For either case, you can find your secret keys in the Monocle Dashboard for your application.

image

Note

In the code snippets below, we hardcode these keys for example purposes. In production environments, you should store these secrets securely.

Decryption API

You may use the Decryption API to decrypt the encrypted Monocle Assessment. This is often a simpler backend integration than manually handling decryption, but it requires an API call from your backend.

You must send a POST request with the encrypted Monocle Assessment (along with your Secret Key in a TOKEN HTTP header) to our Decrypt API at https://decrypt.mcl.spur.us/api/v1/assessment.

The response to this request will contain the decrypted Monocle Assessment.

curl -X POST "https://decrypt.mcl.spur.us/api/v1/assessment" \
-H "Content-type: text/plain; charset=utf-8" \
-H "TOKEN: <MONOCLE SECRET KEY>" \
--data "<MONOCLE ENCRYPTED BUNDLE>"

Backend Decryption

As an alternative to the Decryption API (which requires an additional web request from your backend), you may choose to directly decrypt the Monocle Assessment yourself using your Monocle Private Key.

Note

Don't see your backend's language or framework here? That's okay! The encrypted Monocle Assessment is simply a JWE with its payload encrypted using A256GCM and its content encryption key derived via ECDH-ES. Most languages will have JWT frameworks that support this decryption.

import json
from jwcrypto import jwe, jwk
# sample encrypted Monocle Assessment (no newlines)
sample_bundle = \
"eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImVwayI6eyJrdHkiOiJF"\
"QyIsImNydiI6IlAtNTIxIiwieCI6IkFkY3Z2WjBPRDBWelIyaE1jUXZjZkUweDBE"\
"NHE0aktCRE0tdGtaaG54SFhvUExNRjlQTzdpZ2J0MHlDM05tVENDTEFRRzRzQlRm"\
"Q3BiS3dLZjB0ck0zWjYiLCJ5IjoiQWFjZXg3Tkxtall2VnBwbXlqejdhR0pNNlk0"\
"SnhoNTRGa1ZpRU96TGJQRVpWcGY3ZmlSZHNnd2ZkMEh1Y2FQYjEzR0Y5WTB3WmdG"\
"NllWU3lVb19Pb1RUeiJ9fQ..B1oU-6ar27Q7nOdV.FhjPVZRGAwBO3pdCTAX20kj"\
"ahrcQIV-4bdRnBmSJOatwsiPRPfvAS8z-25aloAPyfBkghiWktJR72jhH7Dxvgj-"\
"2b1tfAXSXFnOYqDzZ8ryYCsDUqWhuPJBnccL4QsccWqfqtVOiSN2EtRTDMfu54Gg"\
"Dnf5eqYy0BDCvDB2E9_a1dq8ONUNwLsVA6pBALNGv2Hp-1QHxxShxX_TdxdNzRqB"\
"clk9JO2Fa4UQ.2PzCpZMEjyvk9MXOLCX82A"
# private key provided by Monocle upon registration (with newlines)
privkey_pem = """\
-----BEGIN PRIVATE KEY-----
MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIAoE6JDdiy5N3xIrrd
WUmSOSRkWG0o2ZtfkMqGl23RwR/tDQg/tuQidUezKBDsw1SESECBnmE7EehKYLKF
qEMO52ChgYkDgYYABADRviNCd7qMJWQU/J1XhXMruGkr9jCs9XXbVw6sw880AwQk
s/kTkLibL6a1KLWwsDv/Ckdt+Nva1vPZh45wOozqvwE0cZoYVB7PqjzVgO3sB/Kw
VjYnkg8SSMrmetbf/8QeVAy5579uxgkcB3UHp6OuvS/2lqznihQ1zO2yzTf9jR6w
9A==
-----END PRIVATE KEY-----
"""
# instantiate JWK
key = jwk.JWK.from_pem(bytes(privkey_pem.encode("utf-8")))
# instantiate JWE
jwetoken = jwe.JWE()
# deserialize and decrypt compact JWE
jwetoken.deserialize(sample_bundle, key=key)
# decode payload to string
bundle = jwetoken.payload.decode("utf-8")
# load bundle string into JSON and pretty print
print(
json.dumps(
json.loads(bundle),
indent=4
)
)
"""
{
"vpn": true,
"proxied": false,
"anon": true,
"ip": "37.19.221.165",
"ts": "2022-12-01T01:00:50Z",
"complete": true,
"id": "0a3e401a-b0d5-496b-b1ff-6cb8eca542a2",
"sid": "example-form"
}
"""