Ricerca nel sito web

Inserisci password invisibili utilizzando questo modulo Python


Dai alla tua password un ulteriore livello di sicurezza con GPG e il modulo getpass Python.

Le password sono particolarmente problematiche per i programmatori. Non dovresti memorizzarli senza crittografarli e non dovresti rivelare cosa è stato digitato quando l'utente ne inserisce uno. Ciò è diventato particolarmente importante per me quando ho deciso che volevo aumentare la sicurezza del mio laptop. Crittografo la mia directory home, ma una volta effettuato l'accesso, qualsiasi password memorizzata come testo semplice in un file di configurazione è potenzialmente esposta a occhi indiscreti.

Nello specifico, utilizzo un'applicazione chiamata Mutt come client di posta elettronica. Mi consente di leggere e comporre e-mail nel mio terminale Linux, ma normalmente si aspetta una password nel suo file di configurazione. Ho limitato le autorizzazioni sul mio file di configurazione Mutt in modo che solo io possa vederlo, ma sono l'unico utente del mio laptop, quindi non sono veramente preoccupato che gli utenti autenticati guardino inavvertitamente le mie configurazioni. Invece, volevo proteggermi dal pubblicare distrattamente la mia configurazione online, sia per vantarmi che per controllare la versione, con la mia password esposta. Inoltre, anche se non mi aspetto ospiti indesiderati sul mio sistema, volevo assicurarmi che un intruso non potesse ottenere la mia password semplicemente eseguendo cat sulla mia configurazione.

PythonGnuPG

Il modulo Python python-gnupg è un wrapper Python per l'applicazione gpg. Il nome del modulo è python-gnupg, che non devi confondere con un modulo chiamato gnupg.

GnuPG (GPG) è il sistema di crittografia predefinito per Linux e lo utilizzo dal 2009 circa. Mi sento a mio agio e ho un alto livello di fiducia nella sua sicurezza.

Ho deciso che il modo migliore per inserire la mia password in Mutt era memorizzare la mia password in un file GPG crittografato, creare un prompt per la mia password GPG per sbloccare il file crittografato e consegnare la password a Mutt (in realtà al offlineimap, che utilizzo per sincronizzare il mio portatile con il server di posta elettronica).

Ottenere l'input dell'utente con Python è piuttosto semplice. Effettui una chiamata a input e qualunque cosa l'utente digiti viene memorizzata come variabile:

print("Enter password: ")
myinput = input()

print("You entered: ", myinput)

Il mio problema è stato quando ho digitato una password nel terminale in risposta alla richiesta della password, tutto ciò che ho digitato era visibile a chiunque mi guardasse alle spalle o scorresse la cronologia del mio terminale:

$ ./test.py
Enter password: my-Complex-Passphrase

Inserimento della password invisibile con getpass

Come spesso accade, c'è un modulo Python che ha già risolto il mio problema. Il modulo è getpass4 e, dal punto di vista dell'utente, si comporta esattamente come input tranne che non mostra ciò che l'utente sta digitando.

Puoi installare entrambi i moduli con pip:

$ python -m pip install --user \
python-gnupg getpass4

Ecco il mio script Python per creare una richiesta di password:

#!/usr/bin/env python
# by Seth Kenlon
# GPLv3

# install deps:
# python3 -m pip install --user python-gnupg getpass4

import gnupg
import getpass
from pathlib import Path

def get_api_pass():
    homedir = str(Path.home())
    gpg = gnupg.GPG(gnupghome=os.path.join(homedir,".gnupg"), use_agent=True)
    passwd = getpass.getpass(prompt="Enter your GnuPG password: ", stream=None)

    with open(os.path.join(homedir,'.mutt','pass.gpg'), 'rb') as f:
        apipass = (gpg.decrypt_file(f, passphrase=passwd))

    f.close()

    return str(apipass)
    
if __name__ == "__main__":
    apipass = get_api_pass()
    print(apipass)

Salva il file come password_prompt.py se vuoi provarlo. Se stai utilizzando offlineimap e desideri utilizzare questa soluzione per l'immissione della password, salvala in una posizione a cui puoi puntare offlineimap nel tuo .offlineimaprc (io uso ~/.mutt/password_prompt.py).

Testare la richiesta della password

Per vedere lo script in azione, devi prima creare un file crittografato (presumo che tu abbia già configurato GPG):

$ echo "hello world" > pass
$ gpg --encrypt pass
$ mv pass.gpg ~/.mutt/pass.gpg
$ rm pass

Ora esegui lo script Python:

$ python ~/.mutt/password_prompt.py
Enter your GPG password:
hello world

Non viene visualizzato nulla durante la digitazione, ma finché inserisci correttamente la passphrase GPG, vedrai il messaggio di prova.

Integrazione della richiesta di password con offlineimap

Avevo bisogno di integrare il mio nuovo prompt con il comando offlineimap. Ho scelto Python per questo script perché sapevo che offlineimap può effettuare chiamate ad applicazioni Python. Se sei un utente offlineimap, apprezzerai che l'unica "integrazione" richiesta è cambiare due righe nel tuo file .offlineimaprc.

Innanzitutto, aggiungi una riga che fa riferimento al file Python:

pythonfile = ~/.mutt/password_prompt.py

Quindi sostituisci la riga remotepasseval in .offlineimaprc con una chiamata alla funzione get_api_pass() in password_prompt.py :

remotepasseval = get_api_pass()

Niente più password nel tuo file di configurazione!

La sicurezza è importante

A volte sembra quasi paranoico pensare alle minuzie di sicurezza sul tuo personal computer. La tua configurazione SSH deve davvero essere limitata a 600? È davvero importante che la tua password e-mail sia in un file di configurazione irrilevante sepolto all'interno di una cartella nascosta chiamata, tra tutte le cose, .mutt? Probabilmente no.

Eppure sapere che non ho dati sensibili nascosti silenziosamente nei miei file di configurazione mi rende molto più semplice inviare file a repository Git pubblici, copiare e incollare snippet nei forum di supporto e condividere le mie conoscenze nel modulo di file di configurazione effettivi e sicuramente validi. Solo per questo, una maggiore sicurezza mi ha reso la vita più semplice. E con così tanti ottimi moduli Python disponibili per aiutarti, è facile da implementare.

Articoli correlati: