C # - NET 4.0 - Криптография: обработка подписи и кодирование / декодирование с использованием SHA256 и PKCS # 10 - PullRequest
0 голосов
/ 06 сентября 2018

Я столкнулся с новой ситуацией, связанной с программой, написанной на .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 или я должен сделать что-нибудь еще? Спасибо, С уважением

...