【问题标题】:How to convert OID of a code-signing algorithm from CRYPT_ALGORITHM_IDENTIFIER to a human readable string?如何将代码签名算法的 OID 从 CRYPT_ALGORITHM_IDENTIFIER 转换为人类可读的字符串?
【发布时间】:2018-12-01 02:22:41
【问题描述】:

当我是来自 Windows 上的可执行文件的 retrieving a code signing signature 时,证书的 CERT_CONTEXT 指向 CERT_INFO,该 CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm 成员包含用于签名的算法。

如何将其转换为人类可读的形式?

例如,SignatureAlgorithm.pszObjId 可以设置为"1.2.840.113549.1.1.11" 字符串,根据this long listszOID_RSA_SHA256RSA。我想我可以为它做一个很长的 switch 语句,并将它链接到"sha256",但我宁愿避免它,因为我不知道这些值中的大多数是什么。是否有 API 可以为我完成所有这些工作?

【问题讨论】:

    标签: c++ winapi code-signing digital-certificate


    【解决方案1】:

    扩展answer of Anders。您还可以从调用WinVerifyTrust() 的结果中获取此信息。它深深嵌套在CRYPT_PROVIDER_DATA

    GUID policyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
    WINTRUST_DATA trustData;
    // omitted: prepare trustData
    
    DWORD lStatus = ::WinVerifyTrust( NULL, &policyGUID, &trustData );
    
    if( lStatus == ERROR_SUCCESS )
    {
        CRYPT_PROVIDER_DATA* pData = ::WTHelperProvDataFromStateData( trustData.hWVTStateData ); 
    
        if( pData && pData->pPDSip && pData->pPDSip->psIndirectData && 
            pData->pPDSip->psIndirectData->DigestAlgorithm.pszObjId )
        {
            CRYPT_ALGORITHM_IDENTIFIER const& sigAlgo = pData->pPDSip->psIndirectData->DigestAlgorithm;
    
            PCCRYPT_OID_INFO pCOI = ::CryptFindOIDInfo( CRYPT_OID_INFO_OID_KEY, sigAlgo.pszObjId, 0 ); 
    
            if(pCOI && pCOI->pwszName)
            {
                _tprintf(_T("%ls"), pCOI->pwszName);
            }
            else
            {
                _tprintf(_T("%hs"), sigAlgo.pszObjId);
            }
        }
    }
    

    注意:为简洁起见,省略了详细的错误检查!

    注意2:从 Win 8 开始(以及修补的 Win 7),WinVerifyTrust 可用于验证和获取有关文件的多个签名的信息,this Q&A 中的更多信息。

    【讨论】:

      【解决方案2】:

      使用CryptFindOIDInfo 获取有关OID 的信息,包括显示名称和CNG 算法标识符字符串:

      void PrintSigAlgoName(CRYPT_ALGORITHM_IDENTIFIER* pSigAlgo)
      {
          if(pSigAlgo && pSigAlgo->pszObjId)
          {
              PCCRYPT_OID_INFO pCOI = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, pSigAlgo->pszObjId, 0);
              if(pCOI && pCOI->pwszName)
              {
                  _tprintf(_T("%ls"), pCOI->pwszName);
              }
              else
              {
                  _tprintf(_T("%hs"), pSigAlgo->pszObjId);
              }
          }
      }
      

      【讨论】:

      • 谢谢。有效。尽管为该函数提供一个代码示例会很好。准确地了解如何使用它并不容易。要从我上面编辑的答案中复制它,我会在此处标记它吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-31
      • 2013-02-21
      • 1970-01-01
      • 1970-01-01
      • 2012-03-25
      相关资源
      最近更新 更多