OpenSSL和MS CryptoAPI:不同的数字签名 [英] OpenSSL and MS CryptoAPI: different digital signatures

查看:284
本文介绍了OpenSSL和MS CryptoAPI:不同的数字签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用makecert实用程序生成了带有私钥的X509证书

I generated X509 certificate with private key using makecert utility

makecert -n "CN=RootCATest" -r -sv RootCATest.pvk RootCATest.cer 
makecert -sk MyKeyName -iv RootCATest.pvk -n "CN=tempCert" -ic RootCATest.cer -sr currentuser -ss my -sky signature —pe 

然后我使用OpenSSL将RootCATest.pvk转换为RootCATest.pem。我提取了公钥:pubRootCATest.pem

Then I converted RootCATest.pvk to RootCATest.pem with OpenSSL. And I extracted public key: pubRootCATest.pem

我有一个小文件叫'msg'。
我使用SHA1签署此文件。

I have small file called 'msg'. And I sign this file using SHA1.

openssl dgst -sha1 -sign c:\RootCATest.pem -out c:\openssl c:\msg

然后我想获得相同的数字签名MS CryptoAPI。

Then I want to obtain the same digital signature using MS CryptoAPI.

这是我的代码(注意:这是理解概念的代码,所以我不释放分配的内存)

Here is my code (Note: this is the code to understand concepts so I don't free allocated memory)

void SwapBytes(BYTE *pv, int n)
{
    BYTE *p = pv;
    int lo, hi;
    for(lo=0, hi=n-1; hi>lo; lo++, hi--)
    {
        BYTE tmp=p[lo];
        p[lo] = p[hi];
        p[hi] = tmp;
    }
}

void sign()
{
    FILE *file;
    BYTE *msg;
    int msg_size;

    HCRYPTPROV hProv;
    HCERTSTORE hStore;
    PCCERT_CONTEXT pCert;
    DWORD dwKeySpec;
    BOOL fCallerFreeProv;
    BYTE  *pSignature;
    DWORD sigLen;

    // Read message bytes from file
    file = fopen("c:\\msg", "r");
    fseek(file, 0, SEEK_END);
    msg_size = ftell(file);
    fseek(file, 0, SEEK_SET);
    msg = new BYTE[msg_size];
    fread(msg, sizeof(BYTE), msg_size, file);
    fclose(file);

    hStore = CertOpenSystemStore(NULL, "My");
    pCert = CryptUIDlgSelectCertificateFromStore(hStore, NULL, NULL, NULL, 0, 0, NULL);
    CryptAcquireCertificatePrivateKey(pCert, CRYPT_ACQUIRE_COMPARE_KEY_FLAG, NULL, &hProv, &dwKeySpec, &fCallerFreeProv);
    PrintCryptoProviderName(hProv); // prints Microsoft Strong Cryptographic Provider

    ALG_ID hashAlgId = CALG_SHA1;
    HCRYPTHASH hHash;
    CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
    CryptHashData(hHash, msg, msg_size, 0);

    CryptSignHash(hHash, dwKeySpec, NULL, 0, NULL, &sigLen);
    pSignature = new BYTE[sigLen];
    CryptSignHash(hHash, dwKeySpec, NULL, CRYPT_NOHASHOID, pSignature, &sigLen);

    SwapBytes(pSignature, sigLen); // Here i reverse byte order as I read that MS CryptoAPI uses reversed byte order

    // Write signature bytes to file
    file = fopen("c:\\CryptSignHash", "w");
    fwrite(pSignature, sizeof(BYTE), sigLen, file);
    fclose(file);
}

作为输出,我得到的签名完全不同于OpenSSL的签名。
如何获得相同的签名?

As output I get the signature absolutely different from the signature made by OpenSSL. How can I obtain the same signature?

我认为有一些时刻需要注意:

As I consider there are some moments to pay attention:


  • 我的msg_size与文件大小相同。所以它是字节数到
    的符号。在一些网站上,我看到了建议添加一个空字节到
    数组。在这种情况下我真的需要它吗?

  • 标志CRYPT_NOHASHOID。没有它,我得到大小130字节的签名,当OpenSSL做的签名是128字节。所以我认为CRYPT_NOHASHOID应该在那里。

  • SwapBytes(...)我试过它,没有它。在这两种情况下,I
    的签名与OpenSSL签名完全不同。

推荐答案


如何获得相同的签名?

How can I obtain the same signature?

大多数数字签名算法在这里使用,是非确定性的。

Most digital signature algorithms - including RSA, which I suppose you have used here, are non-deterministic. Try signing the same file twice with the same program, and you will get different outputs.

这意味着,使用相同的输入执行相同的算法两次将给您不同的签名。这不是问题,只要验证算法仍然设法接受由签名算法(使用拟合键)生成的所有签名。

This means, running the same algorithm twice with the same input will give you different signatures. This is not a problem, as long as the verification algorithm still manages to accept all signatures generated by the signing algorithm (with the fitting key).

这个非确定性是

要查看您的两个签名算法是否实际兼容,请尝试使用MS Crypto API验证OpenSSL签名,以及使用OpenSSL验证MS加密签名。 (然后按一个字节修改文件,并检查它们是否不再验证。)

To see if your two signature algorithms are actually compatible, try to verify the OpenSSL signature with the MS Crypto API, and to verify the MS Crypto signature with OpenSSL. (Then modify the file by one byte and check that they don't verify anymore.)

这篇关于OpenSSL和MS CryptoAPI:不同的数字签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