Skip to main content

Python implementation of the 3ncr.org v1 string encryption standard (AES-256-GCM).

Project description

3ncr (Python)

Test PyPI version OpenSSF Scorecard License: MIT

3ncr.org is a standard for string encryption / decryption (algorithms + storage format), originally intended for encrypting tokens in configuration files but usable for any UTF-8 string. v1 uses AES-256-GCM for authenticated encryption with a 12-byte random IV:

3ncr.org/1#<base64(iv[12] || ciphertext || tag[16])>

Encrypted values look like 3ncr.org/1#pHRufQld0SajqjHx+FmLMcORfNQi1d674ziOPpG52hqW5+0zfJD91hjXsBsvULVtB017mEghGy3Ohj+GgQY5MQ.

This is the official Python implementation. See github.com/3ncr for implementations in other languages (Go, Node.js, PHP, Rust, Java, C#, Ruby).

Install

pip install 3ncr

Requires Python 3.9+.

Usage

Pick a constructor based on the entropy of your secret — see the 3ncr.org v1 KDF guidance for the canonical recommendation.

Recommended: raw 32-byte key (high-entropy secrets)

If you already have a 32-byte AES-256 key, skip the KDF and pass it directly.

import os
from threencr import TokenCrypt

key = os.urandom(32)  # or load from an env variable / secret store
tc = TokenCrypt.from_raw_key(key)

For a high-entropy secret that is not already 32 bytes (e.g. a random API token), hash it through SHA3-256:

tc = TokenCrypt.from_sha3("some-high-entropy-api-token")

Recommended: Argon2id (passwords / low-entropy secrets)

For passwords or passphrases, use TokenCrypt.from_argon2id. It uses the parameters recommended by the 3ncr.org v1 spec (m=19456 KiB, t=2, p=1). The salt must be at least 16 bytes.

from threencr import TokenCrypt

tc = TokenCrypt.from_argon2id("correct horse battery staple", b"0123456789abcdef")

Legacy: PBKDF2-SHA3 (existing data only)

This library does not implement the legacy PBKDF2-SHA3 KDF that earlier 3ncr.org libraries (Go, Node.js, PHP, Java) shipped for backward compatibility. If you need to decrypt data produced by that KDF, derive the 32-byte key with hashlib.pbkdf2_hmac("sha3_256", ...) yourself and pass it to from_raw_key.

Encrypt / decrypt

plaintext = "08019215-B205-4416-B2FB-132962F9952F"
encrypted = tc.encrypt_3ncr(plaintext)
# e.g. "3ncr.org/1#pHRu..."

tc.decrypt_if_3ncr(encrypted)  # -> plaintext

decrypt_if_3ncr returns the input unchanged when it does not start with the 3ncr.org/1# header. This makes it safe to route every configuration value through it regardless of whether it was encrypted.

Decryption failures (bad tag, truncated input, malformed base64) raise threencr.TokenCryptError.

Cross-implementation interop

This implementation decrypts the canonical v1 envelope test vectors shared with the Go, Node.js, and PHP reference libraries. The 32-byte AES key behind those vectors was originally derived via PBKDF2-SHA3-256 with secret = "a", salt = "b", iterations = 1000; the tests hardcode the resulting key and verify the AES-256-GCM envelope round-trips exactly. See tests/test_threencr.py.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

3ncr-1.0.0.tar.gz (7.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

3ncr-1.0.0-py3-none-any.whl (6.7 kB view details)

Uploaded Python 3

File details

Details for the file 3ncr-1.0.0.tar.gz.

File metadata

  • Download URL: 3ncr-1.0.0.tar.gz
  • Upload date:
  • Size: 7.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for 3ncr-1.0.0.tar.gz
Algorithm Hash digest
SHA256 ac859c388378b56172d77ae00790a8dab8fcb61ef35d2cb5c0fb2572a83cefe7
MD5 492fdc7b99bf2efacefbe2117efa7743
BLAKE2b-256 fed78548b2680e75be2e62bb63d8a0b6a6bb6dc5a240fe70e59f3e81db9e70ff

See more details on using hashes here.

File details

Details for the file 3ncr-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: 3ncr-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 6.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for 3ncr-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 aa197115fa43442e273be39b58fd1c15fd9936fbf14b447ce1db067cfb9e1858
MD5 cc22ab02ad2d30272b68e022f5ad5a67
BLAKE2b-256 7cf1886e40f1e03603a46448133f52cfd36b1657343eedbee3306f78e8fbeb8f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page