gpt4 book ai didi

c# - 仅在Windows 2003 Server上指定了无效的算法

转载 作者:行者123 更新时间:2023-11-30 20:12:23 27 4
gpt4 key购买 nike

我正在使用以下方法解码文件:

string outFileName = zfoFileName.Replace(".zfo", "_tmp.zfo");
FileStream inFile = null;
FileStream outFile = null;
inFile = File.Open(zfoFileName, FileMode.Open);
outFile = File.Create(outFileName);
LargeCMS.CMS cms = new LargeCMS.CMS();
cms.Decode(inFile, outFile);


在我的Win 7开发人员计算机上,这可以正常工作,但是在Windows 2003 Server生产计算机上,它会失败,但出现以下异常:

异常:System.Exception:CryptMsgUpdate错误#-2146893816 ---> System.ComponentModel.Win32Exception:指定了无效的算法-内部异常堆栈跟踪的结尾-在LargeCMS.CMS.Decode(FileStream inFile,FileStream outFile)

以下是我调用进行解码的类,如果需要,我可以上传示例文件进行解码,这很奇怪,它只能在Win 7上运行,而不能在Win2k3服务器上运行:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace LargeCMS
{
class CMS
{
// File stream to use in callback function
private FileStream m_callbackFile;

// Streaming callback function for encoding
private Boolean StreamOutputCallback(IntPtr pvArg, IntPtr pbData, int cbData, Boolean fFinal)
{
// Write all bytes to encoded file
Byte[] bytes = new Byte[cbData];
Marshal.Copy(pbData, bytes, 0, cbData);
m_callbackFile.Write(bytes, 0, cbData);

if (fFinal)
{
// This is the last piece. Close the file
m_callbackFile.Flush();
m_callbackFile.Close();
m_callbackFile = null;
}

return true;
}



// Decode CMS with streaming to support large data
public void Decode(FileStream inFile, FileStream outFile)
{
// Variables
Win32.CMSG_STREAM_INFO StreamInfo;
Win32.CERT_CONTEXT SignerCertContext;

BinaryReader stream = null;
GCHandle gchandle = new GCHandle();

IntPtr hMsg = IntPtr.Zero;
IntPtr pSignerCertInfo = IntPtr.Zero;
IntPtr pSignerCertContext = IntPtr.Zero;
IntPtr pbPtr = IntPtr.Zero;
IntPtr hStore = IntPtr.Zero;
Byte[] pbData;
Boolean bResult = false;
int dwFileSize;
int dwRemaining;
int dwSize;
int cbSignerCertInfo;

try
{
// Get data to decode
dwFileSize = (int)inFile.Length;
stream = new BinaryReader(inFile);
pbData = stream.ReadBytes(dwFileSize);

// Prepare stream for decoded info
m_callbackFile = outFile;

// Populate Stream Info struct
StreamInfo = new Win32.CMSG_STREAM_INFO();
StreamInfo.cbContent = dwFileSize;
StreamInfo.pfnStreamOutput = new Win32.StreamOutputCallbackDelegate(StreamOutputCallback);

// Open message to decode
hMsg = Win32.CryptMsgOpenToDecode(
Win32.X509_ASN_ENCODING | Win32.PKCS_7_ASN_ENCODING,
0,
0,
IntPtr.Zero,
IntPtr.Zero,
ref StreamInfo
);
if (hMsg.Equals(IntPtr.Zero))
{
throw new Exception("CryptMsgOpenToDecode error #" + Marshal.GetLastWin32Error().ToString(), new Win32Exception(Marshal.GetLastWin32Error()));
}

// Process the whole message
gchandle = GCHandle.Alloc(pbData, GCHandleType.Pinned);
pbPtr = gchandle.AddrOfPinnedObject();
dwRemaining = dwFileSize;
dwSize = (dwFileSize < 1024 * 1000 * 100) ? dwFileSize : 1024 * 1000 * 100;
while (dwRemaining > 0)
{
// Update message piece by piece
bResult = Win32.CryptMsgUpdate(
hMsg,
pbPtr,
dwSize,
(dwRemaining <= dwSize) ? true : false
);
if (!bResult)
{
throw new Exception("CryptMsgUpdate error #" + Marshal.GetLastWin32Error().ToString(), new Win32Exception(Marshal.GetLastWin32Error()));
}

// Move to the next piece
pbPtr = new IntPtr(pbPtr.ToInt64() + dwSize);
dwRemaining -= dwSize;
if (dwRemaining < dwSize)
{
dwSize = dwRemaining;
}
}

// Get signer certificate info
cbSignerCertInfo = 0;
bResult = Win32.CryptMsgGetParam(
hMsg,
Win32.CMSG_SIGNER_CERT_INFO_PARAM,
0,
IntPtr.Zero,
ref cbSignerCertInfo
);
if (!bResult)
{
throw new Exception("CryptMsgGetParam error #" + Marshal.GetLastWin32Error().ToString(), new Win32Exception(Marshal.GetLastWin32Error()));
}

pSignerCertInfo = Marshal.AllocHGlobal(cbSignerCertInfo);

bResult = Win32.CryptMsgGetParam(
hMsg,
Win32.CMSG_SIGNER_CERT_INFO_PARAM,
0,
pSignerCertInfo,
ref cbSignerCertInfo
);
if (!bResult)
{
throw new Exception("CryptMsgGetParam error #" + Marshal.GetLastWin32Error().ToString(), new Win32Exception(Marshal.GetLastWin32Error()));
}

// Open a cert store in memory with the certs from the message
hStore = Win32.CertOpenStore(
Win32.CERT_STORE_PROV_MSG,
Win32.X509_ASN_ENCODING | Win32.PKCS_7_ASN_ENCODING,
IntPtr.Zero,
0,
hMsg
);
if (hStore.Equals(IntPtr.Zero))
{
throw new Exception("CertOpenStore error #" + Marshal.GetLastWin32Error().ToString(), new Win32Exception(Marshal.GetLastWin32Error()));
}

// Find the signer's cert in the store
pSignerCertContext = Win32.CertGetSubjectCertificateFromStore(
hStore,
Win32.X509_ASN_ENCODING | Win32.PKCS_7_ASN_ENCODING,
pSignerCertInfo
);
if (pSignerCertContext.Equals(IntPtr.Zero))
{
throw new Exception("CertGetSubjectCertificateFromStore error #" + Marshal.GetLastWin32Error().ToString(), new Win32Exception(Marshal.GetLastWin32Error()));
}

// Set message for verifying
SignerCertContext = (Win32.CERT_CONTEXT)Marshal.PtrToStructure(pSignerCertContext, typeof(Win32.CERT_CONTEXT));
bResult = Win32.CryptMsgControl(
hMsg,
0,
Win32.CMSG_CTRL_VERIFY_SIGNATURE,
SignerCertContext.pCertInfo
);
if (!bResult)
{
throw new Exception("CryptMsgControl error #" + Marshal.GetLastWin32Error().ToString(), new Win32Exception(Marshal.GetLastWin32Error()));
}
}
finally
{
// Clean up
if (gchandle.IsAllocated)
{
gchandle.Free();
}
if (!pSignerCertContext.Equals(IntPtr.Zero))
{
Win32.CertFreeCertificateContext(pSignerCertContext);
}
if (!pSignerCertInfo.Equals(IntPtr.Zero))
{
Marshal.FreeHGlobal(pSignerCertInfo);
}
if (!hStore.Equals(IntPtr.Zero))
{
Win32.CertCloseStore(hStore, Win32.CERT_CLOSE_STORE_FORCE_FLAG);
}
if (stream != null)
{
stream.Close();
}
if (m_callbackFile != null)
{
m_callbackFile.Close();
}
if (!hMsg.Equals(IntPtr.Zero))
{
Win32.CryptMsgClose(hMsg);
}
}
}
}
}




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.ComponentModel;
using System.Security.Cryptography;

