OpenSSL sha256使用CPP进行签名和验证

时间:2016-02-15 21:10:05

标签: c++ ssl openssl

我的代码应该读取PKCS12以获取私钥来签署一些文件并检查其签名。

阅读和解析PKCS12似乎工作正常。这个问题特别在验证时发生。接下来是签名和验证。

int sign (EVP_PKEY *pkey, char* msg,unsigned char** sig, size_t* slen){
    EVP_MD_CTX *mdctx = NULL;
    int ret = 0;
    size_t req = 0;

    *sig = NULL;
   /* Create the Message Digest Context */
    if(!(mdctx = EVP_MD_CTX_create())) {
        qDebug()<<"0";
         return 0;
    }

    /* Initialise the DigestSign operation - SHA-256 has been selected as the message digest function in this example */
    if(1 != EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL,pkey)) {
        qDebug()<<"A";
        return 0;
    }

    /* Call update with the message */
    if(1 != EVP_DigestSignUpdate(mdctx, msg, strlen(msg))) {
        qDebug()<<"B";
        return 0;
    }
    /* Finalise the DigestSign operation */
    /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the
    * signature. Length is returned in slen */
    if(1 != EVP_DigestSignFinal(mdctx, NULL, slen)) {
        qDebug()<<"C";
        return 0;
    }
    /* Allocate memory for the signature based on size in slen */
    if(!(*sig =(unsigned char *) OPENSSL_malloc(sizeof(unsigned char) * (*slen)))){
        qDebug()<<"D";
        return 0;
    }

    /* Obtain the signature */
    if(1 != EVP_DigestSignFinal(mdctx, *sig, slen)){
        qDebug()<<"E";
        return 0;
    }
    //qDebug()<<(char*)sig;

    /* Success */
    ret = 1;

    /* Clean up */
    if(*sig && !ret) OPENSSL_free(*sig);
    if(mdctx) EVP_MD_CTX_destroy(mdctx);
    qDebug()<<"SIGNED";
    return 1;
}

/*------------------------------*/

int verify(EVP_PKEY *pubkey, const char* msg,unsigned char* sig, size_t slen){
    EVP_MD_CTX *mdctx;

    ERR_get_error();

    if(!(mdctx = EVP_MD_CTX_create())) {
        qDebug()<<"DEU RUIM";
    }

    EVP_MD_CTX_init(mdctx);

    if(1 != EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, pubkey)){
        qDebug()<<"Err1";
        return 0;
    }

    if(1 != EVP_DigestVerifyUpdate(mdctx, msg, strlen(msg))){
        qDebug()<<"Err2";
        return 0;
    }

    ERR_print_errors_fp(stderr);

    if(1 == EVP_DigestVerifyFinal(mdctx, sig, slen)) {
        qDebug()<<"THE FILE IS ORIGINAL";
        return 1;
    } else{
        qDebug()<<"THE FILE IS NOT ORIGINAL";
        return 0;
    }
}

我的想法是将证书写入文件,并在我想验证时从文件中读取它。问题是它只能正确验证(打印&#39;文件是原文&#39;)当我在sign()传递&#39; sig&#39;之后调用verify()时。和&#39; sln&#39; sign()中的参数在verify()中被改变,否则我只是收到了“FILE IS NOT ORIGINAL&#39;没有任何错误。

打印出verify()工作时使用的参数和不工作的参数,但它们看起来完全一样。

以下是我如何调用函数

/*---(START)IF COMMENT THIS PART, VERIFIES WRONGLY---*/
    sign(prkey, msg, &sig, &len);

    /*write file certificate*/
    ofstream outfile("outCert",ios::out | ios::binary);
    outfile.write((reinterpret_cast<const char*>(sig)),len);
/*---(END)---*/ 

//set public key
EVP_PKEY* pubkey=X509_get_pubkey(cert);
FILE* file2;
unsigned char *msg2;
size_t sz;

file2=fopen ("outCert","rb");
if(file2!=NULL){
        fseek(file2, 0L, SEEK_END);
        sz = ftell(file2);
        fseek(file2, 0, SEEK_SET);
        msg2 = new unsigned char [sz];
        fread(msg2,1,sz,file2);
        fclose(file2);

}else cout << "Unable to open file";

//change 'msg2' and 'sz' for 'sig' and 'len' to work respectively
verify(pubkey,msg,msg2,sz);

一个问题是它在写入文件后无法立即从文件中读取。所以我必须运行一次来​​编写,评论写作部分并运行以阅读。&lt;&lt;解决了这一部分。刚写完后添加了outfile.close()

我不知道OpenSSL函数是否受时间影响,但尝试在函数之间加一些延迟并得到相同的结果。

欢迎任何帮助!

0 个答案:

没有答案