keyrings.cryptfile released on github

Hans-Peter Jansen hpj at urpla.net
Thu Mar 9 16:03:29 EST 2017


Hi,

since the PyCrypto ML is dead, I'm looking for advise/feedback from some
cryptography aware people.

I've released a keyring companion package today:

	https://github.com/frispete/keyrings.cryptfile

Its primary purpose is a decent encrypted file backend for python keyrings.
As such, it uses manually parameterized argon2 hashes as KDF, and AES in OCB 
mode as stream cipher (well, it just encrypts the password for a given 
service/user name). Granted, the advantages of OCB are not /that/ crucial 
here :wink:, but apart from technical factors, the exclusion of military uses 
by its license is rather *attractive* from my POV(!). But I'm open for 
discussions of course.

Still interested? Here we go:

To get you started, I expect you to have a python3 environment and git 
available. You might want to provide the packages argon2-cffi, keyring, 
pycryptodome and their dependencies (most notably SecretStorage and 
cryptography, or use a local venv, but that will depend on a compiler and some
development packages.

Example session, create an encrypted keyring:

$ git clone https://github.com/frispete/keyrings.cryptfile
$ cd keyrings.cryptfile
$ pyvenv env
$ . env/bin/activate
(env) $ pip install -e .
[...] # should succeed, some development packages might be missing otherwise
(env) $ python3
Python 3.4.5 (default, Jul 03 2016, 12:57:15) [GCC] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from keyrings.cryptfile.cryptfile import CryptFileKeyring
>>> kr = CryptFileKeyring()
>>> kr.set_password("service", "user", "secret")
Please set a password for your new keyring: 
Please confirm the password: 
>>> ^d

Second session, retrieve the stored secret from the keyring:

(env) $ python3
Python 3.4.5 (default, Jul 03 2016, 12:57:15) [GCC] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from keyrings.cryptfile.cryptfile import CryptFileKeyring
>>> kr = CryptFileKeyring()
>>> kr.get_password("service", "user")
Please enter password for encrypted keyring: 
'secret'
>>> ^d

Note, that the KDF might delay the {set,get}_password() operations for a 
few seconds (~1 sec. on a capable system).

The resulting file is located here (by default) and might look similar to:
(env) $ cat ~/.local/share/python_keyring/cryptfile_pass.cfg
[keyring_2Dsetting]
password_20reference = eyJub25jZSI6ICJQdVdWVUIwUHNYbEFqYUUxZ2l2RlxuIiwgIm1hYyI6ICIvVTFIVDBWTnRheTFl
        TjA5TVlHb0dRPT1cbiIsICJzYWx0IjogIklMdDNBU1hMUENrbWZ2NzFudmtBSUE9PVxuIiwgImRh
        dGEiOiAidW1EQkNvQ2dRUTk5WEVaNkZ4NWt3NXRkSUZDOHFIUE5ZOHhWXG4ifQ==
scheme = PyCryptodome [Argon2] AES OCB
version = 1.0

[service]
user = eyJub25jZSI6ICI5SUU3UGp2eDU2SXNQdHlLUGRtaFxuIiwgIm1hYyI6ICJKcFR1NXMxaDd0UGlW
        OW9XL3d5cFdBPT1cbiIsICJzYWx0IjogIlpBeEhJdXlqYnRuTkgzb3BMNTFvdkE9PVxuIiwgImRh
        dGEiOiAiT2I3Z1JJbXR5aVJLXG4ifQ==


The values can be decoded like this:

(env) $ python3
>>> import base64
>>> base64.decodebytes(b"""
... eyJub25jZSI6ICI5SUU3UGp2eDU2SXNQdHlLUGRtaFxuIiwgIm1hYyI6ICJKcFR1NXMxaDd0UGlW
... OW9XL3d5cFdBPT1cbiIsICJzYWx0IjogIlpBeEhJdXlqYnRuTkgzb3BMNTFvdkE9PVxuIiwgImRh
... dGEiOiAiT2I3Z1JJbXR5aVJLXG4ifQ==""")
b'{"nonce": "9IE7Pjvx56IsPtyKPdmh\\n", "mac": "JpTu5s1h7tPiV9oW/wypWA==\\n", 
   "salt": "ZAxHIuyjbtnNH3opL51ovA==\\n", "data": "Ob7gRImtyiRK\\n"}'

The items should be self explanatory. In theory, it should be considerable 
hard to get back to the plain values of data without knowing the password.

Any cryptography experts attending?

What do you think? The class hierarchy is inherited from keyrings.alt, and 
not exactly easy to follow, but the interesting parts are all in cryptfile,
which is quite brief.

I would be glad to hear something from you about my handling of cryptography. 
Is it ready for the public in that form or should I better locked away? :wink:

TIA,
Pete



More information about the Python-list mailing list