Ключевое слово в защите информации
ключевое слово
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход. Новые регистрации запрещены.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Yura999  
#1 Оставлено : 21 августа 2014 г. 17:30:12(UTC)
Yura999

Статус: Новичок

Группы: Участники
Зарегистрирован: 09.07.2014(UTC)
Сообщений: 6
Российская Федерация
Откуда: Ижевск

Сказал(а) «Спасибо»: 1 раз
создаю подпись на клиенте через browser plugin, там же проверяю - всё ок.
передаю на сервер для проверки, а там ошибка "Неправильное значение хеша".
при этом в КриптоАРМ подпись успешно проверяется.

Код:

    function Sign() {        
        var oCertificate = oCertificates.Item(1);

        var oSigner = CreateObject("CAdESCOM.CPSigner");
        oSigner.TSAAddress = "https://www.cryptopro.ru/tsp/";
        oSigner.Certificate = oCertificate;
        oSigner.Options = CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN;
        
        var oHashedData = CreateObject("CAdESCOM.HashedData");
        oHashedData.Algorithm = CADESCOM_HASH_ALGORITHM_CP_GOST_3411;
        oHashedData.DataEncoding = CADESCOM_BASE64_TO_BINARY;  // вот это по-моему тут не нужно
        oHashedData.SetHashValue('@Model.Hash');
        
        var oSignedData = CreateObject("CAdESCOM.CadesSignedData");

        var sSignedMessage = "";
        try {
            sSignedMessage = oSignedData.SignHash(oHashedData, oSigner);
        } catch (err) {
            return;
        }
        
        var verifyResult = Verify(sSignedMessage);
        
         if (verifyResult.Result) {
            alert('ok');
        }
        else {
            alert('Ошибка проверки: ' + verifyResult.Error);
        }
    }
    
    function Verify(sSignedMessage) {
        var oHashedData = CreateObject("CAdESCOM.HashedData");
        oHashedData.Algorithm = CADESCOM_HASH_ALGORITHM_CP_GOST_3411;
        oHashedData.DataEncoding = CADESCOM_BASE64_TO_BINARY;
        oHashedData.SetHashValue('@Model.Hash');
        
        var oSignedData = CreateObject("CAdESCOM.CadesSignedData");
        
        // Проверяем подпись
        try {
            oSignedData.VerifyHash(oHashedData, sSignedMessage);
        } catch (err) {
            return { Result: false, Error: "Failed to verify signature. Error: " + GetErrorMessage(err)};
        }

        return { Result: true, Content: oSignedData.Content };
    }



на клиенте '@Model.Hash' = '6ADD02E91BDDFD8B0033A347D1EAD9D382674EC984FC50A38998F50ED1251EF1'
на сервере в originalData передается тот же самый массив байтов.
106, 221, 2, 233, 27, .. ,37 , 30, 241

Код:

        public bool VerifyData(byte[] originalData, byte[] signedData)
        {
            var signedCms = new SignedCms(new ContentInfo(originalData), true);
            try
            {
                signedCms.Decode(signedData);
            }
            catch(Exception e)
            {
                Logger.Log.Error("Signed CMS decode error", e);
                return false;
            }
            
            SignerInfoEnumerator enumerator = signedCms.SignerInfos.GetEnumerator();
            while (enumerator.MoveNext())
            {
                SignerInfo current = enumerator.Current;
                lastSigner = current;
                if (current.Certificate != null && current.Certificate.PublicKey != null 
                    && current.Certificate.PublicKey.Oid.Value != OID_GostR3410_2001_CryptoPro_PublicKey)
                {
                    return false;
                }
                
                try
                {
                    var cerBytes = File.ReadAllBytes(@"C:\myCert.cer");
                    var cer = new X509Certificate2(cerBytes);
                    
                    current.CheckSignature(new X509Certificate2Collection(cer), true); // вот тут ошибка "Неправильное значение хеша"
                }
                catch (System.Security.Cryptography.CryptographicException e)
                {
                    return false;
                }
            }
        }


