如何从.NET中的SHA-256签名文件获取时间戳

问题描述

我写了一个实用程序来获取二进制文件的数字签名时间戳。该工具无法获取文件“ Microsoft.IdentityModel.Tokens.dll” v6.7.1.10630的时间戳。
该二进制文件似乎已使用SHA256签名。我试图用在该二进制文件中找到的替换Oid.value,但是未能转换为Pkcs9SigningTime类型。 如何更新代码以获得时间戳?
任何建议将不胜感激。

public static string getTimestamp(string filename)
{
    string strTimeStamp = string.Empty;
    try
    {
        int encodingType;
        int contentType;
        int formatType;
        IntPtr certStore = IntPtr.Zero;
        IntPtr cryptMsg = IntPtr.Zero;
        IntPtr context = IntPtr.Zero;

        if (!WinCrypt.CryptQueryObject(
            WinCrypt.CERT_QUERY_OBJECT_FILE,Marshal.StringToHGlobalUni(filename),WinCrypt.CERT_QUERY_CONTENT_FLAG_ALL,WinCrypt.CERT_QUERY_FORMAT_FLAG_ALL,out encodingType,out contentType,out formatType,ref certStore,ref cryptMsg,ref context))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }

        // Get size of the encoded message.
        int cbData = 0;
        if (!WinCrypt.CryptMsgGetParam(
            cryptMsg,WinCrypt.CMSG_ENCODED_MESSAGE,//Crypt32.CMSG_SIGNER_INFO_ParaM,IntPtr.Zero,ref cbData))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }

        var vData = new byte[cbData];

        // Get the encoded message.
        if (!WinCrypt.CryptMsgGetParam(
            cryptMsg,vData,ref cbData))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }

        var signedCms = new SignedCms();
        signedCms.Decode(vData);

        foreach (var signerInfo in signedCms.SignerInfos)
        {
            foreach (var unsignedAttribute in signerInfo.UnsignedAttributes)
            {
                if (unsignedAttribute.Oid.Value == "1.3.6.1.4.1.311.3.3.1")
                {
                    foreach (var signedAttribute in signerInfo.UnsignedAttributes)
                    {
                        if (signedAttribute.Oid.Value == "1.3.6.1.4.1.311.3.3.1")
                        {
                            Pkcs9AttributeObject obj = new Pkcs9AttributeObject(signedAttribute.Values[0]);
                            SignedCms rfcTimestampMessage = new SignedCms();
                            rfcTimestampMessage.Decode(obj.RawData);
                            rfcTimestampMessage.CheckSignature(true);

                            foreach(var timeStampSignerInfo in rfcTimestampMessage.SignerInfos)
                            {
                                foreach(var timeStampAttribute in timeStampSignerInfo.SignedAttributes)
                                {
                                    if (timeStampAttribute.Oid.Value == "1.2.840.113549.1.9.5")
                                    {
                                        Pkcs9SigningTime signingTime1 = (Pkcs9SigningTime)timeStampAttribute.Values[0];
                                        strTimeStamp = signingTime1.SigningTime.ToLocalTime().ToString();
                                    }
                                }
                            }

                        }
                    }
                }
            }
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }

    return strTimeStamp;
}

更新:
似乎与SHA256没有关系。二进制Microsoft.IdentityModel.Tokens.dll使用RFC3161作为时间戳。我可以使用SignTool获取以下消息:

Index Algorithm Timestamp
=========================
0     sha256      RFC3161

搜索Microsoft,我应该能够通过Rfc3161TimestampTokenInfo.Timestamp获取时间戳信息,但是.net Framework中没有此api。关于Rfc3161的另一个演示是here

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)