feat: identity-micropython v0.1.0 — Pico W Ed25519 PoC
This commit is contained in:
64
identity_iot_aes.py
Normal file
64
identity_iot_aes.py
Normal file
@@ -0,0 +1,64 @@
|
||||
# ============================================================+
|
||||
# Identity IoT — AES-CBC ITEMS Envelope
|
||||
# (c) Copyright : ae Aeonian Engineering Limited - Hong Kong
|
||||
# (c) Copyright : WIDE di D. Papa - Naples - Italy
|
||||
# ============================================================+
|
||||
# AES-CBC encryption/decryption compatible with PHP ITEMSEncrypter.
|
||||
# Uses ucryptolib (built-in on Pico W / ESP32).
|
||||
# ============================================================+
|
||||
|
||||
import ucryptolib
|
||||
import ubinascii
|
||||
|
||||
|
||||
def _pkcs7_pad(data: bytes, block_size: int = 16) -> bytes:
|
||||
pad_len = block_size - (len(data) % block_size)
|
||||
return data + bytes([pad_len] * pad_len)
|
||||
|
||||
|
||||
def _pkcs7_unpad(data: bytes) -> bytes:
|
||||
pad_len = data[-1]
|
||||
return data[:-pad_len]
|
||||
|
||||
|
||||
def aes_cbc_encrypt(plaintext: str, key: bytes, iv: bytes) -> str:
|
||||
"""
|
||||
Encrypt plaintext string with AES-CBC.
|
||||
Returns base64-encoded ciphertext.
|
||||
Compatible with PHP ITEMSEncrypter::encryptAES().
|
||||
"""
|
||||
if isinstance(key, str):
|
||||
key = key.encode()
|
||||
if isinstance(iv, str):
|
||||
iv = iv.encode()
|
||||
if isinstance(plaintext, str):
|
||||
plaintext = plaintext.encode('utf-8')
|
||||
|
||||
padded = _pkcs7_pad(plaintext)
|
||||
cipher = ucryptolib.aes(key, 2, iv) # mode 2 = CBC
|
||||
encrypted = cipher.encrypt(padded)
|
||||
return ubinascii.b2a_base64(encrypted).decode().strip()
|
||||
|
||||
|
||||
def aes_cbc_decrypt(ciphertext_b64: str, key: bytes, iv: bytes) -> str:
|
||||
"""
|
||||
Decrypt base64-encoded AES-CBC ciphertext.
|
||||
Returns plaintext string.
|
||||
Compatible with PHP ITEMSEncrypter::decryptAES().
|
||||
"""
|
||||
if isinstance(key, str):
|
||||
key = key.encode()
|
||||
if isinstance(iv, str):
|
||||
iv = iv.encode()
|
||||
|
||||
# Normalize base64
|
||||
s = ciphertext_b64.strip().replace('\n', '').replace('\r', '')
|
||||
s = s.replace('-', '+').replace('_', '/')
|
||||
pad = len(s) % 4
|
||||
if pad:
|
||||
s += '=' * (4 - pad)
|
||||
|
||||
encrypted = ubinascii.a2b_base64(s)
|
||||
cipher = ucryptolib.aes(key, 2, iv) # mode 2 = CBC
|
||||
decrypted = cipher.decrypt(encrypted)
|
||||
return _pkcs7_unpad(decrypted).decode('utf-8')
|
||||
Reference in New Issue
Block a user