C++ WIN32上的JWT验证

C++ WIN32上的JWT验证,c++,winapi,jwt,wincrypt,C++,Winapi,Jwt,Wincrypt,我正在尝试使用WIN32加密函数验证RS512 JWT。我已经得到了公钥、要验证的数据以及内存数组中的签名数据。我能够创建证书上下文并导入公钥,但到目前为止我还不能验证签名。无论我尝试什么,我都会得到一个状态参数结果 我看过几篇关于必须反转部分或全部数据的帖子: 反转公钥可防止加载公钥 反转dataBuffer和signatureBuffer中的一个/两个仍然会导致状态\u无效\u参数 我错过了文档中说数据需要散列的部分。在对数据应用相同的散列(SHA512)之后,我能够验证签名。以下是工作代码

我正在尝试使用WIN32加密函数验证RS512 JWT。我已经得到了公钥、要验证的数据以及内存数组中的签名数据。我能够创建证书上下文并导入公钥,但到目前为止我还不能验证签名。无论我尝试什么,我都会得到一个状态参数结果

我看过几篇关于必须反转部分或全部数据的帖子:

  • 反转公钥可防止加载公钥
  • 反转dataBuffer和signatureBuffer中的一个/两个仍然会导致状态\u无效\u参数

  • 我错过了文档中说数据需要散列的部分。在对数据应用相同的散列(SHA512)之后,我能够验证签名。以下是工作代码减去错误检查:

    //Hash data here.
    auto hashedData = data.hash( HashType::SHA512 );
    
    auto signingKeyBuffer = signingKey.publicKeyBuffer();
    PCCERT_CONTEXT cryptCert = CertCreateCertificateContext( X509_ASN_ENCODING, signingKeyBuffer.getBuffer(), signingKeyBuffer.getSize() );
    if( cryptCert != nullptr )
    {
        BCRYPT_KEY_HANDLE cryptKey;
        if( BCRYPT_SUCCESS( CryptImportPublicKeyInfoEx2( X509_ASN_ENCODING, &cryptCert->pCertInfo->SubjectPublicKeyInfo, 0, nullptr, &cryptKey ) ) )
        {
            BCRYPT_PKCS1_PADDING_INFO pkcs1Info;
            pkcs1Info.pszAlgId = cNEHash::algorithmIdForHashType( cAlgorithmType::hashType( algorithm ) );
            auto status = BCryptVerifySignature( cryptKey, &pkcs1Info, hashedData.getBuffer(), hashedData.getSize(), signature.getBuffer(), signature.getSize(), BCRYPT_PAD_PKCS1 );
            if( BCRYPT_SUCCESS( status ) )
                verified = true;
            BCryptDestroyKey( cryptKey );
        }
        CertFreeCertificateContext( cryptCert );
    }
    

    颠倒。。这对于
    状态\u无效\u参数
    是毫无意义的。此错误是因为错误的标志
    BCRYPT\u PAD\u PKCS1
    +
    pPaddingInfo
    (对于椭圆曲线DSA,此值必须为0)或错误的长度(cbSignature)。如果签名错误-将是另一个错误-
    STATUS\u INVALID\u签名
    谢谢您的评论,您让我再次阅读文档。我错过了需要散列数据的部分。完成后,一切都按预期进行。是的,数据当然必须经过哈希运算,并从哈希中计算签名。但是,这在代码中不可见。还不清楚你得到了什么cryptAlg-你没有在代码中使用它你是正确的,我不需要有cryptAlg。
    //Hash data here.
    auto hashedData = data.hash( HashType::SHA512 );
    
    auto signingKeyBuffer = signingKey.publicKeyBuffer();
    PCCERT_CONTEXT cryptCert = CertCreateCertificateContext( X509_ASN_ENCODING, signingKeyBuffer.getBuffer(), signingKeyBuffer.getSize() );
    if( cryptCert != nullptr )
    {
        BCRYPT_KEY_HANDLE cryptKey;
        if( BCRYPT_SUCCESS( CryptImportPublicKeyInfoEx2( X509_ASN_ENCODING, &cryptCert->pCertInfo->SubjectPublicKeyInfo, 0, nullptr, &cryptKey ) ) )
        {
            BCRYPT_PKCS1_PADDING_INFO pkcs1Info;
            pkcs1Info.pszAlgId = cNEHash::algorithmIdForHashType( cAlgorithmType::hashType( algorithm ) );
            auto status = BCryptVerifySignature( cryptKey, &pkcs1Info, hashedData.getBuffer(), hashedData.getSize(), signature.getBuffer(), signature.getSize(), BCRYPT_PAD_PKCS1 );
            if( BCRYPT_SUCCESS( status ) )
                verified = true;
            BCryptDestroyKey( cryptKey );
        }
        CertFreeCertificateContext( cryptCert );
    }