11
votes

Obfuscation efficace de python de la chaîne

J'ai besoin d'obscurcir les lignes de texte Unicode pour ralentir ceux qui voudront peut-être les extraire. Idéalement, cela se ferait avec un module Python intégré ou une petite bibliothèque complémentaire; La longueur de la chaîne sera la même ou inférieure à l'original; et la "discussion" soit aussi rapide que possible.

J'ai essayé divers swaps de caractère et routines XOR, mais ils sont lents. La base64 et le codage hexagonal augmentent considérablement la taille. À ce jour, la méthode la plus efficace que j'ai trouvée consiste à compresser avec zlib au réglage le plus bas (1). Y a-t-il une meilleure façon?


14 commentaires

Utilisez un bon système de cryptage très fréquenté et largement utilisé. Tout le reste est cassé dès que quiconque compétent a une idée de ce que vous faites. Oui, cela prendra du temps, mais c'est le prix que vous avez de payer si vous voulez quelque chose de décent à distance. Si les données ne sont même pas assez importantes pour cela, épargnez-vous simplement les tracas et envoyez-le en tant que texte brut.


Vous avez dit "ralentir", pas "empêcher". Essayez-vous vraiment d'empêcher les gens de lire le texte? Dans quelles conditions le texte original doit-il être lu?


La vitesse est plus importante pour moi que la sécurité. Le cryptage ralentit l'accès des données de manière significative. S'il y avait un schéma de cryptage qui n'a pas causé de goulot d'étranglement important, de nombreux problèmes de développeur seraient résolus. N'y a-t-il pas de place pour un terrain d'entente avec ce problème? Bien sûr, une personne avec la connaissance et un temps libre pourrait obtenir les données, mais cela vaut-il de la peine.


Ce problème est similaire à la qualité des serrures sur la maison. Une porte de la voûte bancaire serait la plus sûre, mais combien d'avoir cela? La plupart se rendent compte qu'il est presque impossible de garder un intrus déterminé, mais ils ont toujours des serrures relativement faibles sur leurs portes pour garder le moins déterminé. C'est tout ce que je veux avec cette obfuscation. Je ne veux tout simplement pas quitter les portes à ma maison grand ouverte.


@Tim: "Qualité des serrures" est défectueux. Le logiciel n'est pas identique à un cornet pour ouvrir une serrure mécanique. Une fois que l'algorithme est connu, l'effet "ralentissement" tombe immédiatement à zéro. Les voûtes bancaires avec combinaisons connues sont aussi inutiles que les portes d'écran avec des crochets simples pour garder le vent fermé dans le vent. Même avec cette "Obfuscation". Une fois que l'obfuscation est connue, le ralentissement tombe immédiatement à zéro.


Oui, il tombe à proximité de zéro lorsque l'intrus connaît l'algorithme et comment la mettre en œuvre, mais cela prend des efforts. Vraiment, la seule différence entre le cryptage simple d'obfuscation et de grade militaire est l'effort qu'un ou plusieurs veulent présenter pour la rompre. Toutefois, à l'observateur occasionnel à l'aide d'un éditeur de texte, on a l'air comme l'autre. Je vous aventue que la plupart ne prendront pas le temps de jouer avec elle.


@ S.Lott, si l'idée est de cacher du texte que le programme décrypte pour lui-même, tout programmeur qualifié qui souhaite faire l'effort peut faire craquer quels algorithme que vous utilisez, car le programme inclut toutes les informations nécessaires. Je recueillis Tim veut simplement arrêter les gens qui viendront simplement regarder le code avec un programme de vidage hexagonal.


@Tom ZYCH: "Le programme inclut toutes les informations nécessaires". Sauf bien sûr, la clé fournie sur le temps d'exécution utilisée. Manquant que la phrase secrète clé rend le cryptage plus difficile à casser.


@ S.Lott: Quelqu'un a-t-il dit que la clé ne serait pas intégrée au programme? J'ai eu l'impression que cela serait autonome.


@Tom Zych: "autonome" et en utilisant une phrase passe au démarrage est courant. SSL, par exemple, fonctionne de cette façon dans Apache. À peine une limitation.


