2

我正在尝试使用 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-----

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

4

1 回答 1

1

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

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

手册页EVP_SignInit说:

EVP_SignInit()初始化签名上下文ctx以使用摘要类型的默认实现。

手册页EVP_sha512说:

[...], EVP_sha512(), [...] 分别返回EVP_MD[...], SHA512 , [...] 摘要算法的结构。 在每种情况下,相关的签名算法都是 RSA。

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

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

摘要和签名算法之间的链接在 OpenSSL 1.0 及更高版本中已修复,因此现在EVP_sha1()可以与 RSA 和 DSA 一起使用,无需再使用EVP_dss1()

于 2011-12-04T20:41:37.180 回答