我正在尝试使用DSA证书签署一些数据。我将证书保存在内存中(该证书是使用openssl gendsa命令生成的)。

我的函数看起来像这样,我的问题是res = EVP_SignFinal。在这里,该函数返回0,并将signature_len设置为0。

bool my_dsa_sign(const Certificate& certificate, const char* messageData, size_t messageLength, Signature &outSignature) {
    bool resultOk = false;
    BIO* bio = BIO_new_mem_buf((void*) certificate.getPEMData(), certificate.getSize());
    if(NULL != bio) {
        EVP_PKEY *pkey = NULL;
        if(NULL != (pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL))) {
            unsigned int signature_len;
            EVP_MD_CTX ctx;
            int res = EVP_SignInit(&ctx, EVP_sha512());
            if(1 == res) {
                res = EVP_SignUpdate(&ctx, messageData, messageLength);
                if(1 == res) {
                    unsigned char* s = (unsigned char*)malloc(EVP_PKEY_size(pkey));

                    // problem here
                    res = EVP_SignFinal(&ctx, s, &signature_len, pkey);
                    if(1 == res) {
                        resultOk = true;
                        signature.setData(s, signature_len);
                    }
                }
            }
            EVP_PKEY_free(pkey);
            EVP_MD_CTX_cleanup(&ctx);
        }
        BIO_free(bio);
    }
    return resultOk;
}

知道可能是什么问题吗?
我已经通过调试器检查了证书的值是否正确,格式为:
-----BEGIN DSA PRIVATE KEY-----
MIID....
.......
-----END DSA PRIVATE KEY-----

长度也正确,与文件长度匹配。

最佳答案

我不太了解OpenSSL,在您的代码中看不到任何使用DSA的地方。

int res = EVP_SignInit(&ctx, EVP_sha512());

manual page to EVP_SignInit 说:



manual page to EVP_sha512 说:



由我突出显示。
因此,似乎您正在尝试使用DSA密钥进行RSA签名,该签名将不起作用(或吐出废话)。

浏览了文档之后,尽管文档现在指出:尽管我还没有找到将SHA512与DSA一起使用的方法。

09-06 15:47