AES Verschlüsselung für Strings

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Christian+
Beiträge: 213
Registriert: 13.07.2008 10:05
Computerausstattung: Windows 8.1 Pro
AMD Phenom II X4 955 @ 3.2 GHz
4GB RAM
NVIDIA GeForce GTX 660

AES Verschlüsselung für Strings

Beitrag von Christian+ »

Da ich heute eine einfache Möglichkeit gesucht habe Strings mit AES zu verschlüsseln und entschlüsseln habe ich mir mal schnell zwei Funktionen dazu geschrieben die es so einfach wie möglich machen.

Code: Alles auswählen

EnableExplicit

Procedure.s StringEncoder( String$, Key$ )
  Protected Size.l, *Input, *IV, *Ciphered, *Base64, Ciphered$
  If String$
    Size = StringByteLength( String$ ) + SizeOf(Character)
    If Size < 16 : Size = 16 : EndIf
    *Input = AllocateMemory( Size )
    If *Input
      PokeS( *Input, String$ )
      Key$ = MD5Fingerprint( @Key$, StringByteLength( Key$ ) )
      *IV = AllocateMemory( 16 )
      CryptRandomData( *IV, 16 )
      *Ciphered = AllocateMemory( Size + 16 )
      If *Ciphered
        CopyMemory( *IV, *Ciphered, 16 )
        AESEncoder( *Input, *Ciphered + 16, Size, @Key$, 256, *IV, #PB_Cipher_CBC )
        *Base64 = AllocateMemory( Size * 1.35 + 64 )
        If *Base64
          Size = Base64Encoder( *Ciphered, Size + 16, *Base64, Size * 1.35 + 64 )
          Ciphered$ = PeekS( *Base64, Size, #PB_Ascii)
          FreeMemory( *Base64 )
        EndIf
        FreeMemory( *Ciphered )
      EndIf
      FreeMemory( *IV )
      FreeMemory( *Input )
    EndIf
  EndIf
  ProcedureReturn Ciphered$
EndProcedure

Procedure.s StringDecoder( String$, Key$ )
  Protected Size.l, *IV.l, *Deciphered, *Base64, Deciphered$, *Buffer
  If String$
    Size = StringByteLength(String$, #PB_Ascii) + SizeOf(Character)
    *Base64 = AllocateMemory( Size + 64 )
    If *Base64
      *Buffer = AllocateMemory(Size)
      PokeS(*Buffer, String$, StringByteLength(String$, #PB_Ascii), #PB_Ascii)
      Size = Base64Decoder( *Buffer, StringByteLength(String$, #PB_Ascii), *Base64, Size + 64 )
      Key$ = MD5Fingerprint( @Key$, StringByteLength( Key$ ) )
      *IV = AllocateMemory( 16 )
      CopyMemory( *Base64, *IV, 16 )
      *Deciphered = AllocateMemory( Size - 16 )
      If *Deciphered
        AESDecoder( *Base64 + 16, *Deciphered, Size - 16, @Key$, 256, *IV, #PB_Cipher_CBC )
        Deciphered$ = PeekS( *Deciphered )
        FreeMemory( *Deciphered )
      EndIf
      FreeMemory( *IV )
      FreeMemory( *Base64 )
      FreeMemory( *Buffer )
    EndIf
  EndIf
  ProcedureReturn Deciphered$
EndProcedure

OpenCryptRandom()

Define String$ = "Hallo Welt + Hallo Welt + Hallo Welt"
Debug String$
String$ = StringEncoder( String$, "Test" )
Debug String$
String$ = StringDecoder( String$, "Test" )
Debug String$ 
Zuletzt geändert von Christian+ am 09.09.2010 08:03, insgesamt 5-mal geändert.
Windows 8.1 Pro 64Bit | AMD Phenom II X4 955 @ 3.2 GHz | 4GB RAM | NVIDIA GeForce GTX 660
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: AES Verschlüsselung für Strings

Beitrag von STARGÅTE »

Danke für den Code, nimmt einem das Denken ab, wenn man einfach nur verschlüssel will.

Hinweis: Dein Code funktioniert nur im Ascii-Modus, nicht unter Unicode!
Problem könnte String$ = LSet( String$, Size ) machen, dort wird die Länge in Characters erwartet, nicht Bytes!
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Christian+
Beiträge: 213
Registriert: 13.07.2008 10:05
Computerausstattung: Windows 8.1 Pro
AMD Phenom II X4 955 @ 3.2 GHz
4GB RAM
NVIDIA GeForce GTX 660

Re: AES Verschlüsselung für Strings

Beitrag von Christian+ »

Oh stimmt das ist nicht gut String$ = LSet( String$, Size ) da habe ich wohl nicht aufgepasst lässt sich aber mit String$ = String$ + Space( 16 ) ersetzen geht ja nur darum dass der String lang genug ist.
Windows 8.1 Pro 64Bit | AMD Phenom II X4 955 @ 3.2 GHz | 4GB RAM | NVIDIA GeForce GTX 660
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: AES Verschlüsselung für Strings

Beitrag von STARGÅTE »

Verstehe, daher auch diese "Umwege" mit dem mitspeichern der Länge, damit man bei kleinen Strings auch wieder das richtig herausbekommt, ohne den zusatz der Spaces ...
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Christian+
Beiträge: 213
Registriert: 13.07.2008 10:05
Computerausstattung: Windows 8.1 Pro
AMD Phenom II X4 955 @ 3.2 GHz
4GB RAM
NVIDIA GeForce GTX 660

Re: AES Verschlüsselung für Strings

Beitrag von Christian+ »

So nachdem der alte Quellcode ja bei weitem nicht Unicode tauglich war da oft Bytes und Zeichen gleichgesetzt waren habe ich das jetzt nochmal überarbeitet sollte auch wenn ich es nicht getestet habe jetzt Unicode unterstützen und dazuhin kleinere Verschlüsselte Strings erzeugen da nun auf das mitspeichern der Länge verzichtet wird hatte das irgendwie umständlich gelöst mache guten Ideen kommen halt erst beim zweiten Versuch.
Windows 8.1 Pro 64Bit | AMD Phenom II X4 955 @ 3.2 GHz | 4GB RAM | NVIDIA GeForce GTX 660
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: AES Verschlüsselung für Strings

Beitrag von STARGÅTE »

Ja gut, immerhin schlüsselt er nun richtig hin und zurück,
jedoch ist das verschlüsselte nicht mehr "verwendbar"
Hallo Welt + Hallo Welt + Hallo Welt
????????????????????????????????????????????????????????????
Hallo Welt + Hallo Welt + Hallo Welt
Problem ist, dass Base64Encoder einen String (Also das zeug im Ausgabespeicher) im Ascii-Modus zurück gibt und Unicode dann aus zwei Asciis ein Unicodezeichenbaut was "unkenntlich" ist, diesen müsstest du erst noch ins Unicode konvertieren:

zB beim Encoder so:

Code: Alles auswählen

        If *Base64
          Size = Base64Encoder( *Ciphered, Size + 16, *Base64, Size * 1.35 + 64 )
          Ciphered$ = PeekS( *Base64, Size, #PB_Ascii) ; << Ascii !
          FreeMemory( *Base64 )
        EndIf
(Damit wird das Codierte natürlich doppenlt so groß)

und beim Decoder müsstest du dann den Unicode-String erst als Ascii in ein Buffer schreiben und dann von Base64Decoder bearbeiten lassen:

Code: Alles auswählen

      *Buffer = AllocateMemory(Size)
      PokeS(*Buffer, String$, StringByteLength(String$, #PB_Ascii), #PB_Ascii)
      Size = Base64Decoder( *Buffer, Size/2, *Base64, Size * 1.3 + 64 )
Im übrigen muss der Speicher nur bei Base64Encoder 35% größer sein, bei Base64Decoder kann er kleiner sein!

Code: Alles auswählen

EnableExplicit

Procedure.s StringEncoder( String$, Key$ )
  Protected Size.l, *Input, *IV, *Ciphered, *Base64, Ciphered$
  If String$
    Size = StringByteLength( String$ ) + SizeOf(Character)
    If Size < 16 : Size = 16 : EndIf
    *Input = AllocateMemory( Size )
    If *Input
      PokeS( *Input, String$ )
      Key$ = MD5Fingerprint( @Key$, StringByteLength( Key$ ) )
      *IV = AllocateMemory( 16 )
      CryptRandomData( *IV, 16 )
      *Ciphered = AllocateMemory( Size + 16 )
      If *Ciphered
        CopyMemory( *IV, *Ciphered, 16 )
        AESEncoder( *Input, *Ciphered + 16, Size, @Key$, 256, *IV, #PB_Cipher_CBC )
        *Base64 = AllocateMemory( Size * 1.35 + 64 )
        If *Base64
          Size = Base64Encoder( *Ciphered, Size + 16, *Base64, Size * 1.35 + 64 )
          Ciphered$ = PeekS( *Base64, Size, #PB_Ascii)
          FreeMemory( *Base64 )
        EndIf
        FreeMemory( *Ciphered )
      EndIf
      FreeMemory( *IV )
      FreeMemory( *Input )
    EndIf
  EndIf
  ProcedureReturn Ciphered$
EndProcedure

Procedure.s StringDecoder( String$, Key$ )
  Protected Size.l, *IV.l, *Deciphered, *Base64, Deciphered$, *Buffer
  If String$
    Size = StringByteLength( String$ )
    *Base64 = AllocateMemory( Size * 1.3 + 64 )
    If *Base64
      *Buffer = AllocateMemory(Size)
      PokeS(*Buffer, String$, StringByteLength(String$, #PB_Ascii), #PB_Ascii)
      Size = Base64Decoder( *Buffer, StringByteLength(String$, #PB_Ascii), *Base64, Size + 64 )
      Key$ = MD5Fingerprint( @Key$, StringByteLength( Key$ ) )
      *IV = AllocateMemory( 16 )
      CopyMemory( *Base64, *IV, 16 )
      *Deciphered = AllocateMemory( Size - 16 )
      If *Deciphered
        AESDecoder( *Base64 + 16, *Deciphered, Size - 16, @Key$, 256, *IV, #PB_Cipher_CBC )
        Deciphered$ = PeekS( *Deciphered )
        FreeMemory( *Deciphered )
      EndIf
      FreeMemory( *IV )
      FreeMemory( *Base64 )
      FreeMemory( *Buffer )
    EndIf
  EndIf
  ProcedureReturn Deciphered$
EndProcedure

OpenCryptRandom()

Define String$ = "Hallo Welt + Hallo Welt + Hallo Welt"
Debug String$
String$ = StringEncoder( String$, "Test" )
Debug String$
String$ = StringDecoder( String$, "Test" )
Debug String$ 
Der Funktioniert nun im Ascii
Hallo Welt + Hallo Welt + Hallo Welt
jatCtCBty4UzQvEVyVD7Q9l/R7rCj64LORFFrsePpcU7DgovPzthLLMembZXXVQD/tZbhUU=
Hallo Welt + Hallo Welt + Hallo Welt
und Unicode!
Hallo Welt + Hallo Welt + Hallo Welt
l/A7OFqR9LnWJPRMXdLTRAph1PzX8CDNBX+RCn8JTqZJoqFRb7wtZOdvIT67lepqmDIadx/nvyVC3iirQaicH1kZKMU4isybhfdr43JtLFmjvJyeyCkpuhJd
Hallo Welt + Hallo Welt + Hallo Welt
Im Unicode ist das Verschlüsselte deshalb länger, weil er hat immer 2Byte (ein zeichen) verschlüsselt und Base daraus dann das alphanumerische macht.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Christian+
Beiträge: 213
Registriert: 13.07.2008 10:05
Computerausstattung: Windows 8.1 Pro
AMD Phenom II X4 955 @ 3.2 GHz
4GB RAM
NVIDIA GeForce GTX 660

Re: AES Verschlüsselung für Strings

Beitrag von Christian+ »

@STARGÅTE
Danke für die Anpassungen. Beim Decoder sollte nun aber Size = StringByteLength( String$ ) zu Size = StringByteLength(String$, #PB_Ascii) + SizeOf(Character) geändert werden da sonst im Unicode Modus zu viel Speicher und im Ascii zu wenig Speicher Reserviert wird.
Wegen dem größeren Speicher bei Base64Decoder in der Hilfe steht dass er zwar kleiner sein kann es aber empfehlenswert ist einen um etwa 30% größeren zu verwenden und da ich den Base64Decoder bisher nicht allzu oft gebraucht und deswegen nicht sagen kann ob man darauf verzichten kann dachte ich mach ich mal Sicherheitshalber die 30% dazu schaden tut es ja nicht. Wenn die aber doch unötig sind dann lass ich das weg *Base64 = AllocateMemory( Size * 1.3 + 64 ) muss dann halt auch noch zu AllocateMemory( Size + 64 ) geändert werden.
Habe das gleich mal alles noch angepasst und meinen Code Aktuallisiert.
Windows 8.1 Pro 64Bit | AMD Phenom II X4 955 @ 3.2 GHz | 4GB RAM | NVIDIA GeForce GTX 660
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: AES Verschlüsselung für Strings

Beitrag von STARGÅTE »

Wegen dem Base64 noch mal:

Base64Decoder:
"Der 'AusgabePuffer' kann bis zu 33% kleiner als der Eingabepuffer sein, mit einer minimalen Größe von 64 Bytes."

Base64Encoder:
"Der 'AusgabePuffer' sollte mindestens 33% größer als der 'EingabePuffer' sein, mit einer minimalen Größe von 64 Bytes."

Auf jeden Fall ist es ichtig beim Codieren mehr Speicher zu geben, was beim Decodieren pasiert ist "eigentlich" egal.
Gleichgroß + 64 Byte ist voll in Ordnung.
Wieso jedoch mindestens diese 64Byte auf beiden Seiten nötig sind, ist mir unklar.
Zumal Base64 effektiv aus 3 Bytes genau 4 Bytes macht.

Aber nun gut. Dein Code läuft nun :allright:
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Antworten