RSA-Bastelei

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

pixelshooter

Betreff: RSA-Bastelei

BeitragMi, Jun 20, 2007 22:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Da mistet man mal seine platte aus, und findet so alte schätzchen, die man vor monaten gecodet hat xD:
Ein Programm, das dateien anhand von RSA verschlüsselt. Nichts dolles, nicht multi-key, vorverschlüsselte Schlüssel...
aber vllt interessiert der ansatz vllt jemanden:
Lauffähinges Programm, einfach in Blitz kopieren und starten.
Code: [AUSKLAPPEN]
;RSA-Verschlüsselung
;==============================
;Functions (RSA):    rsafile(file$,e,n)*: Konvertiert eine Datei in eine RSA-verschlüsstelte Kopie mit der Endung *.rsa
;                    unrsafile(file$,e,p,q)*: Entschlüsselung
;                    createkeys(minsize,maxsize): Generiert zufällige Schlüssel
;Functions (andere): expmod(zahl,exponent,modulo): zum Potenzieren großer Zahlen in der Modul-Arithmetik
;                    IfPrim(zahl[,maximum]): gib WAHR zurück, wenn die Zahl eine Primzahl ist. maximum gibt die maximale Suchtiefe für den Teiler an
;                    Ifgerade(zahl):  gib WAHR zurück, wenn die Zahl gerade ist.
;
; *: e,p und q sind die privaten Schlüssel, die zum Dechiffrieren benötigt werden. n = p * q. n und e sind die öffentlichen Schlüssel
;    und werden zum verschlüsseln benötigt.

