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
感謝您的回答。是的,有一個點太多了。但是這並不能解決我的問題。如果我發佈所有其他文件,對您有幫助嗎? – Draftsman
@Draftsman我不完全確定你的文件的內容。從您的代碼中,我假設如下:chiper文件包含一些可能長但未加密的遊標卡。你需要他們內容的散列值。 sign.bin以* binary *形式包含這三個chipers之一的哈希值,並且使用屬於公共提供的私鑰加密。目前爲止是否正確?但是,如果sign.bin以人類可讀的形式包含散列(但仍然是加密的),那麼您絕對不能將pt應用於它... – Aconcagua
您絕對是對的!但是,在解密公鑰後,它與cipherXX.bin中的哈希值的字節數不相同!我還在帖子末尾添加了我的文件 – Draftsman