2012-12-10 7 views
12

[Update] Ich biete einen Bonus dafür. Offen gesagt ist es mir egal, welche Verschlüsselungsmethode verwendet wird. Vorzugsweise etwas einfaches wie XTEA, RC4, BlowFish ... aber Sie haben gewählt.Ich suche eine Dateiverschlüsselungsimplementierung, die ganze Datei en/de-crypt in Delphi und C verarbeiten kann

Ich möchte minimalen Aufwand von mir, vorzugsweise nur die Dateien in meine Projekte und bauen.

Idealerweise sollten Sie den Code bereits verwendet haben, um eine Datei in Delphi und C zu de- kryptieren (Ich möchte Dateien zwischen einem Atmel UC3-Mikroprozessor (Codierung in C) und einem Windows-PC (Codierung in Delphi) tauschen) en-und-de-crypt in beide Richtungen).

Ich habe eine starke Präferenz für eine einzelne .PAS-Einheit und eine einzelne .C/.H-Datei. Ich möchte nicht eine DLL oder eine Bibliothek verwenden, die Dutzende von Verschlüsselungsalgorithmen unterstützt, nur einen (und ich möchte sicherlich nichts mit einem Installationsprogramm).

Ich hoffe, dass ich nicht zu wählerisch hier klingen, aber ich google & versucht Code für über eine Woche und kann immer noch nicht zwei Implementierungen finden, die übereinstimmen. Ich vermute, dass nur jemand, der das schon getan hat, mir helfen kann ...

Vielen Dank im Voraus.


Im Nachgang zu my previous post, ich bin noch auf der Suche für einige sehr einfachen Code mit, warum ich kann - mit minimalem Aufwand - de-de, eine Datei Krypta und es zwischen Delphi auf einem PC und C an einer Börse Atmel UC3 u-Prozessor.

Es klingt einfach in der Theorie, aber in der Praxis ist es ein Albtraum. Es gibt viele mögliche Kandidaten und ich habe Tage damit verbracht, sie zu googeln und auszuprobieren - ohne Erfolg.

Einige sind humonous Bibliotheken, die viele Verschlüsselungsalgorithmen unterstützen, und ich möchte etwas Leichtgewicht (besonders auf dem C/u-Prozessorende).

Einige sehen gut aus, aber ein Satz Quelle bietet nur Blockmanipulation, die anderen Strings (ich würde ganze Datei en/de-crypt bevorzugen).

Die meisten scheinen sehr schlecht dokumentiert zu sein, mit bedeutungslosen Parameternamen und keinem Beispielcode, um die Funktionen aufzurufen.

Über das letzte Wochenende (plus ein paar Tage mehr) habe ich mich durch eine ganze Reihe von XTEA-, XXTEA- und BlowFish-Implementierungen durchgebrannt, aber während ich verschlüsseln kann, kann ich den Prozess nicht umkehren.

Jetzt schaue ich auf AES-256. Kennt jemand eine Implementierung in C, die eine einzelne AES.C-Datei ist? (plus AES.H, natürlich)

Ehrlich gesagt, werde ich alles nehmen, was ganze Datei en/de-crypt zwischen Delphi und C tun wird, aber wenn niemand dies selbst getan hat, erwarte ich nur "any" zu hören Implementierung, die den Standard erfüllt, sollte tun "- was ist ein nettes Theory, aber gerade nicht für mich :-(

Any einfache AES-256 in C da draußen? Ich habe einige vernünftige Suche Delphi-Code, wird aber nicht sicher sein, bis ich versuche, sie zusammen.

Vielen Dank im Voraus ...

Antwort

1

Hier ist RC4-Code. Es ist sehr leicht.

Das C wird seit fünf Jahren in einem Produktionssystem verwendet.

Ich habe leicht getesteten Delphi-Code hinzugefügt. Das Pascal ist ein zeilenweiser Port mit unsigned char zu Byte. Ich habe nur das Pascal in Free Pascal mit Delphi-Option aktiviert, nicht Delphi selbst. Sowohl C als auch Pascal haben einfache Dateiprozessoren.