namespace LargeCMS
{
class Win32
{
#region "CONSTS"

public const int X509_ASN_ENCODING = 0x00000001;
public const int PKCS_7_ASN_ENCODING = 0x00010000;
public const int CMSG_SIGNED = 2;
public const int CMSG_DETACHED_FLAG = 0x00000004;
public const int AT_KEYEXCHANGE = 1;
public const int AT_SIGNATURE = 2;
public const String szOID_OIWSEC_sha1 = "1.3.14.3.2.26";
public const int CMSG_CTRL_VERIFY_SIGNATURE = 1;
public const int CMSG_CERT_PARAM = 12;
public const int CMSG_SIGNER_CERT_INFO_PARAM = 7;
public const int CERT_STORE_PROV_MSG = 1;
public const int CERT_CLOSE_STORE_FORCE_FLAG = 1;

#endregion

#region "STRUCTS"

[StructLayout(LayoutKind.Sequential)]
public struct CRYPT_ALGORITHM_IDENTIFIER
{
public String pszObjId;
BLOB Parameters;
}

[StructLayout(LayoutKind.Sequential)]
public struct CERT_ID
{
public int dwIdChoice;
public BLOB IssuerSerialNumberOrKeyIdOrHashId;
}

[StructLayout(LayoutKind.Sequential)]
public struct CMSG_SIGNER_ENCODE_INFO
{
public int cbSize;
public IntPtr pCertInfo;
public IntPtr hCryptProvOrhNCryptKey;
public int dwKeySpec;
public CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
public IntPtr pvHashAuxInfo;
public int cAuthAttr;
public IntPtr rgAuthAttr;
public int cUnauthAttr;
public IntPtr rgUnauthAttr;
public CERT_ID SignerId;
public CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm;
public IntPtr pvHashEncryptionAuxInfo;
}

[StructLayout(LayoutKind.Sequential)]
public struct CERT_CONTEXT
{
public int dwCertEncodingType;
public IntPtr pbCertEncoded;
public int cbCertEncoded;
public IntPtr pCertInfo;
public IntPtr hCertStore;
}

[StructLayout(LayoutKind.Sequential)]
public struct BLOB
{
public int cbData;
public IntPtr pbData;
}

[StructLayout(LayoutKind.Sequential)]
public struct CMSG_SIGNED_ENCODE_INFO
{
public int cbSize;
public int cSigners;
public IntPtr rgSigners;
public int cCertEncoded;
public IntPtr rgCertEncoded;
public int cCrlEncoded;
public IntPtr rgCrlEncoded;
public int cAttrCertEncoded;
public IntPtr rgAttrCertEncoded;
}

[StructLayout(LayoutKind.Sequential)]
public struct CMSG_STREAM_INFO
{
public int cbContent;
public StreamOutputCallbackDelegate pfnStreamOutput;
public IntPtr pvArg;
}

#endregion

#region "DELEGATES"

public delegate Boolean StreamOutputCallbackDelegate(IntPtr pvArg, IntPtr pbData, int cbData, Boolean fFinal);

#endregion

#region "API"

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern Boolean CryptAcquireContext(
ref IntPtr hProv,
String pszContainer,
String pszProvider,
int dwProvType,
int dwFlags
);

[DllImport("Crypt32.dll", SetLastError = true)]
public static extern IntPtr CryptMsgOpenToEncode(
int dwMsgEncodingType,
int dwFlags,
int dwMsgType,
ref CMSG_SIGNED_ENCODE_INFO pvMsgEncodeInfo,
String pszInnerContentObjID,
ref CMSG_STREAM_INFO pStreamInfo
);

[DllImport("Crypt32.dll", SetLastError = true)]
public static extern IntPtr CryptMsgOpenToDecode(
int dwMsgEncodingType,
int dwFlags,
int dwMsgType,
IntPtr hCryptProv,
IntPtr pRecipientInfo,
ref CMSG_STREAM_INFO pStreamInfo
);

[DllImport("Crypt32.dll", SetLastError = true)]
public static extern Boolean CryptMsgClose(
IntPtr hCryptMsg
);

[DllImport("Crypt32.dll", SetLastError = true)]
public static extern Boolean CryptMsgUpdate(
IntPtr hCryptMsg,
Byte[] pbData,
int cbData,
Boolean fFinal
);

[DllImport("Crypt32.dll", SetLastError = true)]
public static extern Boolean CryptMsgUpdate(
IntPtr hCryptMsg,
IntPtr pbData,
int cbData,
Boolean fFinal
);

[DllImport("Crypt32.dll", SetLastError = true)]
public static extern Boolean CryptMsgGetParam(
IntPtr hCryptMsg,
int dwParamType,
int dwIndex,
IntPtr pvData,
ref int pcbData
);

[DllImport("Crypt32.dll", SetLastError = true)]
public static extern Boolean CryptMsgControl(
IntPtr hCryptMsg,
int dwFlags,
int dwCtrlType,
IntPtr pvCtrlPara
);

[DllImport("advapi32.dll", SetLastError = true)]
public static extern Boolean CryptReleaseContext(
IntPtr hProv,
int dwFlags
);

[DllImport("Crypt32.dll", SetLastError = true)]
public static extern IntPtr CertCreateCertificateContext(
int dwCertEncodingType,
IntPtr pbCertEncoded,
int cbCertEncoded
);

[DllImport("Crypt32.dll", SetLastError = true)]
public static extern Boolean CertFreeCertificateContext(
IntPtr pCertContext
);

[DllImport("Crypt32.dll", SetLastError = true)]
public static extern IntPtr CertOpenStore(
int lpszStoreProvider,
int dwMsgAndCertEncodingType,
IntPtr hCryptProv,
int dwFlags,
IntPtr pvPara
);

[DllImport("Crypt32.dll", SetLastError = true)]
public static extern IntPtr CertGetSubjectCertificateFromStore(
IntPtr hCertStore,
int dwCertEncodingType,
IntPtr pCertId
);

[DllImport("Crypt32.dll", SetLastError = true)]
public static extern IntPtr CertCloseStore(
IntPtr hCertStore,
int dwFlags
);

#endregion
}
}

最佳答案

您能否提供有关您的环境的更多信息。首先:哪个Service Pack具有Windows 2003 Server。例如,存在一个错误“ Web注册页面上的默认Diffie-Hellman SChannel证书选择导致错误:0x80090008-NTE_BAD_ALGID”,该错误已在SP3 http://support.microsoft.com/kb/324953/en中修复。如果不是您的问题,则应将证书和带有测试消息的二进制文件放在Web上的某个位置,然后在此处发布URL。这样一来,便可以重现并测试问题。

我想,要解决您的问题(如果在Windows Server 2003上安装了最后一个Service Pack),则必须更改签名消息的证书的某些属性。

我认为您通过证书使用SHA-2算法(SHA-256,SHA-384和SHA-512)不会。如果您确实使用了该工具并安装了最后一个Service Pack,则可能需要使用Windows上显式使用的“ Microsoft增强型RSA和AES加密提供程序”(或“ Microsoft增强型RSA和AES加密提供程序(原型)”)。 XP SP3)或PROV_RSA_AES或MS_ENH_RSA_AES_PROV,而不是默认的PROV_RSA_FULL提供程序。 (例如,参见http://blogs.msdn.com/alejacma/archive/2009/01/23/sha-2-support-on-windows-xp.aspx

更新1:
收到测试文件后,问题更加明显。首先是个好消息。您的程序正常运行!在带有SP2的测试Windows 2003服务器上,它可以正常工作。因此,我们有管理上的问题,而不是软件开发。我建议您在另一台Windows 2003 Server上测试该程序。在此服务器上,您可以重新安装SP2,然后转到Microsoft更新并安装所有更新。

顺便说一下,您对SHA256或其他SHA-2算法没有任何问题。您在示例中使用标准的1.2.840.113549.1.1.5 sha1RSA算法。

现在介绍您的程序。我阅读了详细的代码,并确切地了解了您的操作。您收到PKCS#7签名的消息,其中包含一个文本磁贴(一个XML文件)。我如何理解您的示例来自http://blogs.msdn.com/alejacma/archive/2010/04/09/how-to-call-cryptmsg-api-in-streaming-mode-c.aspx,其中描述了解密大于100MB的文件时出现的问题(另请参见http://blogs.msdn.com/alejacma/archive/2010/03/17/asn1-value-too-large-error-when-calling-signedcms-computesignature.aspx)。如果没有这种情况,建议您使用System.Security.Cryptography.Pkcs命名空间中的.NET加密功能。如果确实有大数据,则当前代码可以。唯一可疑的地方是读取输入文件。我不读取stream.ReadBytes()调用。我将使用更好的内存映射文件,而不是在内存中加载巨大的文件。要在本机代码中执行此操作,可以使用如下代码

DWORD MapFileInMemory (IN LPCWSTR pszFileName,
OUT PBYTE *ppbyFile, OUT PDWORD pdwFileSizeLow, OUT PDWORD pdwFileSizeHigh)
{
HANDLE hFile = INVALID_HANDLE_VALUE, hFileMapping = NULL;
DWORD dwStatus = (DWORD)E_UNEXPECTED;

__try {
// Open the input file to be encrypted or decrypted
hFile = CreateFileW (pszFileName, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
dwStatus = GetLastError();
__leave;
}

*pdwFileSizeLow = GetFileSize (hFile, pdwFileSizeHigh);
if (*pdwFileSizeLow == INVALID_FILE_SIZE){
dwStatus = GetLastError();
__leave;
}

hFileMapping = CreateFileMapping (hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (!hFileMapping){
dwStatus = GetLastError();
__leave;
}

*ppbyFile = (PBYTE) MapViewOfFile (hFileMapping, FILE_MAP_READ, 0, 0, 0);
if (*ppbyFile == NULL) {
dwStatus = GetLastError();
__leave;
}

dwStatus = NO_ERROR;
}
__finally {
if (hFileMapping)
CloseHandle (hFileMapping);

if (hFile != INVALID_HANDLE_VALUE)
CloseHandle (hFile);
}

return dwStatus;
}

BOOL UnmapFileFromMemory (LPCVOID lpBaseAddress)
{
return UnmapViewOfFile (lpBaseAddress);
}


编写相应的.NET代码将不是问题。使用“内存映射文件”仅创建到文件的虚拟地址映射,仅当您访问数据的相应部分时才会读取数据。

再说一遍。您的代码部分,用于验证消息是否完整。您需要做的是验证邮件签名所使用的证书。如果使用本机CryptoAPI,则可以针对 CertGetCertificateChain()执行此操作。只有这样,您才能确保证书及其所有父代都是有效的。您还应该针对 CertVerifyCertificateChainPolicy()验证证书链允许使用证书进行消息签名。

顺便说一下,当前代码可以正常工作而不会出现错误消息,但是用于签名消息的证书的颁发者是“ CN = PostSignum合格的CA,O =“Ceskápošta,s.p. [IC 47114983]“,C = CZ”,并且在您的消息内不存在已认证的证书。您可以使用例如 certutil.exe -dump 31602.zfo来查看详细信息:

Missing Issuer: CN=PostSignum Qualified CA, O="Ceská pošta, s.p. [IC 47114983]", C=CZ
Issuer: CN=PostSignum Qualified CA, O="Ceská pošta, s.p. [IC 47114983]", C=CZ
NotBefore: 03.12.2009 11:23
NotAfter: 03.12.2010 10:33
Subject: SERIALNUMBER=S7464, CN=Informacní systém datových schránek - zkušební prostredí, O="Ceská pošta, s.p. [IC 47114983]", C=CZ
Serial: 04d3c5
SubjectAltName: RFC822 Name=postsignum@cpost.cz, Other Name:Description=13 00
59 c7 20 ba 70 b1 e6 93 ea c4 83 4b 3c 1e 35 dc b9 15 f5 ff
A certificate chain could not be built to a trusted root authority. 0x800b010a (-2146762486)


可能您不想将任何已签名的消息解释为有效。必须对证书进行验证。此外,在许多情况下,最好定义要允许签名者作为输入的发件人的来源范围。考虑一下。

更新2:您正确地在新的331879.zfo文件中使用了sha256RSA(1.2.840.113549.1.1.11)进行签名。尝试安装我喜欢的 http://support.microsoft.com/kb/968730/en
http://thehotfixshare.net/board/index.php?showtopic=12629&hl=968730
它是经过数字签名的文件。所以我必须安全。绝对确定您可以从Microsoft获得此修复程序。我希望此修复程序可以解决您的问题。

更新3:我想更多关于您的代码示例。在我看来,要获得最佳实现,您应该将消息解码的整个代码实现为非托管(本机)代码。因此,您不会在解码大数据期间花费任何额外的时间在本机代码和托管代码之间进行封送处理。您应将此本地代码放在DLL中,并导出可以在主托管代码中使用的函数。

关于使用内存映射字段的另一条评论。内存映射文件的使用主要是通过优化方式来访问Windows中的任何文件以进行读写的。您必须知道的一件事是内存使用情况。如果查看任务管理器中的已用内存,您会发现程序已用内存映射文件技术会占用很大的内存。这根本不是问题。该内存不是物理内存,也不是分页文件中的分页内存。虚拟地址将直接映射到您在内存中映射的文件。因此,将针对文件数据本身进行数据分页。不需要操作系统的页面文件的其他部分。文件中的此I / O已针对相应的嵌入式处理器功能进行了优化和实现。

最终解决方案:因为我无法停止思考这个问题,所以我不得不解决它。这是完全基于我之前写过的解决方案。


您可以在带有Service Pack 2的Windows Server上安装补丁KB968730(请参见 http://support.microsoft.com/kb/968730/en)。可以从 http://thehotfixshare.net/board/index.php?showtopic=12629&hl=968730下载补丁。
在类Win32中添加以下行:


public const int PROV_RSA_AES = 24;
public const String MS_ENH_RSA_AES_PROV =
"Microsoft Enhanced RSA and AES Cryptographic Provider";
public const String MS_ENH_RSA_AES_PROV_XP =
"Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)";
public const int CRYPT_VERIFYCONTEXT = unchecked((int)0xF0000000U);


[StructLayout (LayoutKind.Sequential)]
public struct OSVERSIONINFOEX {
public int dwOSVersionInfoSize;
public int dwMajorVersion;
public int dwMinorVersion;
public int dwBuildNumber;
public int dwPlatformId;
[MarshalAs (UnmanagedType.ByValTStr, SizeConst = 128)]
public string szCSDVersion;
public short wServicePackMajor;
public short wServicePackMinor;
public short wSuiteMask;
public byte wProductType;
public byte wReserved;
}


[DllImport ("kernel32.dll")]
public static extern bool GetVersionEx (ref OSVERSIONINFOEX osVersionInfo);



修改 public void Decode(FileStream inFile, FileStream outFile)以在Windows Server 2003或XP上显式使用RSA和AES加密提供程序


// insert next line before of try block like after this line
IntPtr hStore = IntPtr.Zero;
IntPtr hProv = IntPtr.Zero;

//...
// insert Windows versions test before CryptMsgOpenToDecode like after this line
StreamInfo.pfnStreamOutput = new Win32.StreamOutputCallbackDelegate(StreamOutputCallback);

Win32.OSVERSIONINFOEX osVersionInfo = new Win32.OSVERSIONINFOEX ();
osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf (typeof (Win32.OSVERSIONINFOEX));
if (Win32.GetVersionEx (ref osVersionInfo)) {
Console.WriteLine ("dwMajorVersion={0}, dwMinorVersion={1}, wProductType={2}",
osVersionInfo.dwMajorVersion, osVersionInfo.dwMinorVersion, osVersionInfo.wProductType);
if (osVersionInfo.dwMajorVersion == 5 &&
(osVersionInfo.dwMinorVersion == 2 || osVersionInfo.dwMinorVersion == 1)) {
// Windows 2003 or XP
string provider = Win32.MS_ENH_RSA_AES_PROV;
if (osVersionInfo.dwMajorVersion == 5 && osVersionInfo.dwMinorVersion == 1)
provider = Win32.MS_ENH_RSA_AES_PROV_XP;
Win32.CryptAcquireContext (ref hProv, null, provider,
Win32.PROV_RSA_AES, Win32.CRYPT_VERIFYCONTEXT);
}
}

// Open message to decode
hMsg = Win32.CryptMsgOpenToDecode(
Win32.X509_ASN_ENCODING | Win32.PKCS_7_ASN_ENCODING,
0,
0,
hProv,
IntPtr.Zero,
ref StreamInfo
);



在针对CryptReleaseContext函数解码关闭句柄之后
//...
// insert CryptReleaseContext somewhere inside of finally block like after this line
if (!hMsg.Equals(IntPtr.Zero))
{
Win32.CryptMsgClose(hMsg);
}
if (hProv != IntPtr.Zero)
Win32.CryptReleaseContext (hProv, 0);



现在,该程序可以处理使用SHA-2算法签名的数据(例如使用1.2.840.113549.1.1.11 sha256RSA签名的331879.zfo)

我建议您不要忘记内存映射文件。如果使用.NET 4.0,则可以使用新的.NET框架类(请参见 http://msdn.microsoft.com/en-us/library/dd997372%28v=VS.100%29.aspx)。

关于c# - 仅在Windows 2003 Server上指定了无效的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2683867/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com