Bonjour,
Voilà le code et la méthode de la solution proposée.
Il faut, bien entendu, avoir installé cython, ce qui est facile: les Linux modernes ont un paquet cython, et il y a un binaire pour Windows.
Il faut d'abord créer la fonction qui cachera le mot de passe: elle sera utilisée uniquement dans les outils de développement. Dans cette solution, il n'est pas prévu qu'un utilisateur puisse changer le mot de passe, puisque cela nécessiterait une recompilation Cython.
La solution choisie ici est de faire un XOR de chaque caractère avec un masque. Mais comme le résultat sera binaire, il faut ajouter une conversion par base64 pour arriver à un texte qu'on pourra intégrer dans un script. Voir l'exemple qui suit.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import division
# Python 2.7
import base64
#############################################################################
def cache_mdp(mdp, masque=137):
"""cache le mot de passe 'mdp' par un XOR avec le masque
et une conversion base64
"""
ch = ""
for car in mdp:
ch += chr(ord(car)^masque)
ch64 = base64.b64encode(ch)
return ch64 |
Application:
1 2 3 4 5 6 7 8
| mdp = "Paquerette99"
masque = 137
print cache_mdp(mdp)
2ej4/Oz77P397LCw
print bin(masque)
0b10001001 |
Maintenant, on va créer le module qui sera compilé en Cython et qui retournera le mot de passe décrypté. Le module s'appellera, par exemple, "mdpasse.pyx".
Dans les différentes possibilités de syntaxe proposées par la documentation de Cython, j'utilise les décorateurs, ce qui me permet d'écrire en "pure Python" (http://docs.cython.org/src/tutorial/pure.html).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import division
# Python 2.7
import base64
from cython import ccall, returns, locals
#############################################################################
@ccall # permet à cette fonction d'être appelée par C ou par Python
@returns(str) # type de la valeur retournée
@locals(mdp64=str, masque=int, ch=str, mdp=str, car=str) # arg. et var. locales
def mdpasse():
"""retourne en clair le mot de passe caché"""
# mot de passe caché
mdp64 = "2ej4/Oz77P397LCw"
masque = 137
# décodage
ch = base64.b64decode(mdp64)
mdp = ""
for car in ch:
mdp += chr(ord(car)^masque)
return mdp |
On ajoute un fichier "setup.py":
1 2 3 4 5 6 7 8 9 10 11
| from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [Extension("mdpasse", ["mdpasse.pyx"])]
setup(
name = 'mdpasse',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
) |
Et on va compiler en console avec l'instruction suivante (il faut se mettre dans le répertoire qui contient le module mdpasse.pyx et son setup.py):
python setup.py build_ext --inplace
La conversion mdpasse.pyx => mdpasse.c se fait et la compilation de ce dernier donne le module compilé mdpasse.pyd sous Windows ou mdpasse.so sous Linux. Ce module compilé est le seul fichier à diffuser.
Pour savoir s'il est facile de retrouver le mot de passe, il suffit de lire ce fichier binaire avec un éditeur hexa: on voit bien que seule une décompilation (reverse engineering) permettrait de le retrouver, ce qui n'est pas à la portée du premier venu. Et il faudrait que l'enjeux "vaille le coup" d'un tel effort.
Il ne reste plus qu'à utiliser dans un autre script Python:
1 2 3 4 5 6 7 8 9
| #!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import division
# Python 2.7
import mdpasse
print mdpasse.mdpasse()
Paquerette99 |
Ok?
Partager