Crypting/Datei schreiben

Anfängerfragen zum Programmieren mit PureBasic.
Maxwell
Beiträge: 1
Registriert: 09.07.2010 08:27

Crypting/Datei schreiben

Beitrag von Maxwell »

Hallo zusammen,

erstmal zur Warnung: ich bin relativ neu in Purebasic und versuche ein erstes Programm zu schreiben, welches eine per Parameter übergebene Datei ver- bzw entschlüssseln soll.
Prinzipiell funktioniert das soweit. Aber: wenn man eine Datei verschlüsselt und wieder entschlüsselt, so unterscheidet sich das Ergebnis leicht vom Ursprung - und zwar ist die entschlüsselte Datei länger, als die ursprunglich verschlüsselte.

Der Code basiert auf diesem Beispiel aus dem Forum. Ich kann mir den Fehler nicht erklären und bitte um Hilfe:

Code: Alles auswählen

Procedure.s openEncodingFile(file.s)
  Protected result.s, ff, *mem1
  ff = ReadFile(#PB_Any, file)
  If ff
    length = Lof(ff)
    *mem1 = AllocateMemory(length)
    If *mem1
      ReadData(ff, *mem1, length)
      result = PeekS(*mem1)
      FreeMemory(*mem1)
    EndIf
    CloseFile(ff)
  Else
    PrintN("Fehler lesen Datei")
  EndIf
  ProcedureReturn result
EndProcedure

Procedure.s decode(file.s)
  Protected result.s, ff, *mem1, *mem2, length
  ff = ReadFile(#PB_Any, file)
  
  If ff
    length = Lof(ff)
    *mem1 = AllocateMemory(length)
    *mem2 = AllocateMemory(length)
    If *mem1 And *mem2
      ReadData(ff, *mem1, length)
      AESDecoder(*mem1, *mem2, length, ?Key, 128, ?InitializationVector)
      result = PeekS(*mem2)
      FreeMemory(*mem1) : FreeMemory(*mem2)
    EndIf
    CloseFile(ff)
  Else
    PrintN("Fehler lesen Datei")
  EndIf
  ProcedureReturn result
EndProcedure

Procedure memToFile(*mem, file.s)
  Protected ff
  ff = CreateFile(#PB_Any, file)
  If ff
    WriteData(ff, *mem, MemorySize(*mem)-1)
    CloseFile(ff)
  EndIf
EndProcedure

If OpenConsole()
  paramCount = CountProgramParameters()
  param$ = ProgramParameter()
  
  e = (paramCount = 2 And param$ = "e")
  d = (paramCount = 2 And param$ = "d")
  If Not (e Or d )
    PrintN("Incorrect syntax!")
  Else
    
    If (param$= "e" Or param$ = "ed")
      File$ = ProgramParameter()
      String$ = openEncodingFile(File$)
      PrintN("encoding: " + String$)
      
      *CipheredString = AllocateMemory(StringByteLength(String$) + SizeOf(character))
      If AESEncoder(@String$, *CipheredString, StringByteLength(String$) + SizeOf(character), ?Key, 128, ?InitializationVector)
        
        memToFile(*CipheredString, File$+".def")
        FreeMemory(*CipheredString)
        Debug "ok"
        PrintN( "ok")
      Else
        Debug "nok"
        PrintN( "nok")
      EndIf
    EndIf
    
    If (param$ = "d" Or param$ = "ed")
      PrintN("Decoding")
      Debug "Decoding"
      File$ = ProgramParameter()
      Text$ = decode(File$)
      memToFile(@Text$, File$+".dec")
      Print("Done. Result: '")
      Print(Text$)
      PrintN("'")
      Debug "Done. Result: '" + Text$ + "'"
    EndIf
    
  EndIf
  
EndIf ; Console Close

DataSection
  Key:
  Data.b $06, $a9, $21, $40, $36, $b8, $a1, $5b, $51, $2e, $03, $d5, $34, $12, $00, $06
  
  InitializationVector:
  Data.b $3d, $af, $ba, $42, $9d, $9e, $b4, $30, $b4, $22, $da, $80, $2c, $9f, $ac, $41
EndDataSection
Besten Dank schon mal im Voraus.

Max

EDIT: Die Zeile

Code: Alles auswählen

WriteData(ff, *mem, MemorySize(*mem)-1)
war eigentlich

Code: Alles auswählen

WriteData(ff, *mem, MemorySize(*mem))
Hatte das nur ausprobiert, um zu gucken, ob das der Fehler war.... war's aber nicht ;)
Dark
Beiträge: 93
Registriert: 24.08.2007 20:36
Kontaktdaten:

Re: Crypting/Datei schreiben

Beitrag von Dark »

Hallo,

ich kenne zwar die PureBasic Implementierung von AES nicht, jedoch weiß ich das jede Verschlüsselung blockweise arbeitet. Dies bedeuted der Algorithmus arbeitet z.B. immer mit Blöcken der größe 8 Byte oder ähnlichem. Wenn man nur 5 Byte verschlüsseln will, muss man die Daten auf 8 Byte auffüllen, mit nullern oder etwas anderem. Das Problem ist nur, bei der entschlüsselung, weiß man nacher nicht mehr wie groß die original daten waren. Dann hat man zwar nacher wieder seine nuller zurück, weiß aber nicht ob die wirklich in den Daten vorkammen oder nur aufgefüllt wurden.Dies könnte man sich sparen, wenn man nur Daten verschlüsselt, die der Blocksize entsprechen.
In deinem Fall wäre es sinvoller in einem byte der Datei zu speichern um wie viele Bytes aufgefüllt wurde.Ich glaube PureBasic verwendet 16 Byte Blöcke, sicher bin ich mir aber nicht. Dies kannst du einfach testen in dem Du eine Datei mit einem byte verschlüsselt und entschlüsselst und dir Größe der entschlüsselten Datei anschaust. Hiermit würdest du die anzahl der aufgefüllten Bytes für 16 Byte Blöcke bekommen:

Code: Alles auswählen

Procedure BlockFillCount(Length.i)
  If Length % 16 = 0 
    ProcedureReturn 0 
  Else 
    ProcedureReturn  16 - (Length % 16)
  EndIf
EndProcedure
Diesen speicherst du dann als erstes Byte der Datei oder so, und beim entschlüsseln schneidest die Anzahl der Bytes am Ende wieder ab.

mfg,
Dark
Antworten