"""Public demonstration key only. Never use this key to protect real data. Requires Python 3.10+ and cryptography. No network operations. """ import base64 import json import os import sys from cryptography.hazmat.primitives.ciphers.aead import AESGCM PUBLIC_TEST_KEY_HEX = '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f' KEY = bytes.fromhex(PUBLIC_TEST_KEY_HEX) DEMO_MESSAGE = 'Hello from Node.js — Hola, niño 🔐' def encrypt(message=DEMO_MESSAGE): iv, aad = os.urandom(12), b'hashytools:raw-demo' combined = AESGCM(KEY).encrypt(iv, message.encode('utf-8'), aad) return dict(algorithm='AES-256-GCM', encoding='hex', iv=iv.hex(), ciphertext=combined[:-16].hex(), tag=combined[-16:].hex(), aad=aad.hex()) def decode(value, encoding): if not isinstance(value, str): raise ValueError('Expected an encoded string') if encoding == 'hex': result = bytes.fromhex(value) if result.hex() != value.lower(): raise ValueError('Invalid hex') return result if encoding not in ('base64', 'base64url'): raise ValueError('Invalid encoding') bare = value.rstrip('=') padded = bare + '=' * (-len(bare) % 4) if '=' in value and padded != value: raise ValueError('Invalid padding') result = base64.b64decode(padded, altchars=b'-_' if encoding == 'base64url' else None, validate=True) canonical = (base64.urlsafe_b64encode(result) if encoding == 'base64url' else base64.b64encode(result)).decode().rstrip('=') if canonical != bare: raise ValueError('Invalid encoding') return result def decrypt(payload): if payload['algorithm'] != 'AES-256-GCM': raise ValueError('Expected AES-256-GCM') def field(name): return decode(payload.get(name, ''), payload['encoding']) iv, ciphertext, aad = field('iv'), field('ciphertext'), field('aad') if payload.get('tagLayout') == 'appended': ciphertext, tag = ciphertext[:-16], ciphertext[-16:] else: tag = field('tag') if len(iv) != 12 or len(tag) != 16: raise ValueError('Expected 12-byte IV and 16-byte tag') return AESGCM(KEY).decrypt(iv, ciphertext + tag, aad) if __name__ == '__main__': if len(sys.argv) != 3 or sys.argv[1] not in ('encrypt', 'decrypt'): raise SystemExit('Usage: python raw-python.py encrypt|decrypt parameters.json') if sys.argv[1] == 'encrypt': with open(sys.argv[2], 'w', encoding='utf-8') as output: json.dump(encrypt(), output, indent=2) else: with open(sys.argv[2], encoding='utf-8') as source: plaintext = decrypt(json.load(source)) sys.stdout.buffer.write(plaintext)