CSDN-Ada助手 2024-04-17 21:44 采纳率: 1.6%
浏览 5

微软的双数字签名,怎样全读出来 ?

该问题来自社区帖: https://bbs.csdn.net/topics/618480539.为符合问答规范, 该问题经过ChatGPT优化
<html><head><title>优化后的问题</title></head><body>

微软的双数字签名,怎样全读出来?

如图所示,PE文件有两个数字签名。

使用微软官网的示例代码,可以读出第一个数字签名。

可如何读出第二个数字签名呢?

怎样把两个数字签名全部读出呢?

涉及到的API:

  • CryptQueryObject
  • CryptMsgGetParam
  • CertFindCertificateInStore
</body></html>
  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-17 21:44
    关注

    引自免费微信小程序:皆我百晓生

    要读取PE文件中的双数字签名,你需要使用Windows API中的几个函数,特别是CryptQueryObjectCryptMsgGetParamCertFindCertificateInStore。这些函数通常在C++中使用,因为它们是低级别的系统调用。以下是一个简化的示例,展示了如何遍历证书列表以获取所有签名的相关信息。请注意,这个示例假设你已经包含了一些必要的头文件,如wincrypt.hwindows.h

    #include <windows.h>
    #include <wincrypt.h>
    #include <pdh.h>
    
    // 函数原型声明
    HCRYPTMSG GetNextSignature(HCRYPTMSG hCryptMsg, DWORD dwParamIndex);
    BOOL FindCertificateInStore(CertContext* pCertContext, HCERTSTORE hCertStore, DWORD dwCertStoreScope, DWORD dwCertStoreLocation);
    
    // 证书存储库句柄
    HCERTSTORE hCertStore = NULL;
    
    // 获取PE文件的哈希消息
    HCRYPTMSG hCryptMsg = CryptMsgOpenFromHash(hCryptHashHandle, X509_ASN_ENCODING, 0, 0, 0);
    
    if (hCryptMsg) {
        // 遍历签名列表
        while (hCryptMsg) {
            CERT_NAME_BLOB* pSubjectName = nullptr;
            DWORD dwType = 0;
            DWORD dwCertEncodingType = 0;
            DWORD dwParamIndex = 0;
            
            // 获取签名者的姓名
            if (CryptMsgGetParam(hCryptMsg, X509_NAME_PARAM, &dwParamIndex, &pSubjectName)) {
                // 处理姓名数据...
            }
            
            // 获取摘要算法
            if (CryptMsgGetParam(hCryptMsg, X509_ALGORITHM_ID_PARAM, &dwParamIndex, &dwCertEncodingType)) {
                DWORD dwAlgorithmId = 0;
                if (CryptDecodeObject(dwCertEncodingType, X509_ALGORITHM_IDENTIFIER, pSubjectName->pbData, pSubjectName->cbData, &dwAlgorithmId)) {
                    // 处理算法ID...
                }
            }
            
            // 获取时间戳
            if (CryptMsgGetParam(hCryptMsg, CMS_DATA_PARAM, &dwParamIndex, &dwCertEncodingType)) {
                PCCERT_TIMESTAMP timestamp = nullptr;
                if (CryptDecodeObject(dwCertEncodingType, CERT_TIMESTAMP, dwParamIndex, 0, &timestamp)) {
                    // 处理时间戳...
                }
            }
    
            // 获取下一个签名
            hCryptMsg = GetNextSignature(hCryptMsg, dwParamIndex);
        }
    
        // 关闭消息
        CryptMsgClose(hCryptMsg);
    }
    
    // 辅助函数获取下一个签名
    HCRYPTMSG GetNextSignature(HCRYPTMSG hCryptMsg, DWORD dwParamIndex) {
        // ...实现逻辑,递归获取下个签名...
        return hNextCryptMsg;
    }
    
    // 在这里,你需要根据需要定义一个CertContext结构,并实现FindCertificateInStore函数来查找特定的证书
    // 这部分通常涉及证书存储库(CertStore)的遍历,找到对应PE文件的证书
    
    int main() {
        // 初始化和打开存储库
        hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_STORE_OPEN_EXISTING, L"System");
    
        // 找到PE文件对应的证书
        CertContext certContext;
        if (FindCertificateInStore(&certContext, hCertStore, CERT_STORE_LOCAL_MACHINE, CERT_STORE_CURRENT_USER)) {
            // 现在你可以使用certContext处理签名...
        }
    
        // 关闭存储库
        CertCloseStore(hCertStore, 0);
    
        return 0;
    }
    

    请注意,这段代码只是一个基础框架,实际应用中可能需要根据PE文件的具体格式和签名结构进行调整。同时,处理证书数据时,可能需要对CERT_NAME_BLOBX509_ALGORITHM_IDENTIFIER等结构体进行解码,这通常涉及CryptDecodeObject函数。在实际操作中,你可能需要查阅MSDN文档以确保正确处理各种参数和数据类型。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 4月17日

悬赏问题

  • ¥17 pro*C预编译“闪回查询”报错SCN不能识别
  • ¥15 微信会员卡接入微信支付商户号收款
  • ¥15 如何获取烟草零售终端数据
  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?