CryptographicEngine::SignHashedData 未实施错误

CryptographicEngine::SignHashedData not implemented error

我在使用 cppwinrt 时遇到错误。当我使用 CryptographicEngine::SignHashedData 函数对哈希值进行签名时,它 returns WinRT 产生错误 - 0x80004001 : 'not implemented'.

代码如下:

#include "pch.h"

using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Security::Cryptography;
using namespace Windows::Security::Cryptography::Core;
using namespace Windows::Storage::Streams;
using namespace std;

int main()
{
    init_apartment();
    IBuffer buffKeyPair; 
    IBuffer buffPublicKey;
    IBuffer nullBuff(nullptr);
    uint32_t asymmetricKeyLength = 512;
    hstring strMsg = L"zzp yes!";
    hstring strAsymmetricAlgName = AsymmetricAlgorithmNames::RsaPkcs1();
    hstring strAlgNameH = HashAlgorithmNames::Md5();
    AsymmetricKeyAlgorithmProvider objAlgProv = AsymmetricKeyAlgorithmProvider::OpenAlgorithm(strAsymmetricAlgName);
    CryptographicKey keyPair = objAlgProv.CreateKeyPair(asymmetricKeyLength);
    IBuffer buffUtf8Msg = CryptographicBuffer::ConvertStringToBinary(strMsg, BinaryStringEncoding::Utf8);
    HashAlgorithmProvider objAlgH = HashAlgorithmProvider::OpenAlgorithm(strAlgNameH);
    IBuffer buffHash = objAlgH.HashData(buffUtf8Msg);
    IBuffer signedBuff = CryptographicEngine::SignHashedData(keyPair, buffHash);
    hstring strHashHex = CryptographicBuffer::EncodeToHexString(signedBuff);
    std::cout << "the strHashHex is: " << winrt::to_string(strHashHex) << std::endl;
}

你能帮我找到问题吗?谢谢!

我在这方面经验不多 space,但我想我解决了几个问题。发生这种情况是因为您没有使用可用于签名的算法,也没有使用与其兼容的哈希算法。在这方面,文档似乎有点...稀疏...,但其中包含“sign”的算法名称看起来很有希望。

经过一些试验后,我成功了。

using namespace Windows::Security::Cryptography;
using namespace Windows::Security::Cryptography::Core;
using namespace Windows::Storage::Streams;
using namespace std;

int main()
{
    init_apartment();

    auto algo_name = AsymmetricAlgorithmNames::RsaSignPkcs1Sha1();
    auto asymmetric_provider = AsymmetricKeyAlgorithmProvider::OpenAlgorithm(algo_name);
    auto keyPair = asymmetric_provider.CreateKeyPair(512);

    auto md5_hasher = HashAlgorithmProvider::OpenAlgorithm(HashAlgorithmNames::Sha1());
    auto buffHash = md5_hasher.HashData(
        CryptographicBuffer::ConvertStringToBinary(
            L"Hello world", BinaryStringEncoding::Utf8));
    auto signature = CryptographicEngine::SignHashedData(keyPair, buffHash);

    auto publicKey = asymmetric_provider.ImportPublicKey(keyPair.ExportPublicKey());
    auto match = CryptographicEngine::VerifySignatureWithHashInput(
        publicKey, buffHash, signature);
}

注意我使用了RsaSignPkcs1Sha1,这似乎表明该算法可以进行签名。另外,对于哈希算法,我使用了Sha1。使用 Md5 给出了不同的运行时错误(而且 Md5 非常弱,无论如何)。我还添加了代码来展示如何使用您的密钥对的 public 密钥来验证签名。

在尝试你的代码和更多测试后,我发现当你想要对内容进行签名时,需要 RsaSignPkcs1Sha1,RsaPkcs1 不支持签名。此外,我发现 Windows 仅支持使用 SHA 哈希进行 RSA 签名,不支持对 md5 哈希进行签名。此外,这两个名称(RsaSignPkcs1Sha1 和 Sha1)必须匹配,否则您将遇到错误。我不知道它在后面是如何工作的。我还发现用 sign 函数对内容进行签名等同于用 SignHashedData 函数对内容的哈希进行签名,似乎 sign 函数在签名之前先计算哈希。