XOR-Verschlüsselung

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Zilchinger
User
Beiträge: 10
Registriert: Dienstag 18. April 2006, 00:01

Dienstag 18. April 2006, 00:26

Ich sag erstmal Hallo und melde mich als neuer User ins Forum 8) ...hehe

Ich bin ziemlich neu in der Sprache Python und lerne jeden Tag unmengen dazu. Ich programmiere zur Zeit an einem größeren Projekt, worin auch eine XOR-Verschlüsselung benötigt wird.

Das ist auch mein Problem:
Prinzipiell habe ich da was gebaut, was auch wunderbar funktioniert. Solange die Streams, die Verschlüsselt werden sollen relativ klein sind.
Will ich jedoch eine Datei verschlüsseln, die > 1 mb ist, dann kann ich nicht nur ne Kanne Kaffetrinken gehen.

Hier mal der Quelltext:

Code: Alles auswählen

import StringIO
import operator

class XORCrypter:
    
    __password = None
    
    def __init__(self, password):
        self.__password = password;
        
    def cryptXOR(self, input):
        sr = StringIO.StringIO(input)
        sw = StringIO.StringIO(input)
        kIdx = 0
        for x in range(len(input)):
            sr.seek(x)
            sw.seek(x)
            sw.write(chr( ord(sr.read(1)) ^ ord(self.__password[kIdx])))
            kIdx = (kIdx + 1) % len(self.__password) 
        sw.seek(0);
        result = sw.read();
        sr.close()
        sw.close()
        return result
Gibt es da nicht irgendwie eine performantere Methode?

Würde mich freuen, wenn mir jemand helfen, oder Anregungen geben könnte!

Bis dann,
Zilchinger
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Dienstag 18. April 2006, 06:54

Zilchinger hat geschrieben:Ich sag erstmal Hallo
[...]
Ich programmiere zur Zeit an einem größeren Projekt, worin auch eine XOR-Verschlüsselung benötigt wird.
Hi Zilchinger!

Willkommen hier im Board. :D
Hier ein Link, der dir vielleicht weiter hilft: http://www.amk.ca/python/code/crypto.html

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Dienstag 18. April 2006, 08:22

Ich bin mir momentan alles andere als sicher ob PyCrypto eine XOR-Verschlüsselung definiert (in C), aber auf jeden Fall kann man die relativ einfach selbst bauen (wie immer):

xorc.c

Code: Alles auswählen

/* XOR Crypto for Python, in C.
   Copyright (C) 2006, Heiko Wundram.
   Use freely, but without any warranty from the author... :-) */

#include <stdlib.h>
#include <Python.h>

typedef struct {
  char *pwd;
  int pwdlen;
  int pwdpos;
} xorstate;

void xorfree(xorstate *state)
{
  free(state->pwd);
  free(state);
}

PyObject *xorsetup(PyObject *self, PyObject *args)
{
  char *pwd;
  int pwdlen;
  xorstate *state;
  PyObject *pystate;

  if( !PyArg_ParseTuple(args,"s#",&pwd,&pwdlen) )
    return NULL;

  if( !( state = (xorstate*)malloc(sizeof(xorstate)) ) ) {
    PyErr_SetString(PyExc_MemoryError,"Couldn't allocate XOR buffer.");
    return NULL;
  }
  if( !( state->pwd = (char*)malloc(pwdlen) ) ) {
    free(state);
    PyErr_SetString(PyExc_MemoryError,"Couldn't allocate string buffer.");
    return NULL;
  }
  memcpy(state->pwd,pwd,pwdlen);
  state->pwdlen = pwdlen;
  state->pwdpos = 0;
  if( !( pystate = PyCObject_FromVoidPtr(state,xorfree) ) ) {
    free(state->pwd);
    free(state);
    PyErr_SetString(PyExc_MemoryError,"Couldn't allocate PyCObject.");
    return NULL;
  }

  return pystate;
}

