N-PN White-Hat Project
[Python] Chiffrer votre fichier de mot de passe - Version imprimable

+- N-PN White-Hat Project (https://dev.n-pn.fr/forum)
+-- Forum : Informatique (https://dev.n-pn.fr/forum/forumdisplay.php?fid=12)
+--- Forum : Logiciel (https://dev.n-pn.fr/forum/forumdisplay.php?fid=35)
+--- Sujet : [Python] Chiffrer votre fichier de mot de passe (/showthread.php?tid=3803)



[Python] Chiffrer votre fichier de mot de passe - Junky - 14-01-2015

Bonjour,

Alors oui ok le titre fait un peut peur. Peur car je vous vois déjà faire la grimace du "non mais allo quoi!!! Depuis qd on a des mdp dans un fichier hein?". J'en vois certains autres me dire "Non mais toto, y'a déjà des gestionnaires de mdp, pk ré-inventer la roue"

Eh bah oui vous avez raisons mais aux premiers je répondrai:

"Bah grosse entité, avec 42^42 mdp avec tous des règles de sécurités différentes... :/"

et aux deuxièmes:

"Bah j'avais du temps et je voulais essayé... Smile"

Autre chose ? Smile

Bref passons aux choses plus cools...

Le programme utilise des fichiers de config et de mots de passes qui doivent être au format yaml. Je vous laisse vous reporter a la doc yaml pour plus d'infos sur le format. Vous avez aussi un exemple dans le README fournit dans le tar.gz.

Code BASH :

cat README
    ____        ____                                          __
   / __ \__  __/ __ \____ ____________      ______  _________/ /
  / /_/ / / / / /_/ / __ `/ ___/ ___/ | /| / / __ \/ ___/ __  /
 / ____/ /_/ / ____/ /_/ (__  |__  )| |/ |/ / /_/ / /  / /_/ /  
/_/    \__, /_/    \__,_/____/____/ |__/|__/\____/_/   \__,_/  
      /____/                                                    

Pypassword est un logiciel de gestion de mot de passe.

Requirement:
   
    - python-yaml
    - vim

---------------------------------------------------------------------
   
Première Utilisation:

    Lors du premier lancement il faut posséder un fichier nommé
$ori_password_file (se reporter au fichier de config) contenant les
infos a crypter. Ce fichier doit être au format yaml comme suit:

foo:
    description: courte description
    bar: value
    etc....

foo1:
    description: courte description
    bar: value
    etc....

/!\ Encart description OBLIGATOIRE

---------------------------------------------------------------------
 


Le README est voué a évoluer, pour le moment il ne donne qu'un exemple et les packages requis.

J'ai utilisé le format YAML car je le trouve vraiment pratique. J'ai bossé 1ans avec des fichiers de conf de ce type (fichiers de conf VM Xen) et c'est juste un plaisir de l'utiliser.

Vous avez à votre disposition un fichier de config qui références plusieurs parmètres utiles au bon fonctionnement de pypassword:

Code YAML :

# Fichier de config pour pypassword.
# La synthax est de type yaml
#
# Options:
#       debug                   - mode debug
#       ori_password_file       - Fichier non crypté (First run)
#       crypt_password_file           - Nom du fichier crypté
#       path_password_file      - Path des fichiers de configurations
#       path_pypassword         - Path de pypassword
#


debug              
: True

# Nom du fichier non-crypte. (Premiere utilisation"
ori_password_file  
: pass.yaml

# Nom du fichier encrypté des mots de passes.
crypt_password_file      
: password
path_password_file
: None

# Répertoire de travail
path_pypassword    
: .pypassword

 


Elles ne sont pas toutes utilisées pour le moment et j'en ai d'autre a rajouter comme par exemple choisir son EDITOR préféré. Pour le moment c'est vim. Si ca ne vous va pas, modifiez le dans le code.

Donc c'est un programme python, qui va crypter votre fichier de mots de passes via une clé que vous devez saissir au lancement. La clé ne peut pas être donné comme argument (.bash_history Wink ):

Code BASH :

./pass.py

    ____        ____                                          __
   / __ \__  __/ __ \____ ____________      ______  _________/ /
  / /_/ / / / / /_/ / __ `/ ___/ ___/ | /| / / __ \/ ___/ __  /
 / ____/ /_/ / ____/ /_/ (__  |__  )| |/ |/ / /_/ / /  / /_/ /  
/_/    \__, /_/    \__,_/____/____/ |__/|__/\____/_/   \__,_/  
      /____/                                                    

Enter your Key:

 


Pour la demande de key, j'utilise getpass la lib python, qui permet de saisir une value sans que celle-ci ne soit affiché. Une fois votre key saisie, vous aurez 3 choix disponibles:

Code BASH :

Enter your Key:

[x] [E]diter
[x] [C]onsulter
[x] [Q]uitter

>>>
 


Tapez E pour éditer le fichier. Dans ce mode, votre fichier est décrypté et ouvert dans un fichier tmp (lib tempfile). A vous de le modifier a votre convenance, ajout/suppression ce que vous voulez. Une fois le fichier save, celui est crypté et le tmp effacé.

Tapez C pour consulter votre fichier. Le programme vous proposera une vue d'ensemble des sections avec leur description (attention l'encart description est obligatoire pour le moment)

Code BASH :

Enter your Key:

[x] [E]diter
[x] [C]onsulter
[x] [Q]uitter

>>> C
+------------------------+
|Choice or 'q' for leave:|
+------------------------+
=> 0:The Game
 Description
    Ouned les Biatchs!!!!
=> 1:VPN
 Description
    Login/Pass VPN.
=> 2:Tel
 Description
    Login/Pass Phone.
=> 3:Serv002
 Description
    Serveur002
=> 4:Serv001
 Description
    Serveur001
=> 5:Wifi
 Description
    Connection Wifi.
>>>
 


Ensuite saisissez le nombre voulu:

Code BASH :

>>> 1

***********************
VPN
***********************

Account  :  account1
Userid  :  userlogin
Description  :  Login/Pass  VPN.
pass  :  mot_de_passe_super_secure
[x] Exit!
 


Bon je ne sais pas encore pourquoi il me balance la 'description' en plein milieu alors que c'est la première saisis du groupe. Faut que je regarde ca, mais ce n'est qu'un souci d'affichage et ce n'est pas forcément la prio ultime.

Voila une bref présentation du tool. est disponible. Je le mettrai par la suite sur mon git si je le décide de continuer a le faire évoluer.

Zone de téléchargement:
pypassword

Le code n'est pas super propre, j'ai des modifications a apporter, mais aussi de l'optimisation a faire sur des bouts de code juste tt sales. Mais je l'ai codé sur le fil entre 2 réunions et il me faillait un tool op assez rapidement. Smile

N'hésitez à poser des questions si vous en avez ofc...

Junky,


RE: [Python] Crypter votre fichier de mot de passe - ark - 14-01-2015

Yo!

Sympa ton post, mais comme on vient de le dire avec WapiFlapi sur irc, gaffe quand on developpe des tools de crypto!! C'est d'ailleurs rigolo la crypto sur ce point, c'est que sans le savoir, on fait plein d'erreurs!
Bref, du coup, jetons un coup d'oeil a tout ca pour voir ce qui ne va pas. (Je vais juste parler de la partie crypto, parce que t'as bien dit que le code est cracra, et je pense que d'autre s'en chargerons :))

