amora-py


Nameamora-py JSON
Version 0.2.1 PyPI version JSON
download
home_pageNone
SummaryAmora is a secure token inspired by JWT and Branca, but enhanced a bit in some areas.
upload_time2024-03-08 18:03:12
maintainerNone
docs_urlNone
authorGrzegorz Blach
requires_python>=3.8
licenseMPL-2.0
keywords token jwt branca authentication authorization
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Amora

Amora is a secure token inspired by [JWT](https://jwt.io) and [Branca](https://branca.io/),
but enhanced a bit in some areas.

Key features:
- Can contain any type of payload: JSON, msgpack, cbor and so on...
- Always encrypted and authenticated using XChaCha20-Poly1305 algorithm.
- There are two versions of Amora:
	- **Amora zero**: encrypted with a 32-byte symmetric key.
	- **Amora one**: encrypted with a 32-byte asymmetric key.
- Encoded using url-safe base64.
- Always contain token generation time and TTL.

## Amora structure

- header (4 bytes for Amora zero; 36 bytes for Amora one):
	- version marker: 0xa0 or 0xa1 (1 byte)
	- TTL (3 bytes; little-endian)
	- randomly generated public key (32 bytes; Amora one only)
- nonce (24 bytes)
	- token generation time (first 4 bytes; little-endian)
	- randomly generated 20 bytes
- payload (any length)
- message authentication code (4 bytes)

## Token generation time (TGT) + TTL

TGT is an unsigned 32-bit int. It's a number of seconds starting from the Unix epoch
on January 1, 1970 UTC. This means that Amora tokens will work correctly until the year 2106.

TTL is an unsigned 24-bits int. It means that each token can be valid for a maximum of 194 days.

## Asymmetric encryption

The shared key is computed using the X25519 function. It requires two pairs of priv/pub keys.
The first pair must be known. The second pair is randomly generated for each token.

## Code examples

### Symmetric key from bytes

```python
key = bytes([
	0x4f, 0x99, 0x70, 0x66, 0x2f, 0xac, 0xd3, 0x7d,
	0xc3, 0x6c, 0x0f, 0xd1, 0xda, 0xd0, 0x7e, 0xaa,
	0x04, 0x7c, 0x28, 0x54, 0x58, 0x3c, 0x92, 0x0f,
	0x52, 0x4b, 0x2b, 0x01, 0xd8, 0x40, 0x83, 0x1a,
])
amora = amora_py.Amora.amora_zero(key)
payload = "sample_payload_just_for_testing"
token = amora.encode(payload.encode(), 1)
decoded = amora.decode(token, True)
decoded = bytes(decoded).decode()
```

### Symmetric key from string

```python
key = "4f9970662facd37dc36c0fd1dad07eaa047c2854583c920f524b2b01d840831a"
amora = amora_py.Amora.amora_zero_from_str(key)
payload = "sample_payload_just_for_testing"
token = amora.encode(payload.encode(), 1)
decoded = amora.decode(token, True)
decoded = bytes(decoded).decode()
```

### Asymmetric key from bytes

```python
x25519 = X25519PrivateKey.generate()
secret_key = x25519.private_bytes_raw()
public_key = x25519.public_key().public_bytes_raw()
amora = amora_py.Amora.amora_one(secret_key, public_key)
payload = "sample_payload_just_for_testing"
token = amora.encode(payload.encode(), 1)
decoded = amora.decode(token, True)
decoded = bytes(decoded).decode()
```

### Asymmetric key from string

```python
secret_key = "778d0b92672b9a25ec4fbe65e3ad2212efa011e8f7035754c1342fe46191dbb3"
public_key = "5cdd89c1bb6859c927c50b6976712f256cdbf14d7273f723dc121c191f9d6d6d"
amora = amora_py.Amora.amora_one_from_str(secret_key, public_key)
payload = "sample_payload_just_for_testing"
token = amora.encode(payload.encode(), 1)
decoded = amora.decode(token, True)
decoded = bytes(decoded).decode()
```

### Fetch metadata from the token

```python
token = "oAEAAE_X6GVaC7xve5xaaAaLiW1YPqHX9I1BNGbKnC7ArMke4G" \
	"EU9MXCgU2U5jYAkJhDXQBqsO5tadCKyXZmI3mV-bpDFr1aQc1U";
meta = amora_py.Amora.meta(token)
print(meta)
```


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "amora-py",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "token,jwt,branca,authentication,authorization",
    "author": "Grzegorz Blach",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/b2/7c/32b8332c40b252ae93b7d0d9885fb83423c4f9a3400eba338b43876f93e1/amora_py-0.2.1.tar.gz",
    "platform": null,
    "description": "# Amora\n\nAmora is a secure token inspired by [JWT](https://jwt.io) and [Branca](https://branca.io/),\nbut enhanced a bit in some areas.\n\nKey features:\n- Can contain any type of payload: JSON, msgpack, cbor and so on...\n- Always encrypted and authenticated using XChaCha20-Poly1305 algorithm.\n- There are two versions of Amora:\n\t- **Amora zero**: encrypted with a 32-byte symmetric key.\n\t- **Amora one**: encrypted with a 32-byte asymmetric key.\n- Encoded using url-safe base64.\n- Always contain token generation time and TTL.\n\n## Amora structure\n\n- header (4 bytes for Amora zero; 36 bytes for Amora one):\n\t- version marker: 0xa0 or 0xa1 (1 byte)\n\t- TTL (3 bytes; little-endian)\n\t- randomly generated public key (32 bytes; Amora one only)\n- nonce (24 bytes)\n\t- token generation time (first 4 bytes; little-endian)\n\t- randomly generated 20 bytes\n- payload (any length)\n- message authentication code (4 bytes)\n\n## Token generation time (TGT) + TTL\n\nTGT is an unsigned 32-bit int. It's a number of seconds starting from the Unix epoch\non January 1, 1970 UTC. This means that Amora tokens will work correctly until the year 2106.\n\nTTL is an unsigned 24-bits int. It means that each token can be valid for a maximum of 194 days.\n\n## Asymmetric encryption\n\nThe shared key is computed using the X25519 function. It requires two pairs of priv/pub keys.\nThe first pair must be known. The second pair is randomly generated for each token.\n\n## Code examples\n\n### Symmetric key from bytes\n\n```python\nkey = bytes([\n\t0x4f, 0x99, 0x70, 0x66, 0x2f, 0xac, 0xd3, 0x7d,\n\t0xc3, 0x6c, 0x0f, 0xd1, 0xda, 0xd0, 0x7e, 0xaa,\n\t0x04, 0x7c, 0x28, 0x54, 0x58, 0x3c, 0x92, 0x0f,\n\t0x52, 0x4b, 0x2b, 0x01, 0xd8, 0x40, 0x83, 0x1a,\n])\namora = amora_py.Amora.amora_zero(key)\npayload = \"sample_payload_just_for_testing\"\ntoken = amora.encode(payload.encode(), 1)\ndecoded = amora.decode(token, True)\ndecoded = bytes(decoded).decode()\n```\n\n### Symmetric key from string\n\n```python\nkey = \"4f9970662facd37dc36c0fd1dad07eaa047c2854583c920f524b2b01d840831a\"\namora = amora_py.Amora.amora_zero_from_str(key)\npayload = \"sample_payload_just_for_testing\"\ntoken = amora.encode(payload.encode(), 1)\ndecoded = amora.decode(token, True)\ndecoded = bytes(decoded).decode()\n```\n\n### Asymmetric key from bytes\n\n```python\nx25519 = X25519PrivateKey.generate()\nsecret_key = x25519.private_bytes_raw()\npublic_key = x25519.public_key().public_bytes_raw()\namora = amora_py.Amora.amora_one(secret_key, public_key)\npayload = \"sample_payload_just_for_testing\"\ntoken = amora.encode(payload.encode(), 1)\ndecoded = amora.decode(token, True)\ndecoded = bytes(decoded).decode()\n```\n\n### Asymmetric key from string\n\n```python\nsecret_key = \"778d0b92672b9a25ec4fbe65e3ad2212efa011e8f7035754c1342fe46191dbb3\"\npublic_key = \"5cdd89c1bb6859c927c50b6976712f256cdbf14d7273f723dc121c191f9d6d6d\"\namora = amora_py.Amora.amora_one_from_str(secret_key, public_key)\npayload = \"sample_payload_just_for_testing\"\ntoken = amora.encode(payload.encode(), 1)\ndecoded = amora.decode(token, True)\ndecoded = bytes(decoded).decode()\n```\n\n### Fetch metadata from the token\n\n```python\ntoken = \"oAEAAE_X6GVaC7xve5xaaAaLiW1YPqHX9I1BNGbKnC7ArMke4G\" \\\n\t\"EU9MXCgU2U5jYAkJhDXQBqsO5tadCKyXZmI3mV-bpDFr1aQc1U\";\nmeta = amora_py.Amora.meta(token)\nprint(meta)\n```\n\n",
    "bugtrack_url": null,
    "license": "MPL-2.0",
    "summary": "Amora is a secure token inspired by JWT and Branca, but enhanced a bit in some areas.",
    "version": "0.2.1",
    "project_urls": {
        "Issues": "https://codeberg.org/gblach/amora-py/issues",
        "Repository": "https://codeberg.org/gblach/amora-py"
    },
    "split_keywords": [
        "token",
        "jwt",
        "branca",
        "authentication",
        "authorization"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "cd97927b3e246e56e40f831649f5178b74a9831229e31687257466035b9162e3",
                "md5": "c22028e8fdd7d09f0d85cad9cedd84f7",
                "sha256": "6e433123cf1bfcfe5c52f758302e2b29949e3331343f4f476fb4cae3e28d9b51"
            },
            "downloads": -1,
            "filename": "amora_py-0.2.1-cp310-cp310-manylinux_2_34_aarch64.whl",
            "has_sig": false,
            "md5_digest": "c22028e8fdd7d09f0d85cad9cedd84f7",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.8",
            "size": 277748,
            "upload_time": "2024-03-08T18:40:50",
            "upload_time_iso_8601": "2024-03-08T18:40:50.431672Z",
            "url": "https://files.pythonhosted.org/packages/cd/97/927b3e246e56e40f831649f5178b74a9831229e31687257466035b9162e3/amora_py-0.2.1-cp310-cp310-manylinux_2_34_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "2507fe497f29a6dd13ba7a838f7beff0df7ca672da8b2860b6acfe6cf34c2530",
                "md5": "a6cfc83aa5657e025419815e3fa9dd8e",
                "sha256": "6546feb2cf2daf48bf3a9435c106ec30bb3ff9750b316195ae36b4074b06a514"
            },
            "downloads": -1,
            "filename": "amora_py-0.2.1-cp310-cp310-manylinux_2_34_x86_64.whl",
            "has_sig": false,
            "md5_digest": "a6cfc83aa5657e025419815e3fa9dd8e",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.8",
            "size": 297422,
            "upload_time": "2024-03-08T18:04:16",
            "upload_time_iso_8601": "2024-03-08T18:04:16.689580Z",
            "url": "https://files.pythonhosted.org/packages/25/07/fe497f29a6dd13ba7a838f7beff0df7ca672da8b2860b6acfe6cf34c2530/amora_py-0.2.1-cp310-cp310-manylinux_2_34_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "3dea9e995f0dafe4d1347856d8096ca730e5de070c5c38658a2b184cdf5b4088",
                "md5": "a35b036dfc68ebf8a178a646fc7e1f7e",
                "sha256": "42b36d2dc995b7bf6ed7ae83bd54063b565fdbc1b44c5e07446e8871a5bb20c7"
            },
            "downloads": -1,
            "filename": "amora_py-0.2.1-cp311-cp311-manylinux_2_34_aarch64.whl",
            "has_sig": false,
            "md5_digest": "a35b036dfc68ebf8a178a646fc7e1f7e",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.8",
            "size": 277751,
            "upload_time": "2024-03-08T18:35:24",
            "upload_time_iso_8601": "2024-03-08T18:35:24.683719Z",
            "url": "https://files.pythonhosted.org/packages/3d/ea/9e995f0dafe4d1347856d8096ca730e5de070c5c38658a2b184cdf5b4088/amora_py-0.2.1-cp311-cp311-manylinux_2_34_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "17866dbf55a2d42c68977eca816b2ff5de5ec4b363ae24261a98d318628abf20",
                "md5": "328ce25a77dd6c69fe6cb9412d5e33fc",
                "sha256": "05d0bd6a6d40cb82c9a6b81c7f5b8ae6750d8cdf060717c81529923045312161"
            },
            "downloads": -1,
            "filename": "amora_py-0.2.1-cp311-cp311-manylinux_2_34_x86_64.whl",
            "has_sig": false,
            "md5_digest": "328ce25a77dd6c69fe6cb9412d5e33fc",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.8",
            "size": 297452,
            "upload_time": "2024-03-08T18:03:44",
            "upload_time_iso_8601": "2024-03-08T18:03:44.541346Z",
            "url": "https://files.pythonhosted.org/packages/17/86/6dbf55a2d42c68977eca816b2ff5de5ec4b363ae24261a98d318628abf20/amora_py-0.2.1-cp311-cp311-manylinux_2_34_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "758891c704c57c4ef6f76e673e9cbe1050133a8059ad23d998c7718ef945ec14",
                "md5": "52a528948a41897f7ee723d88eb08e8d",
                "sha256": "385ac2e86cdde08afa3dcece2355462f0ad20026021f81d0e34b8eab69aaca44"
            },
            "downloads": -1,
            "filename": "amora_py-0.2.1-cp312-cp312-manylinux_2_34_aarch64.whl",
            "has_sig": false,
            "md5_digest": "52a528948a41897f7ee723d88eb08e8d",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.8",
            "size": 278042,
            "upload_time": "2024-03-08T18:32:29",
            "upload_time_iso_8601": "2024-03-08T18:32:29.697656Z",
            "url": "https://files.pythonhosted.org/packages/75/88/91c704c57c4ef6f76e673e9cbe1050133a8059ad23d998c7718ef945ec14/amora_py-0.2.1-cp312-cp312-manylinux_2_34_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "64570eb996f4d54f0bdf1956bfb10deb1909ef2bd90773072f56c9a2c40f41a0",
                "md5": "d6eae89a113589ab9e8b69bf5031844b",
                "sha256": "af3097d6e450cb2fedb7a9e93d4dbe6cacaf5bfce1103a61a6190ba358dc4b0a"
            },
            "downloads": -1,
            "filename": "amora_py-0.2.1-cp312-cp312-manylinux_2_34_x86_64.whl",
            "has_sig": false,
            "md5_digest": "d6eae89a113589ab9e8b69bf5031844b",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.8",
            "size": 297662,
            "upload_time": "2024-03-08T18:03:10",
            "upload_time_iso_8601": "2024-03-08T18:03:10.076929Z",
            "url": "https://files.pythonhosted.org/packages/64/57/0eb996f4d54f0bdf1956bfb10deb1909ef2bd90773072f56c9a2c40f41a0/amora_py-0.2.1-cp312-cp312-manylinux_2_34_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b27c32b8332c40b252ae93b7d0d9885fb83423c4f9a3400eba338b43876f93e1",
                "md5": "f0e029666e994f21a1ab9cd7d29fb83f",
                "sha256": "c44689554efc9cf13b073543f5dc8cc143e0b34c15e4b9bf7c7f071bc468f950"
            },
            "downloads": -1,
            "filename": "amora_py-0.2.1.tar.gz",
            "has_sig": false,
            "md5_digest": "f0e029666e994f21a1ab9cd7d29fb83f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 15208,
            "upload_time": "2024-03-08T18:03:12",
            "upload_time_iso_8601": "2024-03-08T18:03:12.455498Z",
            "url": "https://files.pythonhosted.org/packages/b2/7c/32b8332c40b252ae93b7d0d9885fb83423c4f9a3400eba338b43876f93e1/amora_py-0.2.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-08 18:03:12",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": true,
    "codeberg_user": "gblach",
    "codeberg_project": "amora-py",
    "lcname": "amora-py"
}
        
Elapsed time: 0.23499s