Durch die Verschlüsselung des Chiffretextes erhält man den ursprünglichen Klartext zurück.

Keine Fehler bisher gemeldet. Hoffe das löst dein Problem.

rc4.h

#ifndef RC4_H 
#define RC4_H 

/* 
* rc4.h -- Declarations for a simple rc4 encryption/decryption implementation. 
* The code was inspired by libtomcrypt. See www.libtomcrypt.org. 
*/ 
typedef struct TRC4State_s { 
    int x, y; 
    unsigned char buf[256]; 
} TRC4State; 

/* rc4.c */ 
void init_rc4(TRC4State *state); 
void setup_rc4(TRC4State *state, char *key, int keylen); 
unsigned endecrypt_rc4(unsigned char *buf, unsigned len, TRC4State *state); 

#endif 

rc4.c

void init_rc4(TRC4State *state) 
{ 
    int x; 
    state->x = state->y = 0; 
    for (x = 0; x < 256; x++) 
    state->buf[x] = x; 
} 

void setup_rc4(TRC4State *state, char *key, int keylen) 
{ 
    unsigned tmp; 
    int x, y; 

    // use only first 256 characters of key 
    if (keylen > 256) 
    keylen = 256; 

    for (x = y = 0; x < 256; x++) { 
    y = (y + state->buf[x] + key[x % keylen]) & 255; 
    tmp = state->buf[x]; 
    state->buf[x] = state->buf[y]; 
    state->buf[y] = tmp; 
    } 
    state->x = 255; 
    state->y = y; 
} 

unsigned endecrypt_rc4(unsigned char *buf, unsigned len, TRC4State *state) 
{ 
    int x, y; 
    unsigned char *s, tmp; 
    unsigned n; 

    x = state->x; 
    y = state->y; 
    s = state->buf; 
    n = len; 
    while (n--) { 
    x = (x + 1) & 255; 
    y = (y + s[x]) & 255; 
    tmp = s[x]; s[x] = s[y]; s[y] = tmp; 
    tmp = (s[x] + s[y]) & 255; 
    *buf++ ^= s[tmp]; 
    } 
    state->x = x; 
    state->y = y; 
    return len; 
} 

int endecrypt_file(FILE *f_in, FILE *f_out, char *key) 
{ 
    TRC4State state[1]; 
    unsigned char buf[4096]; 
    size_t n_read, n_written; 

    init_rc4(state); 
    setup_rc4(state, key, strlen(key)); 
    do { 
    n_read = fread(buf, 1, sizeof buf, f_in); 
    endecrypt_rc4(buf, n_read, state); 
    n_written = fwrite(buf, 1, n_read, f_out); 
    } while (n_read == sizeof buf && n_written == n_read); 
    return (n_written == n_read) ? 0 : 1; 
} 

int endecrypt_file_at(char *f_in_name, char *f_out_name, char *key) 
{ 
    int rtn; 

    FILE *f_in = fopen(f_in_name, "rb"); 
    if (!f_in) { 
    return 1; 
    } 
    FILE *f_out = fopen(f_out_name, "wb"); 
    if (!f_out) { 
    close(f_in); 
    return 2; 
    } 
    rtn = endecrypt_file(f_in, f_out, key); 
    fclose(f_in); 
    fclose(f_out); 
    return rtn; 
} 

#ifdef TEST 

// Simple test. 
int main(void) 
{ 
    char *key = "This is the key!"; 

    endecrypt_file_at("rc4.pas", "rc4-scrambled.c", key); 
    endecrypt_file_at("rc4-scrambled.c", "rc4-unscrambled.c", key); 
    return 0; 
} 
#endif 

Hier wird Pascal leicht getestet. Ich kann den Quellcode in C verschlüsseln und ihn mit der Pascal-Implementierung entschlüsseln.

type 
    RC4State = record 
    x, y : Integer; 
    buf : array[0..255] of Byte; 
    end; 

    KeyString = String[255]; 

procedure initRC4(var state : RC4State); 
var 
    x : Integer; 
begin 
    state.x := 0; 
    state.y := 0; 
    for x := 0 to 255 do 
    state.buf[x] := Byte(x); 