PyObject *xor(PyObject *self, PyObject *args)
{
  char *data, *xordata;
  int datalen, curpos;
  PyObject *pystate, *pydata;
  xorstate *state;

  if( !( PyArg_ParseTuple(args,"Os#",&pystate,&data,&datalen) ) )
    return NULL;

  if( !PyCObject_Check(pystate) ) {
    PyErr_SetString(PyExc_ValueError,"First parameter must be a state.");
    return NULL;
  }
  state = PyCObject_AsVoidPtr(pystate);
  if( !( xordata = (char*)malloc(datalen) ) ) {
    PyErr_SetString(PyExc_MemoryError,"Couldn't allocate xor array.");
    return NULL;
  }
  memcpy(xordata,data,datalen);
  for( curpos = 0; curpos < datalen; curpos++ )
    xordata[curpos] = data[curpos] ^ state->pwd[(curpos+state->pwdpos)%
						state->pwdlen];
  state->pwdpos = (curpos+state->pwdpos) % state->pwdlen;
  pydata = PyString_FromStringAndSize(xordata,datalen);
  free(xordata);

  return pydata;
}

static PyMethodDef XorCMethods[] = {
  {"setup",xorsetup,METH_VARARGS,
   "Sets up a structure which keeps track of the encryptions state."},
  {"xor",xor,METH_VARARGS,
   "XORs the passed buffer with a specified "},
  {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC initxorc()
{
  Py_InitModule("xorc",XorCMethods);
}
Und der entsprechende setup.py-File:

setup.py

Code: Alles auswählen

# -*- coding: iso-8859-15 -*-

from distutils.core import setup, Extension

xorc = Extension('xorc',sources=['xorc.c'])

setup(name='xorc',version='0.1',
      description='Encrypts a string using a simple XOR crypt.',
      ext_modules=[xorc])
Das ganze ist folgendermaßen zu benutzen:

Code: Alles auswählen

modelnine@phoenix ~/xorc/build/lib.linux-x86_64-2.4 $ python
Python 2.4.2 (#1, Apr  3 2006, 12:10:45)
[GCC 3.4.6 (Gentoo 3.4.6, ssp-3.4.5-1.0, pie-8.7.9)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import xorc
>>> state = xorc.setup("mein geheimes kennwort")
>>> xorc.xor(state,"Ich will diesen Text verschlüsseln; wer kann mir sagen was rauskommt?")
'$\x06\x01NW\x0e\t\x04E\r\x04\x00\x00E\x05E:\x0b\x0f\x1bR\x02\x08\x17\x1a\rH\x0b\x99\x1b\x16\x0c\x01\x0bH\x00\x1c\x00\x1cN\x1c\x0e\x1c\x1aM\x08\x00\x1c\x00\x14\x04\x0f\x00\x07M\x12\x12SK\x17\x0f\x1b\x04\x04\x1d\x19\x00\x11V'
>>> decstate = xorc.setup("mein geheimes kennwort")
>>> xorc.xor(decstate,'$\x06\x01NW\x0e\t\x04E\r\x04\x00\x00E\x05E:\x0b\x0f\x1bR\x02\x08\x17\x1a\rH\x0b\x99\x1b\x16\x0c\x01\x0bH\x00\x1c\x00\x1cN\x1c\x0e\x1c\x1aM\x08\x00\x1c\x00\x14\x04\x0f\x00\x07M\x12\x12SK\x17\x0f\x1b\x04\x04\x1d\x19\x00\x11V')
'Ich will diesen Text verschl\xfcsseln; wer kann mir sagen was rauskommt?'
>>>
modelnine@phoenix ~/xorc/build/lib.linux-x86_64-2.4 $
Ich hab einen kurzen Test gemacht der den Durchsatz auf meinem Rechner auf knapp 29MB/s misst (natürlich mit der Quelldatei im Plattencache...).

Viel Spaß damit!

EDIT by mawe: hab den C-Code eingefärbt
--- Heiko.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Dienstag 18. April 2006, 08:37

modelnine hat geschrieben:Ich bin mir momentan alles andere als sicher ob PyCrypto eine XOR-Verschlüsselung definiert (in C)
Hi modelnine!

Ich habe PyCrypto noch nicht ausprobiert. Ich kenne nur die Beispiele aus dem Internet. Die Beschreibung auf der Homepage "Stream encryption algorithms: ARC4, simple XOR" hat mich dazu verleitet, den Link hier zu erwähnen.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Dienstag 18. April 2006, 18:58

Humm... Ich hab gerade auch noch mal geguckt, und tatsächlich, es scheint dass PyCrypto mittlerweilen eine XOR-Verschlüsselung bekommen hat. Als ich vor ewigen Zeiten mal einen Wrapper für PyCrypto geschrieben hab (um es einfacher benutzbar zu machen, yawPyCrypto um genau zu sein) hatte es noch kein C-Modul dafür, und als ich heute morgen auf die Seite geguckt hab, hab ich beim skimmen auch keine Referenz auf XOR gefunden. Okay. Vielleicht kann's ja jemand trotzdem gebrauchen. ;-)
--- Heiko.
Zilchinger
User
Beiträge: 10
Registriert: Dienstag 18. April 2006, 00:01

Mittwoch 19. April 2006, 11:25

Danke für den großen Aufwand.
Ich werde mich da mal reinfuchsen.

Bis die Tage,
Zilchinger
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

Mittwoch 19. April 2006, 20:41

Ich habe ein paar Fragen:
Macht es Sinn, das XORC-Ergebnis noch eimal zu verschlüsseln (noch einmal XORC oder 128bit?)
Wo muss der Skript liegen, um ausgeführt werden zu können?
Noch ein Fehler:
/var/mail/distutils.core
ist bei mir nicht vorhanden...der ganze Order /var/mail ist leer, deshalb eine korrekte fehlermeldung^^ Wie kann ich das nachbessern?
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Mittwoch 19. April 2006, 21:27

murph hat geschrieben:Wo muss der Skript liegen, um ausgeführt werden zu können?
Egal wo. Wenn du es mit python <pafd_zum_stript> aufrufst, ist das vollkommen egal. Wenn du unter Linux arbeitest, ist es praktisch noch das Skript mit chmod a+x skript.py ausführbar zu machen, man kann es dann auch mit ./skript.py ausführen.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

Donnerstag 20. April 2006, 04:59

Wenn er sich nun selbst

Code: Alles auswählen

#include <stdlib.h>
#include <Python.h>
holt, dann nur noch der Fehler mit dem leeren Ordner (ich kann bei der Installation nichts falsch geamcht ahben, das war von Ubuntu(Linux) vorinstalliert. Aber da werde ich mcih dann an das entsprechende Forum bei Ubuntu wenden.
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Donnerstag 20. April 2006, 07:09

Noch mal kurz was zur Verschlüsselungs_sicherheit_ dieses Algorithmus: nicht existent.

1) Es macht keinen Sinn das Ergebnis einer XOR-Verschlüsselung noch mal mittels des selben Algorithmus zu Verschlüsseln, die Brechbarkeit des Algorithmus erschwert sich dadurch kein bisschen (es ist einfach so als ob man anstelle des ursprünglichen Schlüssels einen anderen, lcm(len(schlüssel1),len(schlüssel2))-langen Schlüssel der sich aus den beiden Schlüsseln mittels XOR-Verschlüsselung ergibt, benutzt hätte), wobei sogar wenn man zwei Schlüssel benutzt die Entschlüsselungsreihenfolge egal ist, also:

d(schlüssel2,d(schlüssel1,c)) = d(schlüssel1,d(schlüssel2,c))

wobei d die Entschlüsselungsfunktion (die bei XOR == e ist) und c der Cyphertext (also das Chiffrat).

Kleiner Zusatz: die "Verschlüsselungssicherheit" erhöht sich natürlich, wenn len(schlüssel1) und len(schlüssel2) ungleiche Primzahlen sind (bzw. nur ggT der beiden == 1 ist, bei Primzahlen ist er das aber immer), da dann die effektive Schlüssellänge len(schlüssel1)*len(schlüssel2) ist. Sobald man aber zwei gleichlange Schlüssel benutzt (was ja der Normalfall ist) hat man gar keinen Gewinn, darauf wollte ich hinaus. Was aber nicht bedeutet, dass es noch einen anderen Angriff gibt, der die effektive Schlüssellänge bei solcherart synthetisierten Schlüsseln reduziert, schließlich IANAC (I am not a cryptographer).

2) Die Sicherheit der XOR-Verschlüsselung ist trivial. Durch ein bisschen Zeichenhäufigkeitssuche kann man bei einem mittellangen Text die Verschlüsselung maschinell einfachst brechen, und zwar indem man den Text suksessive in Zeilen aufteilt (einer fixen Länge, genau wie der Schlüssel), und dann einfach in einer Spalte die Zeichenhäufigkeit vergleicht mit Werten die man für eine entsprechende natürliche Sprache kennt. Auch wenn das ganze ein bisschen Zeit braucht, so ist diese Zeit auf einem modernen Rechner < 5s für einen längeren Text (der in einer natürlichen Sprache geschrieben ist).

3) Genauso, wenn ich bei der XOR-Verschlüsselung die Struktur des verschlüsselten Textes kenne (zum Beispiel das er mit "halligalli123" anfängt), dann kann ich unmittelbar auf diese Anzahl von Zeichen des Schlüssels zurückschließen, und habe dann meißtens schon den ganzen Schlüssel.

Insgesamt: XOR ist für eine sinnvolle Verschlüsselung nie im Leben geeignet. Es ist mehr ein Beispiel für eine symmetrische Funktion.
--- Heiko.
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Donnerstag 20. April 2006, 13:24

modelnine hat geschrieben:Insgesamt: XOR ist für eine sinnvolle Verschlüsselung nie im Leben geeignet. Es ist mehr ein Beispiel für eine symmetrische Funktion.
XOR ist absolut sicher, allerdings NUR, wenn
a) der Schlüssel mindestens genauso lang ist wie der Text, und
b) der Schlüssel komplett zufällig ist, und
c) kein Schlüssel mehrmal verwendet wird.

