我正面临一种新情况,涉及一个用.NET Framework 4.0 / C#编写的程序,该程序必须对要在特定种类的WAN中发送/接收的消息进行编码/解码和签名。 这是当前方案,可以正常工作。 我们有一个.p12文件(包含发送者证书)和一个.cer文件(包含接收者证书),它们都安装在pc中。 该方案正在使用1024位SHA1和PKCS#7,因此下面的代码可以工作
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography;
using System.Windows;
using System.Windows.Controls;
using System.Collections;
private static string senderCert = "sendername"; //the name registered in .p12 file
private static string receiverCert = "receivername"; //the name registered in .cer file
/// <summary>
///verify that the receiving message is signed
///and returns the data without sign
/// </summary>
/// <param name="signedData">dataflow with sign</param>
/// <returns></returns>
public static byte[] Verify(this byte[] signedData)
{
X509Certificate2 certPub = GetReceiverCert();
if (certPub == null) return null;
ContentInfo decodeContentInfo = new ContentInfo(signedData);
SignedCms decodeCMS = new SignedCms(decodeContentInfo, false);
try
{
//decode the message, if it isn't signed, raise an exception
decodeCMS.Decode(signedData);
SignerInfo signerInfo = decodeCMS.SignerInfos[0];
X509Certificate2Collection certCollection = new
X509Certificate2Collection(certPub);
return decodeCMS.ContentInfo.Content;
}
catch (CryptographicException err)
{
Logger.Log(err);
return null;
}
}
/// <summary>
/// Returns the certificate used to sign the sending messages
/// </summary>
/// <returns></returns>
private static X509Certificate2 GetSenderCert()
{
//Open the personal certificates folder
X509Store storeMy = new X509Store(StoreName.My, StoreLocation.CurrentUser);
storeMy.Open(OpenFlags.ReadOnly);
//find the proper certificate
X509Certificate2Collection certColl = storeMy.Certificates.Find
(X509FindType.FindBySubjectName, senderCert, false);
//Check if certificate exists in the collection, otherwise returns null
if (certColl.Count == 0)
return null;
storeMy.Close();
return certColl[0];
}
/// <summary>
/// Returns the certificate used to control the sign of the receiving messages
/// </summary>
/// <returns></returns>
private static X509Certificate2 GetReceiverCert()
{
//Open personal certificates' folder
X509Store storeMy = new X509Store(StoreName.My,
StoreLocation.CurrentUser);
storeMy.Open(OpenFlags.ReadOnly);
//find the certificate use for this kind of messages
X509Certificate2Collection certColl = storeMy.Certificates.Find
(X509FindType.FindBySubjectName, receiverCert, false);
//Check if certificate exists in the collection, otherwise returns null
if (certColl.Count == 0)
return null;
storeMy.Close();
return certColl[0];
}
/// <summary>
/// Add a sign to the message
/// </summary>
/// <param name="data">message data flow</param>
/// <returns></returns>
public static byte[] Sign(this byte[] data)
{
X509Certificate2 certificate = GetSenderCert();
if (certificate == null) return null;
if (data == null)
throw new ArgumentNullException("data");
if (certificate == null)
throw new ArgumentNullException("certificate");
//Set the message to sign
ContentInfo content = new ContentInfo(data);
signedCms = new SignedCms(content, false);
CmsSigner signer = new CmsSigner(certificate);
signer.IncludeOption = X509IncludeOption.EndCertOnly;
//Create the sign
signedCms.ComputeSignature(signer);
return signedCms.Encode();
}
正如我之前所说,此代码在给定的情况下(1024位SHA1 + PKCS#7)可以正常工作。 现在,客户端要求更新密码,特别是使用 SHA256 代替SHA1和 PKCS#10 代替PKCS#7,密钥长度为2048位而不是1024。 / p>
根据您的经验,我应该怎么做才能获得新要求?
我唯一能确定的是,我不能使用大于此版本的NET Framework,因为这些设备是旧的XP,并且不能因公司问题而更改。因此,我不能使用为.NET 4.7.1发布的新库来解决我的问题。
我想新证书将作为以前的方法发布,即要安装在计算机中的发件人文件和发件人的文件。
老实说,我对加密没有太多的经验,我想找到一条可以遵循当前方法逻辑的简单方法,因为事实上它们的范围不会改变,而只是签名方法。
如果确实有帮助,我在使用其他库,pinvoke和其他东西方面没有其他限制。
感谢大家的支持 任何建议表示赞赏。 问候
重要更新
我想知道国家机构的要求。 首先,它阐明了2048位的#PKCS10是指请求新证书的方式。需要两个opensl请求(具有特定的范式),并生成两个文件:.p12文件(用于发件人,用于对消息进行签名),以PKCS#10请求以2048位发布,另一个文件(我假设是.cer)文件)以供接收器解码文件。
其余部分,他们确认从SHA1切换到SHA2。 我将继续与他们联系以获取更多信息,但是基于他们的解释,考虑到我仍然必须在计算机上安装新证书并将其用于常规操作,是否足以更改从SHA1(默认)到SHA2的算法,还是我应该做其他事情? 谢谢,问候