я не понимаю что тут не так. весь день гугления не принес результатов.
Offline Yura999  
#2 Оставлено : 21 августа 2014 г. 17:39:09(UTC)
Yura999

Статус: Новичок

Группы: Участники
Зарегистрирован: 09.07.2014(UTC)
Сообщений: 6
Российская Федерация
Откуда: Ижевск

Сказал(а) «Спасибо»: 1 раз
сертификат читается с диска, потому что я не знаю как вытащить сертификат из неподписанного атрибута
OID_id_aa_ets_certValues = "1.2.840.113549.1.9.16.2.23" (AsnEncodedData).
Offline Yura999  
#3 Оставлено : 25 августа 2014 г. 9:32:24(UTC)
Yura999

Статус: Новичок

Группы: Участники
Зарегистрирован: 09.07.2014(UTC)
Сообщений: 6
Российская Федерация
Откуда: Ижевск

Сказал(а) «Спасибо»: 1 раз
Код:

            var cerBytes = File.ReadAllBytes(@"C:\abdula.cer");
            var cer = new X509Certificate2(cerBytes);

            Gost3410CryptoServiceProvider prov = (Gost3410CryptoServiceProvider)cer.PublicKey.Key;
            var b = prov.VerifyHash(originalData, signedData);
 

тоже возвращает false. по-моему уже всё перепробовал. не понимаю как сделать чтобы работало.
Offline overrorflow  
#4 Оставлено : 26 августа 2014 г. 10:49:16(UTC)
overrorflow

Статус: Новичок

Группы: Участники
Зарегистрирован: 26.08.2014(UTC)
Сообщений: 1
Российская Федерация
Откуда: Москва

Поблагодарили: 1 раз в 1 постах
Здравствуйте. Думаю это поможет.

Клиент:
Код:

function Sign(dataToSign) {
    var oCertificate = GetCertificateBySubjectName();

    var oSigner = CreateObject("CAdESCOM.CPSigner");
    oSigner.TSAAddress = "https://www.cryptopro.ru/tsp/";
    oSigner.Certificate = oCertificate;    

    var oHashedData = CreateObject("CAdESCOM.HashedData");
    oHashedData.Algorithm = CADESCOM_HASH_ALGORITHM_CP_GOST_3411;
    oHashedData.DataEncoding = CADESCOM_BASE64_TO_BINARY;  
    oHashedData.Hash(dataToSign); // dataToSign - это строка base64

    var oSignedData = CreateObject("CAdESCOM.CadesSignedData");

    var sSignedMessage = "";
    try {
        sSignedMessage = oSignedData.SignHash(oHashedData, oSigner, CADESCOM_CADES_BES);
    } catch (err) {
        return;
    }

    return sSignedMessage;   
}