end; 

procedure setupRC4(var state : RC4State; var key : KeyString); 
var 
    tmp : Byte; 
    x, y : Integer; 
begin 
    y := 0; 
    for x := 0 to 255 do begin 
    y := (y + state.buf[x] + Integer(key[1 + x mod Length(key)])) and 255; 
    tmp := state.buf[x]; 
    state.buf[x] := state.buf[y]; 
    state.buf[y] := tmp; 
    end; 
    state.x := 255; 
    state.y := y; 
end; 

procedure endecryptRC4(var buf : array of Byte; len : Integer; var state : RC4State); 
var 
    x, y, i : Integer; 
    tmp : Byte; 
begin 
    x := state.x; 
    y := state.y; 
    for i := 0 to len - 1 do begin 
    x := (x + 1) and 255; 
    y := (y + state.buf[x]) and 255; 
    tmp := state.buf[x]; 
    state.buf[x] := state.buf[y]; 
    state.buf[y] := tmp; 
    tmp := (state.buf[x] + state.buf[y]) and 255; 
    buf[i] := buf[i] xor state.buf[tmp] 
    end; 
    state.x := x; 
    state.y := y; 
end; 

procedure endecryptFile(var fIn, fOut : File; key : KeyString); 
var 
    nRead, nWritten : Longword; 
    buf : array[0..4095] of Byte; 
    state : RC4State; 
begin 
    initRC4(state); 
    setupRC4(state, key); 
    repeat 
    BlockRead(fIN, buf, sizeof(buf), nRead); 
    endecryptRC4(buf, nRead, state); 
    BlockWrite(fOut, buf, nRead, nWritten); 
    until (nRead <> sizeof(buf)) or (nRead <> nWritten); 
end; 

procedure endecryptFileAt(fInName, fOutName, key : String); 
var 
    fIn, fOut : File; 
begin 
    Assign(fIn, fInName); 
    Assign(fOut, fOutName); 
    Reset(fIn, 1); 
    Rewrite(fOut, 1); 
    endecryptFile(fIn, fOut, key); 
    Close(fIn); 
    Close(fOut); 
end; 

{$IFDEF TEST} 
// Very small test. 
const 
    key = 'This is the key!'; 
begin 
    endecryptFileAt('rc4.pas', 'rc4-scrambled.pas', key); 
    endecryptFileAt('rc4-scrambled.pas', 'rc4-unscrambled.pas', key); 
end. 
{$ENDIF} 
+1

Okay, ich habe die Eval-Kopie von Delphi und werde versuchen, dies in den nächsten ein oder zwei Tagen zu portieren. – Gene

+0

Ich hoffe, dass Sie das tun werden. Ich habe 22 Stunden, um das Kopfgeld oder das System zu vergeben - also werde ich es dir jetzt geben. Der Vorschlag über die Verwendung einer DLL klingt auch gut. – Mawg

+0

Ich werde mehr Punkte hinzufügen, wenn Sie Delphi & C Code veröffentlichen, der eine ganze Datei in beide Richtungen de/kryptieren wird. – Mawg

2

ich würde vorschlagen, die .NET Micro Framework auf als mit Sekundärmikrocontroller (z.B. Atmel SAM7X) als Krypto-Koprozessor.Sie können dies auf eine testen, die Sie für ca. $ 35/£ 30 abholen können. Das Framework enthält eine AES-Implementierung innerhalb des Namespace System.Security.Cryptography neben einer Reihe anderer kryptografischer Funktionen, die für Sie nützlich sein könnten. Der Vorteil hierbei ist, dass Sie eine vollständig getestete und funktionierende Implementierung und erhöhte Sicherheit über typsicheren Code erhalten.

Sie können SPI oder I2C verwenden, um zwischen den zwei Mikrocontrollern zu kommunizieren, oder Bit-Bang Ihr eigenes Datenübertragungsprotokoll über mehrere E/A-Leitungen parallel, wenn ein höherer Durchsatz benötigt wird.

