【问题标题】:Hash Ciphers and check with Signature in C散列密码并使用 C 中的签名进行检查
【发布时间】:2017-11-09 21:46:27
【问题描述】:

我有三个二进制文件: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:链接到 *.zip https://ufile.io/tqwoh

【问题讨论】:

    标签: c hash rsa digital-signature sha1


    【解决方案1】:

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

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

    此外,您实际上还有一些内存泄漏:您没有释放 public_decrypt 中的 rsa 实例,也没有释放返回的字符串(加密、签名、cypher0x)...

    对 pt 的进一步推荐:

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

    如果您已经有一个合适的常量,请使用它...sizeof(char) 根据定义始终为 1,因此您可以删除它...

    【讨论】:

    • 感谢您的回答。是的,一分太多了。但这并不能解决我的问题。如果我发布所有其他文件,对您有帮助吗?
    • @Draftsman 我不完全确定您文件的内容。根据您的代码,我假设以下内容:芯片文件包含一些可能很长但未加密的芯片。您需要其内容的哈希值。 sign.bin 包含 binary 形式的这三个芯片之一的哈希值,另外使用属于提供的公共密钥的私钥加密。到目前为止是正确的吗?但是,如果 sign.bin 包含人类可读形式的哈希(但仍然是加密的),则根本不能将 pt 应用于它...
    • 你完全正确!但是在解密公钥后,它的字节数与 cipherXX.bin 中的哈希值不同!我还在帖子末尾添加了我的文件
    • 我稍后再看看 - 这里没有可用的正在运行的 openssl,现在也没有时间处理......
    • 如果您能看一看,我将不胜感激。感谢您的努力
    猜你喜欢
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    • 2018-11-20
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多