Я столкнулся с новой ситуацией, связанной с программой, написанной на .NET Framework 4.0 / C #, которая должна кодировать / декодировать и подписывать сообщения для отправки / получения в определенном виде WAN.
Это текущий сценарий, который работает нормально.
У нас есть файл .p12 (который содержит сертификат отправителя) и файл .cer (который содержит сертификат получателя), которые оба установлены на компьютере.
Сценарий работает с использованием SHA1 и PKCS # 7 на 1024 бит, поэтому следующий фрагмент кода работает
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();
}
Как я уже говорил, этот код прекрасно работает в данном сценарии (SHA1 + PKCS # 7 на 1024 битах).
Теперь клиент запрашивает обновление криптографии, в частности, используя SHA256 вместо SHA1 и PKCS # 10 вместо PKCS # 7 с длиной ключа 2048 бит вместо 1024.
Согласно вашему опыту, что я должен сделать, чтобы получить новые требования?
Единственная вещь, в которой я уверен, - это то, что я не могу использовать NET Framework больше, чем этот, потому что устройства являются старыми XP, и их нельзя изменить из-за проблем компании. Поэтому я не могу использовать новые библиотеки, выпущенные для .NET 4.7.1, для решения моей проблемы.
Я предполагаю, что новые сертификаты будут выпущены как предыдущий метод, файл для отправителя, еще один для получателя, который будет установлен на машине.
Честно говоря, у меня не было большого опыта работы с крипто, и я хотел бы найти простой путь, который мог бы следовать логике текущих методов, поскольку тот факт, что их область действия не будет изменена, а только подход подписи.
У меня нет других ограничений в использовании других библиотек, пинвока и прочего, если это действительно может помочь.
Спасибо всем вам за поддержку
Любое предложение приветствуется.
Привет
ВАЖНОЕ ОБНОВЛЕНИЕ
У меня было разъяснение от национального агентства относительно того, что оно хочет.
Прежде всего, он пояснил, что # PKCS10 на 2048 бит относится к способу, которым запрашивается новый сертификат. Им нужны два запроса openssl с определенной парадигмой и генерируются два файла: файл .p12 (для отправителя, чтобы подписать сообщение), выпущенный с запросом PKCS # 10 на 2048 бит, и другой файл (я полагаю, что .cer файл) для приемника, для декодирования файлов.
В остальном они подтверждают переключение с SHA1 на SHA2.
Я буду продолжать общаться с ними, чтобы получить дополнительную информацию, но на основании того, что они объяснили, учитывая, что мне все равно придется устанавливать новые сертификаты на компьютер и использовать их для обычных действий, достаточно ли это изменить алгоритм от SHA1 (по умолчанию) до SHA2 или я должен сделать что-нибудь еще?
Спасибо, С уважением