Ich tat genau dies mit einem Arduino und einem Netduino (mit dem Netduino Hash Blöcke von Daten für eine Hardware BitTorrent-Gerät) und implementiert ein rudimentäres asynchrones System mit verschiedenen Befehlen zwischen den Geräten über SPI und einen Interrupt-Mechanismus gesendet.

  • Arduino ist SPI-Master, Netduino ist SPI-Slave.
  • Ein GPIO-Pin am Netduino wird als Ausgang festgelegt und mit einem anderen interrupt-enabled GPIO pin on the Arduino verknüpft, der als Eingang festgelegt ist. Dies ist der Interrupt-Pin.
  • Arduino sendet 0xF1 als eine "Hallo" Initialisierungsnachricht.
  • Netduino sendet 0xF2 als acknolwedgement zurück.
  • Wenn Arduino einen Block hashen will, sendet es 0x48 (ASCII 'H'), gefolgt von den Daten. Wenn es fertig ist, Daten zu senden, setzt es CS niedrig. Es muss ganze Bytes senden; Einstellung CS niedrig, wenn die Anzahl der empfangenen Bits nicht durch 8 teilbar ist, verursacht einen Fehler.
  • Das Netduino empfängt die Daten und sendet 0x68 (ASCII 'h') gefolgt von der Anzahl der empfangenen Bytes als 2-Byte-Ganzzahl ohne Vorzeichen zurück. Wenn ein Fehler aufgetreten ist, sendet er stattdessen 0x21 (ASCII '!') Zurück.
  • Wenn es erfolgreich war, berechnet das Netduino den Hash und setzt dann den Interrupt Pin hoch. Während der Rechenzeit kann der Arduino seine Arbeit während des Wartens fortsetzen.
  • Der Arduino sendet 0x52 (ASCII 'R'), um das Ergebnis anzufordern.
  • Der Netduino setzt den Interrupt-Pin niedrig, sendet dann 0x72 (ASCII 'r') und die Roh-Hash-Daten zurück.
  • Da der Arduino Interrupts über GPIO-Pins bedienen kann, konnte ich die Verarbeitung komplett asynchron machen. Eine Variable auf der Arduino-Seite verfolgt, ob wir derzeit auf dem Coprozessor warten, um seine Aufgabe zu beenden, also versuchen wir nicht, ihm einen neuen Block zu senden, während er noch an dem alten arbeitet.

    Sie könnten dieses Schema für die Berechnung von AES-Blöcken leicht anpassen.

    +1

    Ich gebe Ihnen +1 für die Zeit, um all das zu schreiben (und für die ausgezeichnete Hilfe, die Sie mir in der Vergangenheit gegeben haben), aber das ist ** WAY ** zu schwere Pflicht. .NETZ ?? Extra Prozessor? Ich möchte nur eine kleine (max. 50k, wahrscheinlich ** viel ** kleinere) Datei mit S/W aus dem Regal und dem Minimum an Aufwand en/kryptieren. Idealerweise möchte ich ein singlwe .PAS-Feld und ein .c/.h-Paar hinzufügen und in der Lage sein, eine Datei mit einem einzigen Aufruf zu de-/de-kryptieren. – Mawg

    +1

    Aus Sicherheitsgründen ist es besser, eine bereits geschriebene Implementierung zu verwenden. Wenn Sie Ihre eigene Implementierung für die Produktion bereitstellen, stellen Sie sicher, dass Sie einen Kryptograph und einen Pentester beauftragen, eine gründliche Analyse Ihrer Hardware durchzuführen. Wenn Sie das nicht tun, werden Sie mit ziemlicher Sicherheit Fälle finden, in denen Ihre Implementierung fehlschlägt, selbst wenn Sie "gerade aus dem Internet gezogen" haben, insbesondere in der Arena von Timing-Angriffen, Power-Analyse, etc. Die Kosten von etwas zu rollen Pre-Made ist viel niedriger als Beratung, selbst wenn Sie es auf einen Hardware-Coprozessor entladen müssen. – Polynomial

    +0

    +1, @Polynomial - Ich suche etwas 10% von der Stange. In jeder Anwendung versuche ich nur die Teile zu kodieren, die für die App einzigartig sind und bewährte Bausteine ​​zu verwenden. Dies gilt nicht nur für Krypto. Lazy zu sein macht mich viel produktiver ;-) – Mawg

    1

    Es sieht einfacher aus, eine Referenz-AES-Implementierung (die mit Blöcken funktioniert) zu erhalten und Code hinzuzufügen, um CBC (oder CTR-Verschlüsselung) zu verarbeiten. Dies würde von Ihnen benötigen nur das Hinzufügen ~ 30-50 Zeilen Code, so etwas wie die folgenden (für CBC):

    aes_expand_key(); 
    
    first_block = iv; 
    
    for (i = 0; i < filesize/16; i++) 
    { 
        data_block = read(file, 16); 
        data_block = (data_block^iv); 
        iv = encrypt_block(data_block); 
        write(outputfile, iv); 
    } 
    
    // if filesize % 16 != 0, then you also need to add some padding and encrypt the last block 
    
    +0

    O, 1 dafür, danke, aber ich suche nicht nach den zusätzlichen 30 - 50 Codezeilen - sowohl in Delphi als auch in C. Ich suche vor allem nicht danach, sie zu debuggen. Ich werde weiterhin nach einer Standardlösung googlen. Danke noch einmal. – Mawg

    2

    Small C library for AES-256 von Ilya Levin. Kurze Implementierung, asm-less, einfache Verwendung. Nicht sicher, wie es mit Ihrer aktuellen Mikro-CPU funktionieren würde.

    [Bearbeiten]
    Sie erwähnt haben einige delphi Implementierung haben, aber falls etwas nicht zusammen arbeiten, versuchen this oder this.
    Auch ich habe arduino (avr-basierte) Modul mit der Ilya-Bibliothek gefunden - so sollte es auch auf Ihre Mikro-CPU funktionieren.

    +0

    +1 auch nicht sicher, wie es in Delphi funktionieren würde – Mawg

    2

    Können Sie C-Code von Delphi kompilieren (Sie können Delphi-Code aus C++ Builder kompilieren, nicht sicher über VV). Oder vielleicht den Free Borland Command line C++ compiler oder sogar einen anderen C-Compiler.

    Die Idee ist, den gleichen C-Code in Ihrer Windows-Anwendung zu verwenden, den Sie auf Ihrem Mikroprozessor verwenden. Auf diese Weise können Sie ziemlich sicher sein, dass der Code in beiden Richtungen funktioniert.


    [Update] Siehe

    http://www.drbob42.com/examines/examin92.htm
    http://www.hflib.gov.cn/e_book/e_book_file/bcb/ch06.htm (mit C++ Code in Delphi)
    http://edn.embarcadero.com/article/10156#H11

    Es ist wie Sie verwenden müssen, um eine DLL aussieht, aber man kann es statisch verknüpfen, wenn Sie möchten es nicht verteilen

    1

    die Verschlüsselungsstärke Unter der Annahme ist nicht ein Problem, wie es in einer Organisation Chinese Wall Anforderung erfüllen, die sehr einfach „Sägezahn“ Verschlüsselungsschema des Hinzufügens (i ++% Modulo 256) fgetc(), für jedes Byte , beginnend am Anfang der Datei, könnte gut funktionieren.

    Wenn ich i als UCHAR deklariere, wird die Modulo-Anforderung eliminiert, da die Ganzzahl mit einem Byte nicht mehr helfen kann, aber durch ihren Bereich von 0-255 zu durchlaufen.

    Der Code ist so einfach, es lohnt sich nicht zu posten. Ein wenig Phantasie, und Sie werden einige Verzierungen haben, die der Stärke dieser Chiffre viel hinzufügen können. Die Hauptschwachstelle dieser Chiffre sind große Blöcke identischer Zeichen. Dies zu korrigieren ist ein guter Ort, um mit der Verbesserung seiner Stärke zu beginnen.

    Diese Chiffre arbeitet mit jedem möglichen Dateityp und ist besonders effektiv, wenn Sie die Datei bereits 7Zipped haben.

    Leistung ist phänomenal. Sie werden nicht einmal wissen, dass der Code dort ist. Totally I/O gebunden.