Password management with python: keyring

https://bitbucket.org/kang/python-keyring-lib/

Mac #

Installation:

$ pip install keyring

Downloading/unpacking keyring
  Downloading keyring-3.5.zip (88Kb): 88Kb downloaded
  Running setup.py egg_info for package keyring
    
    warning: no previously-included files found matching '.hg/last-message.txt'
Installing collected packages: keyring
  Running setup.py install for keyring
    
    warning: no previously-included files found matching '.hg/last-message.txt'
    Installing keyring script to /Users/hide/ve/tact/bin
Successfully installed keyring
Cleaning up...

Try it out:

    >>> import keyring
    >>> dir(keyring)
    ['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 
     'absolute_import', 'backend', 'backends', 'core', 'credentials', 'delete_password', 
     'errors', 'get_keyring', 'get_pass_get_password', 'get_password', 'getpassbackend', 
     'logger', 'logging', 'py27compat', 'set_keyring', 'set_password', 'util']

Backend for Mac:

    >>> keyring.backend.get_all_keyring()
    [<keyring.backends.OS_X.Keyring object at 0x10b1a9150>, 
     <keyring.backends.file.EncryptedKeyring object at 0x10b1a47d0>, 
     <keyring.backends.file.PlaintextKeyring object at 0x10b1a9590>]

OS X Keychain by default:

    >>> keyring.get_keyring()
    <keyring.backends.OS_X.Keyring object at 0x10b1a9150>
    
    >>> keyring.set_password('service','user','password')
    >>> keyring.get_password('service','user')
    u'password'

Keychain access

You can open Application-> Utilities-> Keychain Access and see "service" as the login item.

security command

The OSX backend is a wrapper for security commands.

$ which security
/usr/bin/security

$ security find-generic-password -a user -s service -g
keychain: "/Users/hide/Library/Keychains/login.keychain"
class: "genp"
attributes:
    0x00000007 <blob>="service"
    0x00000008 <blob>=<NULL>
    "acct"<blob>="user"
    "cdat"<timedate>=0x32303134303330333138303733385A00  "20140303180738Z\000"
    "crtr"<uint32>=<NULL>
    "cusi"<sint32>=<NULL>
    "desc"<blob>=<NULL>
    "gena"<blob>=<NULL>
    "icmt"<blob>=<NULL>
    "invi"<sint32>=<NULL>
    "mdat"<timedate>=0x32303134303330333138303733385A00  "20140303180738Z\000"
    "nega"<sint32>=<NULL>
    "prot"<blob>=<NULL>
    "scrp"<sint32>=<NULL>
    "svce"<blob>="service"
    "type"<uint32>=<NULL>
password: "password"

Debian #

