我有三个二进制文件:cipher01.bin、cipher02.bin和cipher03.bin。
此外,我还有一个sign.bin和一个pubkey.pem文件。任务是散列所有三个密码并将其与签名进行比较。因此,我使用RSA从pubkey.pem使用公钥解密sign.bin。
结果看起来不错,但是没有一个密码散列属于签名。但我知道,至少有一个密码属于签名,因为这是我们大学的一项任务。也许我忘了什么,但我不知道是什么。
这是我目前的代码:

#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:链接到*.ziphttps://ufile.io/tqwoh

最佳答案

将文件转换为可读格式两次:

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

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

另外,您实际上有一些内存泄漏:您没有在public_decrypt中释放rsa实例,也没有释放返回的字符串(encrypted、sign、cypherx)。。。
关于pt的进一步建议:
char *buf = (char*)malloc(sizeof(char) * 2 * SHA_DIGEST_LENGTH);

如果你已经有了一个合适的常数,使用它。。。sizeof(char)定义上总是1,所以您可以删除它。。。

关于c - 哈希密码并使用C中的签名进行检查,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44431290/

10-16 11:21