feat: add worker AES-256-GCM crypto matching the web envelope
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import base64
|
||||
import json
|
||||
import os
|
||||
|
||||
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
||||
|
||||
|
||||
def _key() -> bytes:
|
||||
b64 = os.environ.get("LYRA_SECRET_KEY")
|
||||
if not b64:
|
||||
raise RuntimeError("LYRA_SECRET_KEY is not set")
|
||||
k = base64.b64decode(b64)
|
||||
if len(k) != 32:
|
||||
raise RuntimeError("LYRA_SECRET_KEY must decode to 32 bytes")
|
||||
return k
|
||||
|
||||
|
||||
def encrypt_secret(plaintext: str) -> str:
|
||||
iv = os.urandom(12)
|
||||
full = AESGCM(_key()).encrypt(iv, plaintext.encode("utf-8"), None) # ct || tag(16)
|
||||
ct, tag = full[:-16], full[-16:]
|
||||
return json.dumps(
|
||||
{
|
||||
"iv": base64.b64encode(iv).decode(),
|
||||
"ct": base64.b64encode(ct).decode(),
|
||||
"tag": base64.b64encode(tag).decode(),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def decrypt_secret(envelope: str) -> str:
|
||||
e = json.loads(envelope)
|
||||
iv = base64.b64decode(e["iv"])
|
||||
ct = base64.b64decode(e["ct"])
|
||||
tag = base64.b64decode(e["tag"])
|
||||
pt = AESGCM(_key()).decrypt(iv, ct + tag, None) # AESGCM expects ct || tag
|
||||
return pt.decode("utf-8")
|
||||
Reference in New Issue
Block a user