RSA_sign 和 EVP_DigestSignX() 之间的区别

Difference between RSA_sign and EVP_DigestSignX()

我有 2 个代码,都应该签署 SHA256 哈希字符串,并且都使用 C++ 中的 openssl 库和私钥。但是,我不明白它们之间的区别。我没有写任何这些代码。

第一个使用 EVP_DigestSign 函数。

bool RSASign( RSA* rsa,
              const unsigned char* Msg,
              size_t MsgLen,
              unsigned char** EncMsg,
              size_t* MsgLenEnc) {
  EVP_MD_CTX* m_RSASignCtx = EVP_MD_CTX_create();
  EVP_PKEY* priKey  = EVP_PKEY_new();
  EVP_PKEY_assign_RSA(priKey, rsa);
  if (EVP_DigestSignInit(m_RSASignCtx,NULL, EVP_sha256(), NULL,priKey)<=0) {
      return false;
  }
  if (EVP_DigestSignUpdate(m_RSASignCtx, Msg, MsgLen) <= 0) {
      return false;
  }
  if (EVP_DigestSignFinal(m_RSASignCtx, NULL, MsgLenEnc) <=0) {
      return false;
  }
  *EncMsg = (unsigned char*)malloc(*MsgLenEnc);
  if (EVP_DigestSignFinal(m_RSASignCtx, *EncMsg, MsgLenEnc) <= 0) {
      return false;
  }
  EVP_MD_CTX_cleanup(m_RSASignCtx);
  return true;
}
char* signMessage(std::string privateKey, std::string plainText) {
  RSA* privateRSA = createPrivateRSA(privateKey); 
  unsigned char* encMessage;
  char* base64Text;
  size_t encMessageLength;
  RSASign(privateRSA, (unsigned char*) plainText.c_str(), plainText.length(), &encMessage, &encMessageLength);
  Base64Encode(encMessage, encMessageLength, &base64Text);
  free(encMessage);
  return base64Text;
}

第二个非常不同,它不使用任何 EVP_.. 函数。

RSA * createRSA(unsigned char * key,int public_private)
{
    RSA *rsa= RSA_new(); //NULL;
    if (rsa == NULL)
    {
        LOGF_WARN("Failed to create RSA");
        return 0;
    }
    BIO *keybio ;
    keybio = BIO_new_mem_buf(key, -1);
    if (keybio==NULL)
    {
        LOGF_TRACE( "Failed to create key BIO");
        return 0;
    }
    if(public_private)
    {
        rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa,NULL, NULL);
    }
    else
    {
        rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa,NULL, NULL);
    }

    return rsa;
}
int private_sign(const unsigned char * data, int data_len, unsigned char * key,
    unsigned char *sigret, unsigned int * siglen){
    RSA * rsa = createRSA(key,0);
    if (rsa == NULL || !rsa) 
    {
        LOGF_TRACE("Failed to create RSA");
        printLastError("SELLADO RSA-");
        return 0;
    }
    printLastError("SELLADO RSA-");
    int result =  RSA_sign(NID_sha256, data, data_len,sigret, siglen, rsa);

    return result;
}

我找到这些代码是因为我想签署一个我之前在我的程序中创建的 SHA256 散列。但是我对密码学不是很有经验,所以我很难理解这两个代码之间的区别,我读到 EVP 函数是高级的,这是否意味着其他的是低级的?

希望您能帮我解决这个问题,在此先感谢...如果您还需要什么,请告诉我。

来源: http://hayageek.com/rsa-encryption-decryption-openssl-c/ https://gist.github.com/irbull/08339ddcd5686f509e9826964b17bb59

一个典型的签名过程包括
1) 摘要(message) => md
2) do_something_using_private_key(md) => signature

EVP_DigestSignXXXs为您做这两步,而RSA_sign只做第2步,您需要自己做第1步,使用EVP_DigestXXXs, SHA256_XXX, ...

例如:

unsigned char md[64];
SHA256(data, datalen, md);
RSA_sign(rsakey, md, mdlen, sig, &siglen);

函数private_sign的参数datadata_len有点混乱。实际上应该传入一个消息摘要(md)。