Closed sgbaird closed 1 year ago
Perhaps MongoDB generates a unique API key, the Pico W uses cryptolib with a manually generated value as the encryption/decryption key to encrypt the unique device ID, and the Pico W checks to make sure this matches the expected value:
user_keys = ["abc123", "def456"]
...
my_id = my_id = hexlify(unique_id()).decode()
...
mode = 1
encrypted_device_IDs = [aes(my_id).encrypt(user_key, mode) for user_key in user_keys]
...
...
assert _input_message["encrypted_device_ID"] in encrypted_device_IDs
EDIT: ah, still the same issue where the "password" is getting exposed over a public MQTT server, but the actual device ID is hidden.
On the application side, use a Python package (cryptography?) to do the encryption in the same AES mode as cryptolib.
Summary: | Value | Purpose |
---|---|---|
MongoDB API key | database access | |
Unique device ID (or manually generated ID) | private data to be encrypted/decrypted | |
user-assigned encryption key | key for encrypting/decrypting device ID by client/device, respectively |
This is harder than I thought via MicroPython. https://github.com/artem-smotrakov/micropython-rsa-signing comes with little documentation and may not be robust. There's an RSA library for CircuitPython, but I'm still hesitant to move back to CircuitPython. I could set up a web app on something like pythonanywhere, but pythonanywhere free accounts are restricted to a whitelist of websites. test.mosquitto.org has an option for certification, but it expires after 90 days and needs to be manually renewed on the website.
Related:
I'll see if I can get micropython-rsa-signing
working via referencing the python-rsa
instructions.
EDIT: got as far as:
from rsa.key import PrivateKey
from rsa import pkcs1
q=1640646288909657487095359180022062734411738001375224362146789767743298223
e=65537
d=3932070503866894845499545149242528634855814001291977329776170446942801119476224356319257882634777292449414158422402140416944887130847435068069262510801361
p=4287309565142106169103473694063731192260977968066421817319213385543808560298868219
n=7033958527457273924268579824377868739560691183608262863345913379771000030685205506298398376078296576269289512487456279410830335887754385753052069093874837
privkey = PrivateKey(n, e, d, p, q)
signature = pkcs1.sign("hello".encode('utf8'), privkey, 'SHA-256')
print(signature)
where the integers were generated via python-rsa, and I realized that it doesn't seem to support a PublicKey class nor an easy way to encrypt/decrypt, just to sign with the private key (?).
Tracking discussion at https://github.com/orgs/micropython/discussions/10048.
Seems my options are:
python-rsa
) via Vercel (https://vercel.com/docs/rest-api). Related: the "firewall" for multi-device control. See also commentary on VercelWill try waiting it out for now.
Someone got back to me on the MicroPython forums with a solution (https://github.com/dmazzella/ucrypto) that seems to be working.
Planning to leave the value of e
set to what it's in the examples (65537
) based on discussion at:
EDIT: related to secure handshakes https://github.com/sparks-baird/self-driving-lab-demo/discussions/127#discussioncomment-4320010 (use of HiveMQ)
Hardware validation now takes place by restricting the publication of documents to certain collections to specific API keys. Additionally, an encrypted, truncated device ID and a device nickname are stored in each document.
Assigning one MongoDB API key and one MongoDB collection per device is good enough. However, asymmetric encryption could still play a role at some point (hence leaving the functionality mostly there, including the storing of a truncated, encrypted device ID).
Related:
Based on discussion with @rekumar https://github.com/sparks-baird/self-driving-lab-demo/discussions/127#discussioncomment-4198692:
https://github.com/sparks-baird/self-driving-lab-demo/discussions/127#discussioncomment-4199099: