C# RSA/MD5数字签名-需要帮助使用CryptVerifySignature反转现有代码吗

C# RSA/MD5数字签名-需要帮助使用CryptVerifySignature反转现有代码吗,c#,C#,我继承了一个项目,该项目应该执行两个功能: 一种有效的数字签名方法 b.创建数字签名 我的难题是,我对验证/签名数字签名的了解不够。 我有验证代码,它的工作原理与预期一致。我正在努力重新创建签名部分 简言之,我们有大量的文件,体积小,里面存储着数字签名。例如,前150个字节特定于该公司,而剩余的字节属于数字签名,长度似乎总是0x40 以下是有效的验证代码: static readonly string pszContainer = "XXXXXXXX-XXXX-470f-XXXX-XXX

我继承了一个项目,该项目应该执行两个功能: 一种有效的数字签名方法 b.创建数字签名

我的难题是,我对验证/签名数字签名的了解不够。 我有验证代码,它的工作原理与预期一致。我正在努力重新创建签名部分

简言之,我们有大量的文件,体积小,里面存储着数字签名。例如,前150个字节特定于该公司,而剩余的字节属于数字签名,长度似乎总是0x40

以下是有效的验证代码:

    static readonly string pszContainer = "XXXXXXXX-XXXX-470f-XXXX-XXXXXXXXXXXX";
    static readonly string pszProvider = "Microsoft Base Cryptographic Provider v1.0";
    static readonly byte[] pbData = new byte[] { 0x0, 0x0, ....};

    static bool VerifiyFile(string lpFileName)
    {
        byte[] fileBytes = File.ReadAllBytes(lpFileName);
        byte[] pbSignature = new byte[0x40];
        Buffer.BlockCopy(fileBytes, fileBytes.Length - 0x40, pbSignature, 0, 0x40);

        if (InitialiseUpdateCryptoAPI())
        {
            IntPtr hProv = default(IntPtr);
            IntPtr hHash = default(IntPtr);
            IntPtr hPubKey = default(IntPtr);
            int bufferLen = (fileBytes.Length - 0x40);
            byte[] buffer = new byte[bufferLen];
            Buffer.BlockCopy(fileBytes, 0, buffer, 0, bufferLen);

            if (Crypto.CryptAcquireContext(ref hProv, pszContainer, pszProvider, Crypto.PROV_RSA_FULL, 0))
                if (Crypto.CryptImportKey(hProv, pbData, 0x54, default(IntPtr), 0, ref hPubKey))
                    if (Crypto.CryptCreateHash(hProv, Crypto.CALG_MD5, default(IntPtr), 0, ref hHash))
                        if (Crypto.CryptHashData(hHash, buffer, bufferLen, 0))
                            if (Crypto.CryptVerifySignature(hHash, pbSignature, 0x40, hPubKey, null, 0))
                                return true;

        }
        return false;
    }
从中,我学到了两件事,我们似乎一直期望签名的长度为0x40,到目前为止,它适用于我测试/验证过的一些文件,我们将Sig存储在文件特定数据的末尾

我确实删除了pszContainer和pbData的实际值,因为它们是特定于我们公司的

…就我的一生而言,我无法复制与现有文件签名匹配的签名;我试图做的是从一个现有文件中提取数据,减去有效的签名,然后尝试复制完全相同的签名

        IntPtr hCryptProv = IntPtr.Zero;
        IntPtr hKey = IntPtr.Zero;
        IntPtr hXchgKey = IntPtr.Zero;
        IntPtr hHash = IntPtr.Zero;

        byte[] pbSignature = new byte[] { ... };
        byte[] data = new byte[] { ... };

        int dwSignlen = pbSignature.Length;

        if (Crypto.CryptAcquireContext(ref hCryptProv, pszContainer, pszProvider, Crypto.PROV_RSA_FULL, 0))
            if (Crypto.CryptImportKey(hCryptProv, pbData, pbData.Length, IntPtr.Zero, 0, ref hXchgKey))
                if (Crypto.CryptCreateHash(hCryptProv, Crypto.CALG_MD5, IntPtr.Zero, 0, ref hHash))
                    if (Crypto.CryptHashData(hHash, data, data.Length, 0))
                        if (Crypto.CryptSignHash(hHash, Crypto.AT_SIGNATURE, null, 0, pbSignature, ref dwSignlen))
                            Console.WriteLine("pbSignature is the hash signature");

        Crypto.CryptDestroyHash(hHash);
        hHash = IntPtr.Zero;

…我不太了解这是如何工作的,因此无法理解哪里出了问题/遗漏了什么。我们解雇了实施这项计划的人,失去了大部分工作;FWIW,加密对象是wincrypt的一个实现

您无法生成安全的64字节RSA签名。这是一个512位的模数,即使是业余爱好者也很容易打破。当然,MD5的弱抗碰撞性通常也很危险。谢谢你的回复!我想我们缺少的是用来签署这些文件的私钥。从你的回答听起来——用暴力强迫我们回到私钥可能不太难——这听起来对吗?