Alors, tout d'abord, j'ai repere ce bout de code:
Code PYTHON :
def cryptfile(original_file, Key , destination_file, debug):                    
        if debug: debugg("Crypt %s dans %s" % (original_file, destination_file))
                                                                               
        FILE_O = open(original_file,"r") if os.path.exists(original_file) else quit(2, "Impossible d'ouvrir %s. Reportez au README" % original_file)
        FILE_D = open(destination_file,"w")                                    
        message = msg_len(FILE_O.read())                                        
        Key = msg_len(Key)                                                      
        coder = AES.new(Key, AES.MODE_ECB)                                      
        message = coder.encrypt(message)                                      
        FILE_D.write(message)                                                  
        FILE_O.close()
        FILE_D.close()


Ici, l'utilisation du mode ECB n'est pas une bonne idee. En effet, ce mode va chiffrer chaque bloc de la meme facon, et si un bloc se repete, on observera une repetition dans la cipher text. En soi, ca leak des infos, et c'est pas une bonne chose. Typiquement dans ton cas, si t'as deux mots de passes pareils, tu pourrais le savoir rien qu'en lisant les datas du ciphertext. Ensuite, il est possible d'effectuer une attaque sur ce genre de ciphertext, surtout si le contenu est bien long (42 ^ 42 mots de passes :p) afin de retrouver la cle, et donc le contenu.

Personellement, je conseillerais d'utiliser soit un mode CBC, soit un mode CTR. (et je recommande a tous ceux qui ne connaissent pas la lecture de cet article: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation)
Le mode d'operation est un des concepts tres importants en cryptographie, et ca serait bien d'arreter d'utiliser de ECB !

Un autre concept important en crypto, c'est le padding. Et la, tu nous fait un padding a ta sauce, pas forcement bon. En l'occurence ici, tu t'en fous que tes donnees soit des donnees binaire, et donc en theorie, tu vas avoir uniquement des char affichable dans ton clear text. Ce qu'il y a c'est qu'en temps normal, c'est pas forcement le cas, et que du coup, il faut pouvoir etre sur de ce qui est le padding, et ce qui ne l'est pas.

