2017-06-08 7 views
0

Ich habe drei Binärdateien: cipher01.bin, cipher02.bin und cipher03.bin. Zusätzlich habe ich eine sign.bin und eine pubkey.pem Datei. Die Aufgabe besteht darin, alle drei Ziffern zu vergleichen und sie mit der Signatur zu vergleichen. Daher habe ich RSA verwendet, um sign.bin mit dem öffentlichen Schlüssel von pubkey.pem zu entschlüsseln.Hash-Chiffren und überprüfen mit Signatur in C

Das Ergebnis sieht gut aus, aber keines der Chiffre-Hashes gehört zur Signatur. Aber ich weiß, dass es mindestens eine Chiffre gibt, die zur Signatur gehört, weil es eine Aufgabe von unserer Universität ist. Vielleicht habe ich etwas vergessen, aber ich kann nicht herausfinden, was.

Hier ist mein Code so weit:

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <openssl/sha.h> 
#include <openssl/err.h> 
#include <openssl/evp.h> 
#include <openssl/pem.h> 
#include <openssl/ssl.h> 
#include <openssl/rsa.h> 
#include <openssl/bio.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 

/** converts unsigned character to readble string*/ 
char *pt(unsigned char *md) { 
    int i; 
    char *buf = (char*)malloc(sizeof(char)*80); 

    for(int i = 0; i < SHA_DIGEST_LENGTH;i++) { 
    sprintf(&(buf[i*2]),"%02x",md[i]); 
    } 

    return (buf); 
} 

/** returns error */ 
void err_exit(void) { 
    printf("%s\n",ERR_error_string(ERR_get_error(),NULL)); 

    ERR_free_strings(); 
    exit(EXIT_FAILURE); 
} 

/** reads a file */ 
char * readFile(char * filename,long int * filesize) { 
    FILE *fin; 
    char *buf; 

    if((fin=fopen(filename,"r"))==NULL) { 
    printf("Error opening %s.\n",filename); 
    exit(EXIT_FAILURE); 
    } 

    fseek(fin,0L,SEEK_END); 
    *filesize = ftell(fin); 
    rewind(fin); 

    if(!(buf=malloc(*filesize))) { 
    printf("Memory exhausted. Stop.\n"); 
    exit(EXIT_FAILURE); 
    } 


    fread(buf,*filesize,1,fin); 
    fclose(fin); 

    return buf; 
} 

/** hash a file with sha1 */ 
char * hashBinaryFile(char * filename) { 
    long int filesize = 0; 

    EVP_MD_CTX c; 
    unsigned char md[SHA_DIGEST_LENGTH]; 

    ERR_load_crypto_strings(); 

    EVP_MD_CTX_init(&c); 

    /** reads files into buf */ 
    char * buf = readFile(filename,&filesize); 

    if((EVP_DigestInit(&c,EVP_sha1()))==0) { 
    err_exit(); 
    } 

    if((EVP_DigestUpdate(&c,buf,filesize))==0) { 
    err_exit(); 
    } 

    if((EVP_DigestFinal(&c,md,NULL))==0) { 
    err_exit(); 
    } 

    //printf("%s\n",pt(md)); 

    EVP_MD_CTX_cleanup(&c); 
    free(buf); 
    ERR_free_strings(); 

    return pt(md); 

} 

int padding = RSA_PKCS1_PADDING; 

/** loads public key and creates rsa */ 
RSA * createRSAWithFilename(char * filename,int public) { 
    FILE * fp = fopen(filename,"rb"); 

    if(fp == NULL) { 
    printf("Unable to open file %s \n",filename); 
    return NULL;  
    } 

    RSA *rsa= RSA_new() ; 

    if(public) { 
    rsa = PEM_read_RSA_PUBKEY(fp, &rsa,NULL, NULL); 
    } else { 
    rsa = PEM_read_RSAPrivateKey(fp, &rsa,NULL, NULL); 
    } 

    return rsa; 
} 

/** decrypt signature */ 
char * public_decrypt(unsigned char * enc_data,int data_len, unsigned char *decrypted) { 
    RSA * rsa = createRSAWithFilename("archieve/pubkey.pem",1); 
    int result = RSA_public_decrypt(data_len,enc_data,decrypted,rsa,padding); 
    return pt(decrypted); 
} 

int main(int argc,char *argv[]) { 
    /** decrypt signature */ 
    long int encrypted_length; 
    long int decrypted_length; 
    unsigned char decrypted[4098]={}; 
    char * encrypted = readFile("archieve/s72897-sig.bin",&encrypted_length); 
    char * sign = public_decrypt(encrypted,encrypted_length, decrypted); 

    char * cipher01 = hashBinaryFile("archieve/s72897-cipher01.bin"); 
    char * cipher02 = hashBinaryFile("archieve/s72897-cipher02.bin"); 
    char * cipher03 = hashBinaryFile("archieve/s72897-cipher03.bin"); 

    if(strcmp(sign,cipher01)==0) { 
    printf("cipher01\n"); 
    } else if(strcmp(sign,cipher02)==0) { 
    printf("cipher02\n"); 
    } else if(strcmp(sign,cipher03)==0) { 
    printf("cipher03\n"); 
    } else { 
    printf("No cipher matches the signature\n"); 
    } 

    return 0; 
} 

Vielen Dank für jede Art von Hilfe.

Edit: Fest einige Code

Edit2: Link auf die * .zip https://ufile.io/tqwoh

Antwort

2

Sie Ihre Dateien in für Menschen lesbaren Format umwandeln zweimal:

char * public_decrypt(...) 
{ 
    return pt(decrypted); 
    // ^
} 

int main(int argc,char *argv[]) 
{ 
    char * sign = pt(public_decrypt(encrypted,encrypted_length, decrypted)); 
    //   ^

Zusätzlich Sie tatsächlich etwas Speicher haben leaks: Sie befreien nicht die RSA-Instanz in public_decrypt noch befreien Sie die zurückgegebenen Zeichenfolgen (verschlüsselt, sign, cypher0 x) ...

Weitere Empfehlung für pt:

char *buf = (char*)malloc(sizeof(char) * 2 * SHA_DIGEST_LENGTH); 

Wenn Sie eine entsprechende Konstante bereits haben, verwenden Sie es ... sizeof(char) ist immer 1 per Definition, so dass Sie es fallen könnte ...

+0

Danke für die Antwort . Ja, es gibt einen Punkt zu viel. Aber das löst mein Problem nicht. Ist es hilfreich für Sie, wenn ich alle zusätzlichen Dateien posten? – Draftsman

+0

@Draftsman Ich bin mir nicht ganz sicher über den Inhalt Ihrer Dateien. Von Ihrem Code gehe ich folgendermaßen aus: Die chiper-Dateien enthalten einige potentiell lange, aber unverschlüsselte chipers. Sie benötigen die Hash-Werte ihres Inhalts. Die sign.bin enthält den Hash-Wert eines dieser drei chipers in * binary * -Form, zusätzlich verschlüsselt mit dem privaten Schlüssel des öffentlichen bereitgestellten. Ist das soweit richtig? Wenn jedoch sign.bin den Hash in einer für Menschen lesbaren Form enthält (aber immer noch verschlüsselt), dürfen Sie ihn überhaupt nicht anwenden ... – Aconcagua

+0

Sie haben absolut recht! Aber nach dem Entschlüsseln des öffentlichen Schlüssels hat es nicht die gleiche Anzahl an Bytes wie die Hash-Werte von der cipherXX.bin! Ich habe auch meine Dateien am Ende des Posts hinzugefügt – Draftsman

Verwandte Themen