Graphics 800,600,0,2
AppTitle "RSA - Konverter"
ClsColor 255,255,220
Color 0,0,0
Repeat
   .start
   Cls
   SetFont LoadFont ("lucida Console",30,1)
   Text GraphicsWidth() / 2,0,"RSA - Konverter by Fabian Lenzen",1
   SetFont LoadFont("lucida Console",15,1)
   Rect GraphicsWidth() / 2 - 205,50,200,50,0
   Rect GraphicsWidth() / 2 + 5,50,200,50,0
   Text ((GraphicsWidth() / 2 - 205) + GraphicsWidth() / 2 - 5) / 2,(50 + 100) / 2,"Datei Verschlüsseln",1,1
   Text ((GraphicsWidth() / 2 + 205) + GraphicsWidth() / 2 + 5) / 2,(50 + 100) / 2,"Datei Entschlüsseln",1,1
   WaitMouse()
   If MouseX() > (GraphicsWidth() / 2 - 205) And MouseX() < (GraphicsWidth() / 2 - 5) And MouseY() > 50 And MouseY() < 100
      Color 165,165,150
      Rect GraphicsWidth() / 2 - 205,50,200,50,1
      Rect GraphicsWidth() / 2 + 5,50,200,50,1
      Color 100,100,065
      Rect GraphicsWidth() / 2 - 205,50,200,50,0
      Rect GraphicsWidth() / 2 + 5,50,200,50,0
      Text ((GraphicsWidth() / 2 - 205) + GraphicsWidth() / 2 - 5) / 2,(50 + 100) / 2,"Datei Verschlüsseln",1,1
      Text ((GraphicsWidth() / 2 + 205) + GraphicsWidth() / 2 + 5) / 2,(50 + 100) / 2,"Datei Entschlüsseln",1,1
      Color 0,0,0
      Text GraphicsWidth() / 2,110,"Datei Verschlüsseln",1
      Locate 0,130
      .name
      Quelle$ = Input$("Quelldatei: ")
      If FileSize(quelle) = 0 Then
         Print "ERROR: Datei nicht gefunden"
         Delay 1000
         Goto start
      EndIf
      Rect GraphicsWidth() / 2 - 205,150,200,50,0
      Rect GraphicsWidth() / 2 + 5,150,200,50,0
      Text ((GraphicsWidth() / 2 - 205) + GraphicsWidth() / 2 - 5) / 2,(150 + 200) / 2,"[Schlüssel aus Bank]",1,1
      Text ((GraphicsWidth() / 2 + 205) + GraphicsWidth() / 2 + 5) / 2,(150 + 200) / 2,"Schlüssel Eingeben",1,1
      .mouse
      WaitMouse()
      If MouseX() > (GraphicsWidth() / 2 - 205) And MouseX() < (GraphicsWidth() / 2 - 5) And MouseY() > 150 And MouseY() < 200
      ElseIf MouseX() > (GraphicsWidth() / 2 + 5) And MouseX() < (GraphicsWidth() / 2 + 205) And MouseY() > 150 And MouseY() < 200
         Locate 0,200
         keye = Input("Schlüssel e: ")
         keyn = Input("Schlüssel n: ")
      Else Goto mouse
      EndIf
      FlushKeys()
      Text GraphicsWidth() / 2,250,"Enter drücken zum Starten - dieser Vorgang kann einige Minuten dauern ^_^",1
      Repeat   
         Delay 100
         If KeyHit(28) Then Exit
         If KeyHit(1)  Then Goto start
      Forever
      Rect 10,300,GraphicsWidth() - 20,50,0
      rsafile(quelle$,keye,keyn)
   ElseIf MouseX() > (GraphicsWidth() / 2 + 5) And MouseX() < (GraphicsWidth() / 2 + 205) And MouseY() > 50 And MouseY() < 100
      Color 165,165,150
      Rect GraphicsWidth() / 2 - 205,50,200,50,1
      Rect GraphicsWidth() / 2 + 5,50,200,50,1
      Color 100,100,065
      Rect GraphicsWidth() / 2 - 205,50,200,50,0
      Rect GraphicsWidth() / 2 + 5,50,200,50,0
      Text ((GraphicsWidth() / 2 - 205) + GraphicsWidth() / 2 - 5) / 2,(50 + 100) / 2,"Datei Verschlüsseln",1,1
      Text ((GraphicsWidth() / 2 + 205) + GraphicsWidth() / 2 + 5) / 2,(50 + 100) / 2,"Datei Entschlüsseln",1,1
      Color 0,0,0
      Text GraphicsWidth() / 2,110,"Datei Entschlüsseln",1
      Locate 0,130
      Quelle$ = Input$("Quelldatei: ")
      .schluessefalscheingegeben
      keye = Input("Schlüssel e: ")
      keyp = Input("Schlüssel p: ")
      keyq = Input("Schlüssel q: ")
      If (Not ifprim(keye)) Or (Not ifprim(keyp)) Or (Not ifprim(keyq))
         Print "Mindestens einer der Schlüssel wurde falsch eingegeben."
         Print "Bitte versuchen Sie es erneut!"
         Goto schluessefalscheingegeben
      EndIf
      FlushKeys()
      Text GraphicsWidth() / 2,250,"Enter drücken zum Starten - dieser Vorgang kann einige Minuten dauern ^_^",1
      Repeat   
         Delay 100
         If KeyHit(28) Then Exit
         If KeyHit(1)  Then Goto start
      Forever
      Rect 10,300,GraphicsWidth() - 20,50,0
      unrsafile(quelle$,keye,keyp,keyq)
   EndIf
Forever

Function rsafile(datei$,e,n)
   lesen     = ReadFile(datei$)
   schreiben = WriteFile(datei$ + ".rsa")
   Repeat
      zaehler# = zaehler + 1
      byte = ReadByte(lesen)
      code = expmod(byte,e,n)
      WriteByte(schreiben,code)
      anteil# = zaehler / FileSize(datei)
      Rect 10,300,(GraphicsWidth() - 20) * anteil,50
   Until Eof (lesen)
   CloseFile lesen
   CloseFile schreiben
   Print
End Function