Pour le coup, c'est generalement le padding definit par PKCS#7 qui est utilise (http://tools.ietf.org/html/rfc2315#section-10.3)
En gros, ca consiste a mettre la longueur du padding sur tous les bytes du padding.

Comme ca (en python3):
Code PYTHON :
length = 16 - (len(data) % 16)
data += chr(length)*length


Et du coup, tu le remove, apres le dechiffrement, de la facon suivante:
Code PYTHON :
data = data[:-data[-1]]


Et ensuite, il y a ca:
Code PYTHON :
def edit_password(crypt_password_file, Key):                
        tmp = tempfile.NamedTemporaryFile(suffix=".tmp")    
        editor = os.environ.get('EDITOR','vim')            
        message = decrypt_file(crypt_password_file, Key)    
        tmp.write(message[0])                              
        tmp.flush()                                        
        call([editor,tmp.name])                            
        cryptfile(tmp.name, Key, crypt_password_file, False)
        tmp.close()                                        


Et la, c'est pas tant un probleme de chiffrement, mais de ce qu'on appelle "side channel", en effet, ici, tu nous ecris le contenu dechiffre sur le disque dur, le temps de l'edition. Il suffit a un attaquant de poser un programme qui va check tout tes fichiers *.tmp dans ton repertoire /tmp et de les leak. Et la, au moment ou tu vas editer tes mots de passes, il va pouvoir tout recuperer d'un coup!
Pas joli joli :p Le mieux serait de se debrouiller pour tout modifier en RAM directement, mais il ne faut surtout pas aller ecrire le contenu dechiffre sur le disque ! En plus, j'ai pas l'impression que tu delete le fichier ^^

J'ai fini ! :p

Ah, et pour la route, on dit CHIFFRER et pas crypter. (cf je sais plus quel thread (mais j'editerais si je le retrouve :D))


RE: [Python] Crypter votre fichier de mot de passe - Junky - 15-01-2015

Merci pour ce retour ark.

Apres je n'ai jamais codé crypto, c'est juste mon premier tool (tu connais mon AMOUR pour la crypto. Smile )
Je voulais dans un premier tps un tool qui fait le taf. Je ne voulais pas en clair mes mdp.

Citation :En plus, j'ai pas l'impression que tu delete le fichier ^^

doc python
Code BASH :

 tempfile.NamedTemporaryFile([mode='w+b'[, bufsize=-1[, suffix=''[, prefix='tmp'[, dir=None[, delete=True]]]]]])

    This function operates exactly as TemporaryFile() does, except that the file is guaranteed to have a visible name in the file system (on Unix, the directory entry is not unlinked). That name can be retrieved from the name attribute of the file object. Whether the name can be used to open the file a second time, while the named temporary file is still open, varies across platforms (it can be so used on Unix; it cannot on Windows NT or later). If delete is true (the default), the file is deleted as soon as it is closed.
 


J'avais regardé qd même si le fichier était delete. Je suis noobass en dev/crypto mais qd même. Big Grin

En tt cas merci pour ce retour totalement constructif. Smile

J'améliorerai le tout.

Junky


RE: [Python] Chiffrer votre fichier de mot de passe - 0pc0deFR - 17-01-2015

Petit plantage dans ton code: si l'éditeur de texte utilisé dans le code n'est pas disponible sur la machine:
Code :
Traceback (most recent call last):
  File "pass.py", line 206, in <module>
    action(config)
  File "pass.py", line 104, in action
    if (choice == 'E'): edit_password(config['crypt_password_file'], Key)
  File "pass.py", line 179, in edit_password
    call([editor,tmp.name])
  File "/usr/lib/python2.7/subprocess.py", line 522, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

et le fichier XXXXX.tmp n'est pas supprimé donc reste disponible sur la machine, dans le dossier /tmp.
Peut être voir pour utiliser les exceptions.


RE: [Python] Chiffrer votre fichier de mot de passe - Junky - 17-01-2015

Bonjour,

Citation :Pour le moment c'est vim. Si ca ne vous va pas, modifiez le dans le code.

Si il plante en effet, le .tmp doit certainement resté mais ca parait normal en faite. Mais j'ai pas mal d'améliorations à faire. La c'est un premier jet sur le cailloux.

Junky,


RE: [Python] Chiffrer votre fichier de mot de passe - octarin - 17-01-2015

Excellent code Junky !
Je tiens d'ailleurs à vous faire connaître cet excellent utilitaire que j'ai découvert il y a peu, http://www.passwordstore.org/.