Is there a way to access the keyring in Windows without giving a master password?
Asked Answered
M

1

6

I'm developing a script with a co-worker that involves connecting to a database. We want to keep the code independent of which one of us uses it, while keeping our passwords private and not having to authenticate over and over during the workday. After some searching (we are both novices in Python) it seems that we can use keyring for this purpose, so I installed it from pip (most likely version 1.2.2 of the library, based on my memory of the installation date).

The problem is that when I try to access my stored passwords, I am prompted to set a master password to access the keyring, as shown here (from IDLE):

>>> import keyring
>>> keyring.set_password('Service', 'MyUsername', 'MyPassword')

Warning (from warnings module):
  File "C:\Python27\lib\getpass.py", line 92
  return fallback_getpass(prompt, stream)
GetPassWarning: Can not control echo on the terminal.
Warning: Password input may be echoed.
Please enter password for encrypted keyring:

After setting the password, I can get and set passwords easily, until I restart the shell. Now I have to enter the master password again:

>>> ================================ RESTART ================================
>>> import keyring
>>> print keyring.get_password('Service', 'MyUsername')

Warning (from warnings module):
  File "C:\Python27\lib\getpass.py", line 92
    return fallback_getpass(prompt, stream)
GetPassWarning: Can not control echo on the terminal.
Warning: Password input may be echoed.
Please enter password for encrypted keyring:

After entering the master password, this authentication persists only during the current session/between restarts. When running scripts from the command line, it's even worse - I have to authenticate every time the script is run. At this point, keyring is not saving me any time or effort, and I doubt it's making my password any more secure vs. memorization and manual entry.

After searching for solutions, it looks like keyring will automatically authenticate on Unix if the master password is the same as the password for the user account, but this didn't work for me on Windows.

Am I trying to get keyring to do something it's not meant to do, or is there just an error in my implementation?

My experience seems to conflict with that reported by another user who claims (s)he is not prompted for a password when an application tries to access the keyring in the related question, How does python-keyring work on Windows?

Mebane answered 28/5, 2013 at 18:35 Comment(3)
I don't have an answer but I have been looking at a similar problem. From my reading of the documents I think you may need to implement a custom python-keyring backend (probably subclassed from on the keyring.backends.file.BaseKeyring) and override the encrypt/decrypt methods to a certificate based scheme and configure the backend to use a certificate that identifes the allowed userUncomfortable
Which keyring version are you using? I just downloaded the latest keyring from: bitbucket.org/kang/python-keyring-lib/downloads. Tried under Windows 7 with Python2.7 in IDLE. It didn't report warnings like you, neither asked for Please enter password for encrypted keyring:. It just works fine hereHyperbola
@Hyperbola I was probably using version 1.2.2 at the time this question was written, but soon gave up and haven't used it since. Looks like this issue is no longer present in the current version 3.8 available via pip. Thanks for the check - if you create an answer, I'll give credit for the bounty.Mebane
R
2

Which backend are you using? Check using:

>>> from keyring import get_keyring
>>> get_keyring()
[... what is output here?]

If it outputs this:

<keyring.backends.file.EncryptedKeyring object at 0x.....>

Then that's why it's requesting a password. The module failed to find any platform specific keyring to use, so it's instead just encrypting your passwords using a master password and placing them into an ordinary file.

Personally, it's more important to me that my scripts run unattended than that my passwords are secure, so I wrote this function:

def configureKeyring():
    """
    EncryptedKeyring requires a master password to unlock it, which is not ideal
    for our scripts since we want them to run unattended. So if we're using
    EncryptedKeyring, automatically swap to a PlaintextKeyring instead.

    If we're using something else, say WinVaultKeyring, then that's more secure
    than PlaintextKeyring without being any less convenient, so we'll use it.
    """
    from keyring               import get_keyring, set_keyring
    from keyring.backends.file import EncryptedKeyring, PlaintextKeyring

    if isinstance(get_keyring(), EncryptedKeyring):
        set_keyring(PlaintextKeyring())

Before you use keyring to set_password or get_password, run this function configureKeyring(), if you, like me, value not needing to insert a master password over keeping your passwords safe. Please understand the security implications that you are storing your passwords in plaintext before doing this.

A better long term solution is to probably investigate all the other available backends and install the proper pre-reqs so that a different one can be used, if one exists where you don't need to input a master password and simply being logged in is sufficient.

Note: from https://build.opensuse.org/package/view_file/openSUSE:Leap:42.2/python-keyring/python-keyring.changes?rev=a2e727a9e4a21a65c9496362d8cff27d

As these keyrings have moved, any keyrings indicated explicitly in configuration will need to be updated to replace "keyring.backends." with "keyrings.alt.". For example, "keyring.backends.file.PlaintextKeyring" becomes "keyrings.alt.file.PlaintextKeyring"

so depending on the version in the solution already provided, you might have to do

from keyrings.alt.file import EncryptedKeyring, PlaintextKeyring 
Refresh answered 28/9, 2015 at 15:34 Comment(2)
Odd, but there is no backends.file. There is backends.SecretService and others. But haven't figured out how to set them as default keyring. There is no PlaintextKeyring, although backend.get_all_keyring() provides me with [<PlaintextKeyring at /home/<user>/.local/share/python_keyring/keyring_pass.cfg>, <keyring.backends.fail.Keyring at 0x7ffa97af6490>, <EncryptedKeyring at /home/<user>/.local/share/python_keyring/crypted_pass.cfg>]Tiatiana
The history of keyring is showing in the beginning of 2016 all but the preferred keyring backends for each of the major desktop platforms have been removed. "...All other keyrings have been moved to a new package, keyrings.alt and backward-compatibility aliases removed."Estivation

© 2022 - 2024 — McMap. All rights reserved.