@TOM: Vous êtes correct. Je veux juste que le texte soit brouillé pour l'utilisateur moyen afin qu'ils ne puissent pas copier / coller facilement, extraire, etc. et "emprunter" les données. La vitesse est la plus cruciale. J'ai plus de 31 000 lignes de texte dans un DB SQLite et un chiffrement véritable ralentissent dans une analyse. La compression ZLIB est beaucoup mieux mais toujours considérablement plus lente que le texte brut.


@Tim: "Le vrai cryptage ralentit-il à un crawl"? Pourquoi? Vous ne chiffrez que dans le téléchargement. Pourquoi chiffrer ce qui est dans la base de données?


@ S.Lott: Comme la DB est distribuée avec l'application et peut être facilement ouverte avec un visualiseur SQLite (Firefox). Le cryptage SQLite (APSW) est également très lent. Zlib est la méthode la plus rapide que j'ai trouvée. Un index de texte brut (qui serait accessible via un spectateur aussi), je n'ai pas trouvé de meilleure façon.


@Tim: Quelle est la taille de ce dB? Est-ce de plus de 1 Go? Sinon, pourquoi est-ce une base de données relationnelle et non des structures Python marinées que vous déchiffrez une fois lorsque vous les chargez en mémoire? Pourquoi désordre avec un RDBM (lent) distribué avec une application?


3 Réponses :


12
votes

Ceci utilise un schéma de cryptage simple et rapide sur octets code> Objets.

# For Python 2

mask = 'keyword'
nmask = [ord(c) for c in mask]
lmask = len(mask)

def obfuscate(s):
    # Use same function in both directions.  Input and output are
    # Python 2 strings, ASCII only.
    return ''.join([chr(ord(c) ^ nmask[i % lmask])
                    for i, c in enumerate(s)])

def test(s):
    data = obfuscate(s.encode('utf-8'))
    print len(s), len(data), repr(data)
    newdata = obfuscate(data).decode('utf-8')
    print newdata == s


simple_string = u'Just plain ASCII'
unicode_string = (u'sensei = \N{HIRAGANA LETTER SE}\N{HIRAGANA LETTER N}'
                  '\N{HIRAGANA LETTER SE}\N{HIRAGANA LETTER I}')

test(simple_string)
test(unicode_string)


5 commentaires

Ça a l'air bien, mais je n'ai pas mentionné que je suis limité à Python 2.5-2.7. Je n'ai même pas de 3.x sur mon système à tester avec. Quel est l'équivalent 2.x équivalent au module d'octets?


@Tim: essayez ceci. Je n'ai que 2,6 sur cette machine et on dirait que cela n'a pas interprété le \ n {...} , donc je ne pouvais donc pas le tester aussi complètement que j'aimerais.


Merci pour la version 2.x. Malheureusement, il est beaucoup plus lent que zlib.compress (). Pour un fichier de 6 Mo, cela prend environ 5,1 secondes. Avec zlib il faut .18 sec. Environ 25 fois plus vite.


Probablement la différence entre le code C et le code Python natif. Allez avec Zlib, puis.


Il faut également faire attention lorsque vous traitez avec la chaîne obscurcée, car elle peut avoir \ x00 (caractère Terminator à chaîne). Dans mon cas, il tronquait un mot de passe obscurposé lorsqu'il était stocké dans la base de données.



11
votes

Que diriez-vous de l'ancien Rot13 Trick? XXX

pour une chaîne UNICODE: xxx


2 commentaires

Mis à jour pour Unicode - il suffit d'y échapper d'abord. L'échappement ajoute sans frais de surcharge pour des caractères non unicode.


Je ne savais pas à propos de l'évasion Unicode, agréable. Cependant, il faut environ deux fois plus long que zlib.compress (S, 1). On pourrait penser qu'une simple substitution serait plus rapide, mais pas selon mes tests rapides.



1
votes

Cela dépend de la taille de votre entrée, si elle est supérieure à 1K, puis en utilisant est d'environ 60 fois plus vite (fonctionne dans moins de 2% du code naïf python). xxx

 Table des résultats

Note: Je suis un novice avec Numpy , si quelqu'un a des commentaires sur mon code, je serais très heureux d'en entendre parler dans les commentaires .


0 commentaires