2017-06-08 29 views
0

我有三個二進制文件:cipher01.bin,cipher02.bin和cipher03.bin。 另外我有一個sign.bin和一個pubkey.pem文件。其任務是對所有三種密碼進行散列並將其與簽名進行比較。因此我使用RSA使用pubkey.pem中的公鑰解密sign.bin。哈希密碼和檢查與簽名在C

結果看起來不錯,但沒有一個密碼哈希屬於簽名。但我知道,至少有一個密碼屬於簽名,因爲它是我們大學的一項任務。也許我忘了一些東西,但我無法弄清楚什麼。

這裏是我到目前爲止的代碼:

#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; 
} 

感謝任何形式的幫助。

編輯:修正了一些代碼

EDIT2:鏈接* .zip文件https://ufile.io/tqwoh

回答

2

你改變你的文件人類可讀的格式兩次:

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

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

此外,你確實有一些內存泄漏:您不會釋放public_decrypt中的rsa實例您也不會釋放返回的字符串(加密,簽名,cypher0 x)...

在PT進一步建議:

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

如果你有一個適當的常數已經使用它... sizeof(char)始終是1的定義,所以你可以放棄它...

+0

感謝您的回答。是的,有一個點太多了。但是這並不能解決我的問題。如果我發佈所有其他文件,對您有幫助嗎? – Draftsman

+0

@Draftsman我不完全確定你的文件的內容。從您的代碼中,我假設如下:chiper文件包含一些可能長但未加密的遊標卡。你需要他們內容的散列值。 sign.bin以* binary *形式包含這三個chipers之一的哈希值,並且使用屬於公共提供的私鑰加密。目前爲止是否正確?但是,如果sign.bin以人類可讀的形式包含散列(但仍然是加密的),那麼您絕對不能將pt應用於它... – Aconcagua

+0

您絕對是對的!但是,在解密公鑰後,它與cipherXX.bin中的哈希值的字節數不相同!我還在帖子末尾添加了我的文件 – Draftsman