Function unrsafile(datei$,e#,p#,q#)
   kürzel$   = Right$(Left$(datei$,Len(datei$) - 4),4)
   ziel$     = Left$(datei,Len(datei) - 8) + "_unrsa" + kürzel
   lesen     = ReadFile(datei$)
   schreiben = WriteFile(ziel)
   Print "generiere Dechiffrierschlüssel..."
   Repeat
      zaehler# = zaehler + 1
      d# = (1 + zaehler * (p - 1) * (q - 1)) / e
      d2 = d#
   Until d2 = d#
   zaehler = 0
   Repeat
      zaehler = zaehler + 1
      byte = ReadByte(lesen)      
      code = expmod(byte,d,p * q)
      WriteByte(schreiben,code)
      anteil# = anteil# = zaehler / FileSize(datei)
      Rect 10,300,(GraphicsWidth() - 20) * anteil,50
   Until Eof (lesen)
   CloseFile lesen
   CloseFile schreiben   
End Function

Function createkeys(minsize,maxsize)
   SeedRnd(MilliSecs())
   Repeat
      p = Rnd(minsize,maxsie)
   Until ifprim(p,maxsize)
   Repeat
      q = Rnd(minsize,maxsie)
   Until ifprim(q,maxsize)
   Repeat
      e = Rnd(minsize,maxsie)
   Until ifprim(e,maxsize)
End Function

Function expmod(zahl,ex,Modulo)
   erg = 1
   If Not gerade(ex)
      erg = zahl
      ex = ex - 1
   EndIf
   potenzen = ex / 2
   For i = 1 To potenzen
      erg = (erg * ((zahl^2) Mod modulo)) Mod modulo
   Next
   Return erg
End Function

Function gerade(zahl)
   Repeat
      zahl = zahl - 2
   Until zahl <= 1
   If zahl = 1 Then Return False Else Return True
End Function

Function ifPrim(zahl%,maximum = 100)
   prim = True
   zahl2# = zahl%
   zaehler% = 1
   Repeat
      zaehler% = zaehler% + 1
      flt# = Float#(zahl2# / zaehler%)
      Abso = zahl% / zaehler
      If flt# = abso
         If Not zaehler = zahl
            prim = False
            Exit
         Else
            Exit
         EndIf
      EndIf
   Until zaehler = maximum
   Return prim
End Function


vllt mag ja jemand was schreiben, was ich mir dann in ein paar wochen ansehen kann...

schöne ferien!

PS: Manche sachen sind wohl nicht so schön gelöst, zb ifPrim()^^
>> Musikerstellung, Grafik und Design: http://www.pixelshooter.net.tc
 

Dreamora

BeitragMi, Jun 20, 2007 23:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Abbruchkriterium ist leider verheerend falsch gewählt fürchte ich, das macht den Test höchst ineffizient
Um zu testen ob eine Zahl X prim ist muss man nur bis sqrt(X) prüfen, nicht bis X.

Code: [AUSKLAPPEN]

Function ifPrim(zahl,maximum = 100)
   prim = True
   zaehler = 1

   if maximum > zahl or maximum > sqrt(zahl)
      ; Das eigentlich korrekte Abbruchkriterium wenn man wirklich auf
      ; prim testen will.
      sqrtMax# = sqrt(zahl)
   else
      ; Diese zuweisung ist primär wenn man nur bis zu einem gewissen Wert
      ; testen wollte anstatt darauf obs wirklich primär ist.
      sqrtMax# = maximum   
   endif

   Repeat
      zaehler = zaehler + 1
      flt# = float(zahl) / zaehler
      If flt = int(flt)
         prim = False
         Exit
      EndIf
   Until zaehler > sqrtMax
   Return prim
End Function



wie man sieht reduziert sich das mit der korrekten Abbruchbedingung um einiges.
Was noch fehlt ist eine optimierung die schon verwendete Teiler auslöscht als weitere zähler. Heisst das man mindestens nur 1x auf gerade Teiler testet.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

pixelshooter

BeitragSa, Jun 30, 2007 19:41
Antworten mit Zitat
Benutzer-Profile anzeigen
jupp, das, was du da geschrieben hast, stimmt vollkommen ;D
die funktion für gerade zahlen lässt sich auch kürzen auf:
Code: [AUSKLAPPEN]

function gerade(zahl)
     return (zahl Mod 2) = 0 ; oder langsamer: return Not zahl Mod 2
end function
>> Musikerstellung, Grafik und Design: http://www.pixelshooter.net.tc

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group