Сервер:
Код:

 byte[] encodedSignedCms = Convert.FromBase64String(fs.FileSign); // fs.FileSign - отправленая строка из sSignedMessage
 using (FileStream sourceStream = File.Open(fs.FileNames.First(), FileMode.Open))
 {
		byte[] resultByte = new byte[sourceStream.Length];
    await sourceStream.ReadAsync(resultByte, 0, (int)sourceStream.Length);
  
    ContentInfo contentInfo = new ContentInfo(resultByte);

    SignedCms signedCms = new SignedCms(contentInfo, true);

    signedCms.Decode(encodedSignedCms);

    if (signedCms.SignerInfos.Count == 0)
    {
    	return BadRequest("Документ не подписан.");
    }

    bool valid = true;
    SignerInfo current = signedCms.SignerInfos[0];

    try
    {
    	current.CheckSignature(true);
    }
    catch (System.Security.Cryptography.CryptographicException e)
    {
    	valid = false;
    }


Если будут вопросы, то задавайте.
thanks 1 пользователь поблагодарил overrorflow за этот пост.
Yura999 оставлено 26.08.2014(UTC)
Offline Yura999  
#5 Оставлено : 26 августа 2014 г. 14:25:51(UTC)
Yura999

Статус: Новичок

Группы: Участники
Зарегистрирован: 09.07.2014(UTC)
Сообщений: 6
Российская Федерация
Откуда: Ижевск

Сказал(а) «Спасибо»: 1 раз
Автор: overrorflow Перейти к цитате
Здравствуйте. Думаю это поможет.
Если будут вопросы, то задавайте.

спасибо! только у меня CADESCOM_CADES_X_LONG_TYPE_1.
Получается я просто неправильно задавал ContentInfo. Я думал туда нужно записывать хэш, а оказалось нужны исходные данные.

Ну теперь осталось решить еще одну проблему.
Если предварительно не загрузить с диска сертификат и не передать его в параметре
current.CheckSignature(new X509Certificate2Collection(cer), true);
то будет ошибка "Не найден автор исходной подписи."

"Сертификаты для усовершенствованной подписи лежат в неподписанном атрибуте certificate-values:
id-aa-ets-certValues OBJECT IDENTIFIER ::= { iso(1) member-body(2)
us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) id-aa(2) 23}"

Осталось его оттуда вытащить.

Код:

const string OID_id_aa_ets_certValues = "1.2.840.113549.1.9.16.2.23";

                    foreach (var unsignedAttribute in current.UnsignedAttributes)
                    {
                        if (unsignedAttribute.Oid.Value == OID_id_aa_ets_certValues)
                        {
                            foreach (AsnEncodedData value in unsignedAttribute.Values)
                            {
                                System.IO.File.WriteAllBytes(@"C:\attr.bin", value.RawData);
                            }
                        }
                    }

Не могу понять как из него сделать X509Certificate2.
Вложение(я):
attr.zip (2kb) загружен 6 раз(а).

У Вас нет прав для просмотра или загрузки вложений. Попробуйте зарегистрироваться.
Offline Новожилова Елена  
#6 Оставлено : 26 августа 2014 г. 17:10:01(UTC)
Новожилова Елена

Статус: Сотрудник

Группы: Администраторы, Участники
Зарегистрирован: 10.12.2008(UTC)
Сообщений: 945
Женщина
Откуда: Крипто-Про

Поблагодарили: 117 раз в 106 постах
Offline Yura999  
#7 Оставлено : 26 августа 2014 г. 17:26:14(UTC)
Yura999

Статус: Новичок

Группы: Участники
Зарегистрирован: 09.07.2014(UTC)
Сообщений: 6
Российская Федерация
Откуда: Ижевск

Сказал(а) «Спасибо»: 1 раз
Автор: Новожилова Елена Перейти к цитате

это первое, что я попробовал. но так не получается. там сидит последовательность из трех сертификатов. их сначала надо разделить на части. очень не хочется писать свой парсер ASN.1. может есть способ проще?
Offline Yura999  
#8 Оставлено : 26 августа 2014 г. 17:43:15(UTC)
Yura999

Статус: Новичок

Группы: Участники
Зарегистрирован: 09.07.2014(UTC)
Сообщений: 6
Российская Федерация
Откуда: Ижевск

Сказал(а) «Спасибо»: 1 раз
Воспользовался LipingShare.LCLib.Asn1Parser
еще не читал что там с лицензией, но в целом всё получилось.
Код:

                                var parser = new Asn1Parser();
                                using (Stream stream = new MemoryStream(value.RawData))
                                {
                                    parser.LoadData(stream);
                                }
                                
                                for (var i = 0 ; i < parser.RootNode.ChildNodeCount; i++)
                                {
                                    var childNode = parser.RootNode.GetChildNode(i);
                                    var cer = new X509Certificate2(childNode.GetRawData());
                                    certCollection.Add(cer);
                                }

RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.