Ansonsten gilt natürlich das von modelnine gesagte. Wenn ihr Sicherheit wollt, nehmt einfach einen erprobten Verschlüsselungsalgo, z.B. AES oder Blowfish (beides ist mit PyCrypto kein Problem)
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

Donnerstag 20. April 2006, 13:53

Ein absolut sichere Verschlüsselung ist das One Time Pad. Es ist in der praxis sehr schwer anwendbar, dafür aber auch unmöglich knackbar(wenn einige Bedingungen erfüllt sind).

Aber leider kann man das mit PyCrypto nicht machen! :?
mfg

Thomas :-)
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Donnerstag 20. April 2006, 14:09

Ein absolut sichere Verschlüsselung ist das One Time Pad.
XOR mit längerem Schlüssel als Plaintext ist eine Art von One-Time-Pad-Verschlüsselung.
--- Heiko.
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

Donnerstag 20. April 2006, 14:10

modelnine hat geschrieben:
Ein absolut sichere Verschlüsselung ist das One Time Pad.
XOR mit längerem Schlüssel als Plaintext ist eine Art von One-Time-Pad-Verschlüsselung.
Achso gut, das wusste ich nicht!Man lernt eben nie aus! :wink:
mfg

Thomas :-)
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Donnerstag 20. April 2006, 14:24

Normalerweise bedeutet "One-Time-Pad" keinen spezifischen Algorithmus (der Name kommt zwar von einer bestimmten Anwendung, aber...), sondern spezifiziert eine Klasse von Algorithmen mit bestimmten Eigenschaften, wie die "Unbrechbarkeit." (die auch hier sehr relativ zu verstehen ist bei einer real-world-Anwendung, aber dazu lass ich mich jetzt nicht aus ;-))
--- Heiko.
Antworten