3ncr (Python)
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.
Release files for 3ncr 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| 3ncr-1.0.0.tar.gz | 7.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 3ncr-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 14.5 kB
Release files / 3ncr-1.0.0.tar.gz
| Download URL | 3ncr-1.0.0.tar.gz |
|---|---|
| Size | 7.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ac859c388378b56172d77ae00790a8dab8fcb61ef35d2cb5c0fb2572a83cefe7
|
|
BLAKE2b-256 checksum How to use checksums |
fed78548b2680e75be2e62bb63d8a0b6a6bb6dc5a240fe70e59f3e81db9e70ff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / 3ncr-1.0.0-py3-none-any.whl
| Download URL | 3ncr-1.0.0-py3-none-any.whl |
|---|---|
| Size | 6.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
aa197115fa43442e273be39b58fd1c15fd9936fbf14b447ce1db067cfb9e1858
|
|
BLAKE2b-256 checksum How to use checksums |
7cf1886e40f1e03603a46448133f52cfd36b1657343eedbee3306f78e8fbeb8f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|