Also installed with pip. File-based: because it's a window system or a non-running server

    >>> keyring.backend.get_all_keyring()
    [<keyring.backends.file.EncryptedKeyring object at 0x28f4a50>, 
     <keyring.backends.file.PlaintextKeyring object at 0x28ebc50>]

    
    >>> current = _
    >>> dir(current[0])
    ['__abstractmethods__', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_abc_cache', '_abc_negative_cache', '_abc_negative_cache_version', '_abc_registry', '_check_file', '_classes', '_create_cipher', '_ensure_file_path', '_get_new_password', '_init_file', '_lock', '_migrate', '_unlock', 'block_size', 'decrypt', 'delete_password', 'encrypt', 'file_path', 'filename', 'get_password', 'keyring_key', 'priority', 'pw_prefix', 'set_password', 'viable']
        
    >>> current[0].filename
    'crypted_pass.cfg'
    >>> current[0].file_path
    '/home/hdknr/.local/share/python_keyring/crypted_pass.cfg'
    
    >>> current[1].filename
    'keyring_pass.cfg'
    >>> current[1].file_path
    '/home/hdknr/.local/share/python_keyring/keyring_pass.cfg'

I will try to make it. Keystore password as root:

    >>> keyring.set_password('ubuntu','user','password')
    Please enter password for encrypted keyring: root
    >>> keyring.get_password('ubuntu','user')
    u'password'
    
    >>> keyring.set_password('ubuntu','user1','password1')

ini file format store

Below home:

$ more /home/hdknr/.local/share/python_keyring/crypted_pass.cfg 
[keyring_2Dsetting]
password_20reference = eyJwYXNzd29yZF9lbmNyeXB0ZWQiOiAiUVpqd2I1a2tKem5oMU1tdVpNL3VFTjE3QURFVU9mazg3
	Zm9vXG4iLCAic2FsdCI6ICJ5cTFES3BkeTl1QWtZN1VWSVhkR0JkczR6RUpzQ0UraFFHMjVWa1hL
	MWZFPVxuIiwgIklWIjogIm5uWGFlK0t3L0ErQUg1T2I2eGJiWFE9PVxuIn0=

[ubuntu]
user = eyJwYXNzd29yZF9lbmNyeXB0ZWQiOiAiK3ViUmdaRVYrRURVYTdVPVxuIiwgInNhbHQiOiAidEJt
	OGpaUzhkTnFIYkIzZHlrOU5TZGwvTnFFOGZ6TkttWEZsZVhwYkRkRT1cbiIsICJJViI6ICJxWXFQ
	YkY2TmV5YytFZmtZOVV0b0RRPT1cbiJ9
user1 = eyJwYXNzd29yZF9lbmNyeXB0ZWQiOiAiL2E1Qzl2RlFQR3Y1YU5GSVxuIiwgInNhbHQiOiAidjZV
	a3BIeHR3OGU3RnM5NDRoTTQwc1llL0hjdisrb3F0dktRSHdIeGw0az1cbiIsICJJViI6ICI0aENO
	QWZsTDdUeVBxVW1PSlBIU3FnPT1cbiJ9	

Delete user1

$ vi /home/hdknr/.local/share/python_keyring/crypted_pass.cfg
    >>> import keyring
    >>> keyring.get_password('ubuntu','user')
    Please enter password for encrypted keyring: 
    u'password'
    >>> keyring.get_password('ubuntu','user1')
    >>> 

The password "root" is bad, so delete it after evaluation.

Json Base64 version

[keyring_2Dsetting] section

    >>> key_data = '''eyJwYXNzd29yZF9lbmNyeXB0ZWQiOiAiazloc1R1bmt3UERnRGo0TFY3UWljcVQybGxoSTRJS3Ns
    ...     Z1BVXG4iLCAic2FsdCI6ICJrcUZYUWhTMkR1ZEZGMjFkK3BpRmVJbll5dVkzY3V4MWlyam5OT3Zt
    ...     azBFPVxuIiwgIklWIjogIkQ0YUhEQ1VJbVhTUnFLZmN4MXRicmc9PVxuIn0='''.replace(' ','').replace('\n','')
    
    >>> import base64
    >>> import json
    >>> key_param = json.loads(base64.decodestring(key_data))
    >>> key_param
    {u'salt': u'kqFXQhS2DudFF21d+piFeInYyuY3cux1irjnNOvmk0E=\n', 
     u'password_encrypted': u'k9hsTunkwPDgDj4LV7QicqT2llhI4IKslgPU\n', 
     u'IV': u'D4aHDCUImXSRqKfcx1tbrg==\n'}
    
    >>> lambda d: dict([ (base64.decodestring(k.encode()), base64.decodestring(v.encode())) for k,v in d.items()])
    <function <lambda> at 0x7f4aba18dd70>
    >>> cv = _
    >>> key_param = cv(key_param)
    >>> key_param
    {'password_encrypted': '\x93\xd8lN\xe9\xe4\xc0\xf0\xe0\x0e>\x0bW\xb4"r\xa4\xf6\x96XH\xe0\x82\xac\x96\x03\xd4', 
     'salt': '\x92\xa1WB\x14\xb6\x0e\xe7E\x17m]\xfa\x98\x85x\x89\xd8\xca\xe67r\xecu\x8a\xb8\xe74\xeb\xe6\x93A', 
      'IV': '\x0f\x86\x87\x0c%\x08\x99t\x91\xa8\xa7\xdc\xc7[[\xae'}

pycrypto & AES CBF ##

If you have pycrypto, use it. [CFB block cipher] with block size 32 (https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation). Use salt to derive the key (https://www.dlitz.net/software/pycrypto/api/2.6/Crypto.Protocol.KDF-module.html)


    >>> from Crypto.Protocol.KDF import PBKDF2
    >>> from Crypto.Cipher import AES
    >>> pw_key = PBKDF2('root', key_param['salt'], 32)
    >>> cipher_key = AES.new(pw_key[:32], AES.MODE_CFB, key_param['IV'])
    >>> keyring_password = cipher_key.decrypt(key_param['password_encrypted']).decode('utf8')
    >>> keyring_password
    u'pw:password reference value'
    
Excluding prefix
    >>> p = keyring_password[3:]
    >>> p
    u'password reference value'

Similarly user data

    >>> user_data ='''eyJwYXNzd29yZF9lbmNyeXB0ZWQiOiAiY1VNVERaT1F4YWh4SElvPVxuIiwgInNhbHQiOiAicTg3
    ...     L0hDcmVOYTk1blBydFlvZVl4czB6aEVlSzVxMWdFTnUvdGtKRUhtYz1cbiIsICJJViI6ICI1TU5G
    ...     RjBZbnZzdyt2elFabWNTNmF3PT1cbiJ9'''.replace(' ','').replace('\n','')
    
    >>> user_param = cv( json.loads( base64.decodestring(user_data) ) )
    >>> user_param
    {'password_encrypted': 'qC\x13\r\x93\x90\xc5\xa8q\x1c\x8a', 'salt': '\xab\xce\xff\x1c*\xde5\xafy\x9c\xfa\xedb\x87\x98\xc6\xcd3\x84G\x8a\xe6\xad`\x10\xdb\xbf\xb6BD\x1eg', 'IV': "\xe4\xc3E\x17F'\xbe\xcc>\xbf4\x19\x99\xc4\xbak"}
    
    
    >>> pw_user = PBKDF2('root', user_param['salt'], 32)
    >>> cipher_user = AES.new(pw_user[:32], AES.MODE_CFB, user_param['IV'])
    >>> cipher_user.decrypt(user_param['password_encrypted']).decode('utf8')[3:]
    u'password'

Recommended Posts

Password management with python: keyring
YouTube video management with Python 3
[GUI with Python] PyQt5-Layout management-
[Python] Generate a password with Slackbot
Password generation in texto with python
FizzBuzz with Python3
Scraping with Python
Statistics with python
Scraping with Python
Python installation and package management with pip
Twilio with Python
Integrate with Python
Play with 2016-Python
AES256 with python
Simplify PDF password unlock with python + bat
python starts with ()
Bingo with python
Zundokokiyoshi with python
Excel table creation with Python [Progress management table]
Excel with Python
Microcomputer with Python
Cast with python
Experiment with NIST 800-63B password rules in Python
Serial communication with Python
Django 1.11 started with Python3.6
Primality test with Python
Python with eclipse + PyDev.
Socket communication with Python
Data analysis with python 2
Scraping with Python (preparation)
Try scraping with Python.
Learning Python with ChemTHEATER 03
"Object-oriented" learning with python
Run Python with VBA
Handling yaml with python
Solve AtCoder 167 with python
Serial communication with python
[Python] Use JSON with Python
Learning Python with ChemTHEATER 05-1
Learn Python with ChemTHEATER
Run prepDE.py with python3
1.1 Getting Started with Python
Collecting tweets with Python
Binarization with OpenCV / Python
3. 3. AI programming with Python
Kernel Method with Python
Non-blocking with Python + uWSGI
Scraping with Python + PhantomJS
Posting tweets with python
Drive WebDriver with python
Use mecab with Python3
[Python] Redirect with CGIHTTPServer
Voice analysis with python
Think yaml with python
Getting Started with Python
Use DynamoDB with Python
Zundko getter with python
Handle Excel with python
Ohm's Law with Python
Primality test with python
Solve Sudoku with Python