xi-keyring

simple and extensible alternative for gnome-keyring
git clone https://git.ce9e.org/xi-keyring.git

commit
f3718283f287391ed6f7370ee0105db67eb7ef95
parent
45f757d0a1fcd7ec699942bee88fd55c26c92df4
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2024-08-04 07:31
use argon2 for encryption

Diffstat

M PKGBUILD 1 +
M xikeyring/keyring.py 28 +++++++++++++++++++++++++---

2 files changed, 26 insertions, 3 deletions


diff --git a/PKGBUILD b/PKGBUILD

@@ -6,6 +6,7 @@ url='https://github.com/xi/xi-keyring'
    6     6 license='MIT'
    7     7 depends=(
    8     8 	pinentry
   -1     9 	python3-argon2
    9    10 	python3-cryptography
   10    11 	python3-gi
   11    12 )

diff --git a/xikeyring/keyring.py b/xikeyring/keyring.py

@@ -3,6 +3,7 @@ import json
    3     3 import os
    4     4 from dataclasses import dataclass
    5     5 
   -1     6 import argon2
    6     7 from cryptography.fernet import Fernet
    7     8 from cryptography.fernet import InvalidToken
    8     9 from cryptography.hazmat.primitives import hashes
@@ -47,14 +48,33 @@ class Crypt:
   47    48         key = kdf.derive(self.password.value)
   48    49         return base64.urlsafe_b64encode(key)
   49    50 
   -1    51     def get_argon2(
   -1    52             self,
   -1    53             salt: bytes,
   -1    54             time_cost: int,
   -1    55             memory_cost: int,
   -1    56             parallelism: int,
   -1    57         ) -> bytes:
   -1    58         # https://www.rfc-editor.org/rfc/rfc9106.html#name-parameter-choice
   -1    59         key = argon2.low_level.hash_secret_raw(
   -1    60             secret=self.password.value,
   -1    61             salt=salt,
   -1    62             time_cost=time_cost,
   -1    63             memory_cost=memory_cost,
   -1    64             parallelism=parallelism,
   -1    65             hash_len=32,
   -1    66             type=argon2.low_level.Type.ID,
   -1    67         )
   -1    68         return base64.urlsafe_b64encode(key)
   -1    69 
   50    70     def encrypt(self, data: bytes) -> bytes:
   51    71         salt = os.urandom(16)
   52    -1         params = [100_000]
   53    -1         key = self.get_pkbf2(salt, *params)
   -1    72         params = [3, 1 << 16, 4]
   -1    73         key = self.get_argon2(salt, *params)
   54    74         content = Fernet(key).encrypt(data)
   55    75         return b'$'.join(
   56    76             [
   57    -1                 b'fernet',
   -1    77                 b'fernet-argon2',
   58    78                 base64.urlsafe_b64encode(salt),
   59    79                 *[str(p).encode() for p in params],
   60    80                 content,
@@ -67,6 +87,8 @@ class Crypt:
   67    87         params = [int(p, 10) for p in params]
   68    88         if algo == b'fernet' and len(params) == 1:
   69    89             key = self.get_pkbf2(salt, *params)
   -1    90         elif algo == b'fernet-argon2' and len(params) == 3:
   -1    91             key = self.get_argon2(salt, *params)
   70    92         else:
   71    93             raise TypeError('Unknown encryption algorithm')
   72    94         return Fernet(key).decrypt(content)