Der Entschlüsselungs- und Verschlüsselungscode (im Folgenden enthalten) ist möglicherweise falsch. Sie kompilieren fehlerfrei, jedoch ist die entschlüsselte Datei nicht die gleiche wie die Klartextdatei. Es ist verstümmelt.(Sprache C) Verstümmelte Entschlüsselung im AES-CTR-basierten Verschlüsselungsentschlüsselungstool
Ich versuche herauszufinden, warum es verstümmelt ist. Ich bezweifle, dass mein Code in Ordnung ist.
Ich habe eine Reihe von Dingen, die möglicherweise das Problem lösen könnten, aber keiner funktionierte. Ich habe eine bestimmte Art der Verwendung von AES-CTR, d. H. Ich schließe nicht direkt OpenSSL ein. Ich bin abhängig von /dev/urandom/dev/random für Zufälligkeit (von IV, et cetera).
Die Menge Dinge beinhaltet die Art, wie ich mit meinem encrypt befasse und entschlüsseln Funktion (wie: *(ptr)
statt ptr[]
und mehrere anderen gleichwertigen Ersatz verwenden, die in der Regel nicht notwendig sind), welche Argumente ich vorbei und Kontrolle für bestimmte Validierungen bevor Sie schließlich die verschlüsselten oder entschlüsselten Texte speichern.
Ich werde die initialisierte IV nicht erhöhen (oder ändern). IV ist 16 Bytes.
Früher, ich tat dies das letzte Byte von IV zu erhöhen:
size_t blocksize = CCA_STRENGTH; /* CCA_STRENGTH is "#define CCA_STRENGTH 16" */
char *iv = (char *) malloc(16 * sizeof(char));
ri(); /* PRNG initialized.*/
prng_getbytes(iv, blocksize);
*
*
*
*
size_t iv_counter = 0;
while loop starts here...
*
*
*(iv +(block_size - 1)) += iv_counter;
*
*
while loop ends here...
Diese while-Schleife, wo die Verschlüsselung und Entschlüsselung geschieht vorhanden ist unten (dieser Teil vorübergehend, da es eine Sicherheit entfernt wird Anforderung und nicht ein Kodierungsstandard oder die Anforderung der Entschlüsselungs- oder Entschlüsselungsfunktion).
Hier ist meine Entschlüsseln Code:
#include "pv.h"
void decrypt_file (const char *ptxt_fname, void *raw_sk, size_t raw_len, int fin)
{
int fd;
if((fd = open(ptxt_fname, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0)
{
/*fd will become -1 on failure.*/
perror("plaintext file permission error\n");
exit(EXIT_FAILURE);
}
size_t block_size = CCA_STRENGTH;
const char *aes_key;
aes_key = (const char *) raw_sk;
aes_ctx aes;
aes_setkey(&aes, aes_key, block_size);
char *iv;
iv = (char *) malloc(block_size * sizeof(char));
size_t bytes_read;
bytes_read = read(fin, iv, block_size);
char *buf = (char *) malloc(block_size * sizeof(char)); /*ctxt-file read buffer*/
char *ptxt = (char *) malloc(block_size * sizeof(char)); /*p-text buffer*/
memset(ptxt, 0, block_size);
bytes_read = read(fin, buf, block_size);
while(bytes_read >= 1)
{
aes_encrypt(&aes, ptxt, iv); /* earlier it was "aes_decrypt(&aes, ptxt, iv);" which was not the correct reverse transformation function */
for(loop_variable = 0; loop_variable < bytes_read; loop_variable++)
{
*(ptxt + loop_variable) = *(ptxt + loop_variable)^*(buf + loop_variable);
}
if((result = write_chunk(fd, ptxt, bytes_read)) == -1)
{
perror("Problem when writing to ptxt file... \n");
close(fd);
unlink(ptxt_fname); /*for file deletion*/
aes_clrkey(&aes);
free(ptxt);
free(iv);
free(buf);
exit(EXIT_FAILURE);
}
if((bytes_read = read(fin, buf, block_size)) < 1)
{
close(fd);
aes_clrkey(&aes);
free(ptxt);
free(iv);
free(buf);
break;
}
}
}
void
usage (const char *pname)
{
printf ("Simple File Decryption Utility\n");
printf ("Usage: %s SK-FILE CTEXT-FILE PTEXT-FILE\n", pname);
printf (" Exits if either SK-FILE or CTEXT-FILE don't exist, or\n");
printf (" if a symmetric key sk cannot be found in SK-FILE.\n");
printf (" Otherwise, tries to use sk to decrypt the content of\n");
printf (" CTEXT-FILE: upon success, places the resulting plaintext\n");
printf (" in PTEXT-FILE; if a decryption problem is encountered\n");
printf (" after the processing started, PTEXT-FILE is truncated\n");
printf (" to zero-length and its previous content is lost.\n");
exit (1);
}
int main (int argc, char **argv)
{
int fdsk, fdctxt;
char *sk = NULL;
size_t sk_len = 0;
if (argc != 4) {
usage (argv[0]);
}
else if (((fdsk = open (argv[1], O_RDONLY)) == -1)
|| ((fdctxt = open (argv[2], O_RDONLY)) == -1)) {
if (errno == ENOENT) {
usage (argv[0]);
}
else {
perror (argv[0]);
exit (-1);
}
}
else {
setprogname (argv[0]);
if (!(sk = import_sk_from_file (&sk, &sk_len, fdsk))) {
printf ("%s: no symmetric key found in %s\n", argv[0], argv[1]);
close (fdsk);
exit (2);
}
close (fdsk);
decrypt_file (argv[3], sk, sk_len, fdctxt);
bzero(sk, sk_len);
free(sk);
close (fdctxt);
}
return 0;
}
Hier ist meine encrypt Code:
#include "pv.h"
void encrypt_file (const char *ctxt_fname, void *raw_sk, size_t raw_len, int fin)
{
size_t block_size = CCA_STRENGTH;
int fd; /* ctxt fd */
if((fd = open(ctxt_fname,O_WRONLY|O_TRUNC|O_CREAT,0600)) < 0)
{
perror("Ciphertext file permission error\n");
exit(EXIT_FAILURE);
}
char *iv;
iv = (char *) malloc(block_size * sizeof(char));
ri(); /*IV initialized*/
prng_getbytes(iv, block_size);
struct aes_ctx aes;
const char *aes_key = aes_key = (const char *) raw_sk;
aes_setkey(&aes, aes_key, block_size); /*sets the encryption key.*/
char *buf = buf = (char *) malloc(block_size * sizeof(char)); /*file read buffer*/
char *ctxt = ctxt = (char *) malloc(block_size * sizeof(char)); /*ciphertext buffer*/
int result;
size_t looper = 0;
size_t bytes_read;
result = write_chunk(fd, iv, block_size);
if(result == -1)
{
exit(-1);
}
bytes_read = read(fin, buf, block_size); /*returns how many bytes read*/
while(bytes_read >= 1)
{
aes_encrypt(&aes, ctxt, iv);
for(looper = 0; looper < bytes_read; looper++)
{
*(ctxt + looper) = *(ctxt + looper)^*(buf + looper);
}
result = write_chunk(fd, ctxt, bytes_read);
if(result == -1)
{
perror("Problem when writing to ctxt file... \n");
close(fd);
unlink(ctxt_fname); /*for file deletion*/
aes_clrkey(&aes);
free(ctxt);
free(iv);
free(buf);
exit(EXIT_FAILURE);
}
printf("crossed written to file\n");
if((bytes_read = read(fin, buf, block_size)) < 1)
{
close(fd);
aes_clrkey(&aes);
free(ctxt);
free(iv);
free(buf);
break;
}
}
}
void usage (const char *pname)
{
printf ("Personal Vault: Encryption \n");
printf ("Usage: %s SK-FILE PTEXT-FILE CTEXT-FILE\n", pname);
printf (" Exits if either SK-FILE or PTEXT-FILE don't exist.\n");
printf (" Otherwise, encrpyts the content of PTEXT-FILE under\n");
printf (" sk, and place the resulting ciphertext in CTEXT-FILE.\n");
printf (" If CTEXT-FILE existed, any previous content is lost.\n");
exit (1);
}
int main (int argc, char **argv)
{
int fdsk, fdptxt;
char *raw_sk;
size_t raw_len;
if (argc != 4)
{
usage (argv[0]);
}
else if (((fdsk = open (argv[1], O_RDONLY)) == -1) || ((fdptxt = open (argv[2], O_RDONLY)) == -1))
{
if (errno == ENOENT)
{
usage (argv[0]);
}
else
{
perror (argv[0]);
exit (-1);
}
}
else
{
setprogname (argv[0]);
if (!(import_sk_from_file (&raw_sk, &raw_len, fdsk)))
{
printf ("%s: no symmetric key found in %s\n", argv[0], argv[1]);
close (fdsk);
exit (2);
}
close (fdsk);
bzero(raw_sk, raw_len);
free(raw_sk);
close (fdptxt);
}
return 0;
}
Der encrypt Code 16 Bytes IV der Chiffretext-Datei wird das Voranstellen erste (wie es sein sollte, ich denke, wir lesen diese 16 Bytes aus der ctxt-Datei im Entschlüsselungsprozess) und dann passiert die eigentliche Verschlüsselung (wenn man sie als Blackbox betrachtet) w hier senden wir die IV und den Schlüssel; 16 Byte werden zurückgegeben. Diese 16 Bytes, die zurückgegeben werden, müssen mit dem Klartext-Dateipuffer XOR-verknüpft werden (bis zu 16 Bytes für jede Runde, wenn eine Datei mehr als 16 Bytes hat).
Post, dass die XORed-Bytes (die bis zu 16 Bytes sein werden) in die Datei geschrieben werden. Diese Sache passiert bis zur letzten Runde, die schließlich die Schleife unterbricht, wenn sie versucht, die Datei zu lesen, die keinen Inhalt mehr zu lesen hat. Lesefunktion versucht bei jedem Aufruf die nächsten verfügbaren Bytes zu lesen (bis zur angegebenen Anzahl an Bytes).
Dies ist keine perfektionierte Implementierung, da ich den Sicherheitsaspekt (Randomisierung der IV für jeden Zyklus) gelockert habe, jedoch muss es so zuerst funktionieren.
Mathematisch was ich versuche, die exakte Kopie dieses Konzepts zu tun sein sollte:
ciphertext_block = message_block^[AES(IV, Key)]
message_block = ciphertext_block^[AES(IV, Key)]
Hier Chiffretext/message_block bezieht sich auf einen Block von Zeichen das sind 16 Bytes für 1. bis n-1 Runden, können aber in der letzten Runde 16 Bytes sein oder nicht.
In jedem Fall XORing wird zwischen 16 Bytes Zeichen (Ausgabe von AES-CTR) und einem anderen Block (Block für die Verschlüsselung, Chiffretext-Block für die Entschlüsselung, auf jeden Fall kann es bis zu 16 Bytes und damit sind sie getan die XOR-Bedingungen, dh sie sind die Entscheider der Länge der XOR-Ausgabe).
Da sie die Entscheider sind, sobald die XORing-Operation ihre Länge abdeckt, stoppt die XORing-Schleife und wir gehen vorwärts in Richtung Schreiben in eine Datei (ctxt-Datei für Verschlüsselung, ptxt-Datei für Entschlüsselung).
Es sollte keine Polsterungsanforderungen geben.
Ich bin mir nicht sicher, ob ich realloc
Funktionen an irgendeinem Ort verwenden sollte.
Ich werde gerne zusätzliche Dokumentationen zur Verfügung stellen, wenn ein Leser Probleme hat zu verstehen, was ich versuche zu tun.
Das Programm hat mehrere Bibliotheksabhängigkeiten, der Code wird jedoch fehlerfrei kompiliert.
Das ist meine Sammlung Befehl:
gcc -g -O2 -ansi -Wall -Wsign-compare -Wchar-subscripts -Werror -I. -I/usr/include/ -I/home/devel/libdcrypt/include/ -c pv_keygen.c pv_misc.c
gcc -g -O2 -ansi -Wall -Wsign-compare -Wchar-subscripts -Werror -o pv_keygen pv_keygen.o pv_misc.o -L. -L/usr/lib/ -L/home/devel/libdcrypt/lib/ -ldcrypt -lgmp
Dies ist nur für die Erstellung meiner verschlüsseln Datei. Fast gleiche (und ebenso strenge) Befehle sind für meine keygen- und entschlüsselte Datei. Keygen Code scheint gut zu funktionieren (ich habe das hier noch nicht aufgenommen); Ich kann einen Schlüssel erzeugen und ihn in eine Datei serialisieren. Diese Schlüsseldatei enthält tatsächlich zwei Schlüssel und ich lese nur die erste Hälfte für AES-CTR. Die nächste Hälfte wird MAC-Zwecken dienen (mit AES-CBC).
Dateigröße Details
Klartext-Datei: x Bytes
Chiffretext-Datei: (x + 16) Bytes
entschlüsselten Text-Datei: x Bytes
Statistik Recht, Inhalte ist nicht. Die entschlüsselte Textdatei und die Klartextdatei müssen identisch sein.
Ich versuche: diff plaintext_file decrypted_file auf RedHat zum Dateivergleich.
Schlüssel-Datei ist eigentlich 32 Bytes, von denen die ersten 16 Bytes für die Verschlüsselung verwendet werden und die späteren 16 Bytes für die MAC-Post-Verschlüsselung verwendet werden.
Schlüsseldatei (die serialisiert bis 64 Basen) (hex):
0000000 4662 6e4b 6631 7268 4876 676c 772f 664e
0000010 4d5a 6f32 384e 5141 7139 6635 3442 7245
0000020 646c 4a77 5553 4c30 4f63 3d6f 000a
000002d
Eingangsklartextdatei (hex):
0000000 6161 6161 6161 6161 6161 6161 610a 6161
0000010 000a
0000011
Verschlüsselte Datei (hex):
0000000 540e 0e30 d74d 5000 78c1 13e3 0476 d4a2
0000010 61c9 76ac e717 cd6d 013e e872 8e16 4827
0000020 00a2
0000021
Entschlüsselte Datei (hex):
0000000 8bea 616a 1f1b d6b0 fd13 da46 5824 ec00
0000010 0081
0000011
Externe Verweise (I abgeschnitten haben unten Dinge, wo der Fehler existieren kann):
1.) http://www.scs.stanford.edu/nyu/05sp/lab/lab1.html
2) http://www.scs.stanford.edu/nyu/05sp/lab/install-libs.html
Side: "Hat eine Menge zufälliger Dinge gemacht" - Dartboards und Augenbinden funktionieren selten selbst bei scheinbar einfachen Aufgaben und ziemlich viel - nie auf Dinge wie Kryptographie. so dass das Ergebnis etwas selbstprophezeiendes war. – WhozCraig
@WhozCraig Zufälligkeit wird nicht helfen. Lass mich nochmal fragen. Das waren eher nachdenkliche Versuche, es zum Laufen zu bringen. Es scheint, dass etwas furchtbar schief geht (nur verschlüsseln und/oder entschlüsseln). Darauf freue ich mich. – Avineshwar
Dies ist ziemlich komplex zu * überprüfen * oder * debug *. Stellen Sie vor dem Verfassen sicher, dass Sie zuerst Ihr Antragsrecht verfassen. Entfernen Sie also die Dateiverwaltung aus dem Krypto-Code und schreiben Sie Unit-Tests darum herum. Es ist gut zu sehen, dass Sie Komplexität um z. IV-Erstellung, aber Sie müssen dies ein paar Schritte weiter gehen. –