Форум КриптоПро
»
Средства криптографической защиты информации
»
КриптоПро .NET
»
Помогите реализовать ЭЦП, с помощью приобритенного КриптоПро Sharpei
Статус: Участник
Группы: Участники
Зарегистрирован: 12.01.2012(UTC) Сообщений: 19 Откуда: Kazan RF
|
Добрый день! Подскажите пожалуйста. Инфа из документации: Цитата:ЭЦП формируется согласно требованиям ГОСТ Р 34.10-2001 ("Информационная технология. Криптографическая защита информации. Процессы формирования и проверки электронной цифровой подписи") и ГОСТ Р 34.11-94 ("Информационная технология. Криптографическая защита информации. Функция хэширования"). Программный продукт КриптоПро CSP 2.0 компании КриптоПро удовлетворяет указанным условиям. ЭЦП представляет собой строку, закодированную в BASE64 (RFC3548). в старом варианте было реализовано так: Код: string retVal = "";
IntPtr hCryptoProvider = IntPtr.Zero;
IntPtr hPubKey = IntPtr.Zero;
IntPtr hHash = IntPtr.Zero;
...
if (!Crypt32Wrapper.CryptAcquireContext(out hCryptoProvider, containerName, null, TYPE, 0))
...
int code = Crypt32Wrapper.CryptGetUserKey(hCryptoProvider, Crypt32Wrapper.AT_SIGNATURE, ref hPubKey);
...
if (!Crypt32Wrapper.CryptCreateHash(hCryptoProvider, CERT_ALG_ID, IntPtr.Zero, 0, out hHash))
...
byte[] buffer = encoding.GetBytes(toSign);
if (!Crypt32Wrapper.CryptHashData(hHash, buffer, buffer.Length, 0))
...
uint signatureLength = 0;
if (!Crypt32Wrapper.CryptSignHash(hHash, Crypt32Wrapper.AT_KEYEXCHANGE, null, 0, null, ref signatureLength))
...
byte[] signature = new byte[signatureLength];
if (!Crypt32Wrapper.CryptSignHash(hHash, Crypt32Wrapper.AT_KEYEXCHANGE, null, 0, signature, ref signatureLength))
retVal = Convert.ToBase64String(signature, 0, (int)signatureLength);
Делаю так 1. Код:Gost3410CryptoServiceProvider prov = (Gost3410CryptoServiceProvider)certificate.PrivateKey;
SecureString s = new SecureString();
// заполняем пароль... например так
s.AppendChar('1');
// и передаем его в провайдер.
prov.SetContainerPassword(s);
2. Цитата: // Открываем файл и вычисляем хеш-функцию, ( в дальнейшем просто стрим планирую использовать) using (FileStream inStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read)) { myhash.ComputeHash(inStream); }
// Получаем подсчитанное значение хеш-функции. byte[] hashValue = myhash.Hash; 3. //подписываю prov.SignHash(myhash.Hash); Все этого достаточно? или есть еще какие подводные камни? Отредактировано пользователем 12 марта 2012 г. 14:16:29(UTC)
| Причина: Не указана
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 12.01.2012(UTC) Сообщений: 19 Откуда: Kazan RF
|
Формирование эцп похоже заработало, а вот с проверкой трудности. ЭЦП проверяется публичным ключом отправителя. У меня есть сертификат с сервера с публичным ключом. У Gost3410CryptoServiceProvider вижу функцию VerifySignature, в принципе понимаю как ее использовать. Подскажите, пожалуйста, как создать Gost3410CryptoServiceProvider без приватного ключа!? или куда капать. Раньше делалось так. Сейчас хочу сертификат брать из хранилища, а не из файла как в примере. Код: FileInfo fi = new FileInfo(serverCertFilePath);
uint certLen;
byte[] cert = new byte[fi.Length];
using (FileStream fs = File.OpenRead(serverCertFilePath))
{
certLen = (uint)fs.Read(cert, 0, (int)fi.Length);
fs.Close();
}
//hCertContext = Crypt32Wrapper.CertCreateCertificateContext(CryptoPro.CERT_ENCODING, cert, (uint)cert.Length);
hCertContext = Crypt32Wrapper.CertCreateCertificateContext( CryptoPro.PKCS_7_ASN_ENCODING | CryptoPro.X509_ASN_ENCODING, cert, (uint)cert.Length);
if (hCertContext == IntPtr.Zero)
{
...
}
Crypt32Wrapper.CryptAcquireContext(out hCryptoProvider, null, null, CryptoPro.TYPE, Crypt32Wrapper.CRYPT_VERIFYCONTEXT);
IntPtr pCertInfo = (IntPtr)Marshal.ReadInt32(hCertContext, 12);
IntPtr pSubjectPublicKeyInfo = (IntPtr)(pCertInfo.ToInt32() + 56);
Crypt32Wrapper.CryptImportPublicKeyInfo(hCryptoProvider, CryptoPro.CERT_ENCODING, pSubjectPublicKeyInfo, out hPubKey);
Crypt32Wrapper.CryptCreateHash(hCryptoProvider, (uint)CryptoPro.CERT_ALG_ID, IntPtr.Zero, 0, out hHash);
byte[] buffer = encoding.GetBytes(body);
Crypt32Wrapper.CryptHashData(hHash, buffer, buffer.Length, 0);
byte[] verifySignature = Convert.FromBase64String(signature);
retVal = Crypt32Wrapper.CryptVerifySignature(hHash, verifySignature, verifySignature.Length, hPubKey, null, 0);
Отредактировано пользователем 12 марта 2012 г. 18:45:02(UTC)
| Причина: Не указана
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,517   Сказал «Спасибо»: 555 раз Поблагодарили: 2252 раз в 1757 постах
|
а в SDK разве нет примеров проверки ЭЦП?
|
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 12.01.2012(UTC) Сообщений: 19 Откуда: Kazan RF
|
Примеров куча, вижу смотрю, но целой картины не вижу. Все примеры просты, там криптопровайдер используется как правило один и тот же для создания и проверки и как правило из приватного ключа или вообще без ключа. Тут сложность именно в использовании публичного ключа из сертификата. Как в примере что я привел выше. Подпись тоже формируется не верно говорят.
Помогите пожалуйста. Отредактировано пользователем 12 марта 2012 г. 19:41:37(UTC)
| Причина: Не указана
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 12.01.2012(UTC) Сообщений: 19 Откуда: Kazan RF
|
формирование ЭЦП заработало нормально после корректировки кодировки. Код: using (MemoryStream stream = new MemoryStream(encoding.GetBytes(body)))
{
myhash.ComputeHash(stream);
}
С проверкой вопрос остался открытым. Хелп.
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,517   Сказал «Спасибо»: 555 раз Поблагодарили: 2252 раз в 1757 постах
|
Roberto1 написал:формирование ЭЦП заработало нормально после корректировки кодировки. Код: using (MemoryStream stream = new MemoryStream(encoding.GetBytes(body)))
{
myhash.ComputeHash(stream);
}
С проверкой вопрос остался открытым. Хелп. как можно Хелп, если нет ни примеров ... файл+эцп, ни кода ... ? Или код из SDK не работает? Ваш экстрасенс (с) |
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 14.10.2011(UTC) Сообщений: 148  Поблагодарили: 31 раз в 30 постах
|
В чём проблема? Какая ошибка? Можете привести пример кода с ошибкой? Что конкретно не получается сделать? |
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 12.01.2012(UTC) Сообщений: 19 Откуда: Kazan RF
|
Простите если пишу не ясно, вот он вопрос.ЭЦП проверяется публичным ключом отправителя. У меня есть сертификат с сервера с публичным ключом. У Gost3410CryptoServiceProvider вижу функцию VerifySignature, в принципе понимаю как ее использовать. Но, как создать Gost3410CryptoServiceProvider без приватного ключа!? или куда капать.Раньше проверка ЭЦП делалось так. Сейчас хочу сертификат брать из хранилища, а не из файла как в примере. Код:
FileInfo fi = new FileInfo(serverCertFilePath);
uint certLen;
byte[] cert = new byte[fi.Length];
using (FileStream fs = File.OpenRead(serverCertFilePath))
{
certLen = (uint)fs.Read(cert, 0, (int)fi.Length);
fs.Close();
}
//hCertContext = Crypt32Wrapper.CertCreateCertificateContext(CryptoPro.CERT_ENCODING, cert, (uint)cert.Length);
hCertContext = Crypt32Wrapper.CertCreateCertificateContext( CryptoPro.PKCS_7_ASN_ENCODING | CryptoPro.X509_ASN_ENCODING, cert, (uint)cert.Length);
if (hCertContext == IntPtr.Zero)
{
...
}
Crypt32Wrapper.CryptAcquireContext(out hCryptoProvider, null, null, CryptoPro.TYPE, Crypt32Wrapper.CRYPT_VERIFYCONTEXT);
IntPtr pCertInfo = (IntPtr)Marshal.ReadInt32(hCertContext, 12);
IntPtr pSubjectPublicKeyInfo = (IntPtr)(pCertInfo.ToInt32() + 56);
Crypt32Wrapper.CryptImportPublicKeyInfo(hCryptoProvider, CryptoPro.CERT_ENCODING, pSubjectPublicKeyInfo, out hPubKey);
Crypt32Wrapper.CryptCreateHash(hCryptoProvider, (uint)CryptoPro.CERT_ALG_ID, IntPtr.Zero, 0, out hHash);
byte[] buffer = encoding.GetBytes(body);
Crypt32Wrapper.CryptHashData(hHash, buffer, buffer.Length, 0);
byte[] verifySignature = Convert.FromBase64String(signature);
retVal = Crypt32Wrapper.CryptVerifySignature(hHash, verifySignature, verifySignature.Length, hPubKey, null, 0);
Отредактировано пользователем 13 марта 2012 г. 15:18:12(UTC)
| Причина: Не указана
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 12.01.2012(UTC) Сообщений: 19 Откуда: Kazan RF
|
Затык был только в этом: Gost3410CryptoServiceProvider prov = (Gost3410CryptoServiceProvider)certificate2.PublicKey.Key;Все решилось, всех благодарю, работает: Код: Gost3410CryptoServiceProvider prov = (Gost3410CryptoServiceProvider)certificate2.PublicKey.Key;
// Создаем объект для хеширования.
HashAlgorithm myhash = HashAlgorithm.Create("GOST3411");
using (MemoryStream stream = new MemoryStream(encoding.GetBytes(body)))
{
myhash.ComputeHash(stream);
}
//проверим
return prov.VerifySignature(myhash.Hash, Convert.FromBase64String(signature));
|
|
|
|
Форум КриптоПро
»
Средства криптографической защиты информации
»
КриптоПро .NET
»
Помогите реализовать ЭЦП, с помощью приобритенного КриптоПро Sharpei
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close