我正在尝试使用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-----
长度也是正确的,与文件的长度相匹配。
答案 0 :(得分:2)
对OpenSSL了解不多,我没有看到您在代码中使用DSA的任何地方。
int res = EVP_SignInit(&ctx, EVP_sha512());
EVP_SignInit()
初始化签名上下文 ctx 以使用摘要类型的默认实现。
[...],
EVP_sha512()
,[...]分别为[...],SHA512,[...]摘要算法返回EVP_MD
个结构。 在每种情况下,相关的签名算法都是RSA。
我的亮点。 因此,看起来您正在尝试使用DSA密钥进行RSA签名,这不会起作用(或吐出废话)。
在浏览完文档后,我找不到将SHA512与DSA一起使用的方法,尽管文档现在说明了:
摘要和签名算法之间的链接在OpenSSL 1.0及更高版本中得到修复,因此现在可以使用
EVP_sha1()
使用RSA和DSA,无需再使用EVP_dss1()
。