Статус: Новичок
Группы: Участники
Зарегистрирован: 11.08.2020(UTC) Сообщений: 4
Сказал(а) «Спасибо»: 1 раз Поблагодарили: 2 раз в 1 постах
|
Добрый день! Задача проверить подпись маркера доступа ЕСИА. Документация говорит: Цитата:.... Части маркера разделены точкой, так что он имеет вид: HEADER.PAYLOAD.SIGNATURE Маркер передается в виде строки в формате Base64url64 ....
.... в настоящее время в ЕСИА поддерживается алгоритм электронной подписи ГОСТ Р 34.10-2012 (соответствует значению “GOST3410_2012_512”). ....
.... В общем виде эта процедура включает в себя следующие шаги: 1. Осуществление base64url-декодирования первых двух частей маркера. В header указан алгоритм шифрования (параметр alg). 2. Третья часть маркера доступа представляет собой подпись в кодировке UTF-8 от значений первых двух частей маркера доступа (HEADER.PAYLOAD). Необходимо осуществить проверку данной электронной подписи с использованием сертификата ключа проверки электронной подписи ЕСИА. 3. Проверка времени выдачи, начала и прекращения маркера. 4. Проверка организации, выпустившей маркер, а также адресата маркера. .....
Реализую проверку по пункту №2 так: Цитата:byte[] messageBytes = Encoding.UTF8.GetBytes(Base64UrlEncoder.Decode(message.Split(new[] { '.'})[0]) +"."+ Base64UrlEncoder.Decode(message.Split(new[] { '.' })[1])); byte[] signatureBytes = Base64UrlEncoder.DecodeBytes(signature); var content = new ContentInfo(messageBytes); var signedCms = new SignedCms(content, true);
signedCms.Decode(signatureBytes); // здесь получаю ошибку "ASN1 bad tag value met." signedCms.CheckSignature(certificates, true);
token.txt (1kb) загружен 28 раз(а).прикреплен пример токена в текстовом виде. Пробовал также через csptest утилиту, тоже ничего не вышло. Capture.PNG (25kb) загружен 31 раз(а).Коллеги, что делаю не так?
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,322 Сказал «Спасибо»: 549 раз Поблагодарили: 2208 раз в 1723 постах
|
Здравствуйте.
Там не CMS, а RAW подпись (само значение). Нужно использовать низкоуровневый интерфейс работы с CSP (передавать значение подписи\открытый ключ).
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,322 Сказал «Спасибо»: 549 раз Поблагодарили: 2208 раз в 1723 постах
|
Создание подписи: Цитата: csptest -keys -cont "HDIMAGE\\Контейнер" -sign GOST12_256 -keytype exchange -in файл.ext -out файл.ext.rawsign
Проверка подписи: Цитата: csptest -keys -verify GOST12_256 -in файл.ext -signature файл.ext.rawsign -cert raw.cer
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,322 Сказал «Спасибо»: 549 раз Поблагодарили: 2208 раз в 1723 постах
|
В КриптоПРО.NET SDK смотреть
C:\Program Files (x86)\Crypto Pro\.NET SDK\Examples\simple.zip\Sign\cs\ |
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,322 Сказал «Спасибо»: 549 раз Поблагодарили: 2208 раз в 1723 постах
|
Можете прислать пример токена и сертификат (в ЛС)? |
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 11.08.2020(UTC) Сообщений: 4
Сказал(а) «Спасибо»: 1 раз Поблагодарили: 2 раз в 1 постах
|
Автор: Андрей * Можете прислать пример токена и сертификат (в ЛС)? В личку отправить не могу, прикрепляю файлы, а они не прикрепляются. Ссылка на сервтификат https://esia.gosuslugi.ru/public/esia.zip имя ГОСТ ТЕСИА 2012.cer Токен я прикреплял выше. Я пробовал так ранее Цитата: private static bool VerifyRawSignString(string message, string signature, X509Certificate2Collection certificates) { byte[] messageBytes = Encoding.UTF8.GetBytes(Base64UrlEncoder.Decode(message.Split(new[] { '.' })[0]) + "." + Base64UrlEncoder.Decode(message.Split(new[] { '.' })[1])); byte[] signatureBytes = Base64UrlEncoder.DecodeBytes(signature);
Gost3411_2012_256CryptoServiceProvider GostHash = new Gost3411_2012_256CryptoServiceProvider(); var csp = (Gost3410_2012_256CryptoServiceProvider)certificates[0].PublicKey.Key; var res = csp.VerifyData(messageBytes, GostHash, signatureBytes); return res; }
Возвращает false.
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,322 Сказал «Спасибо»: 549 раз Поблагодарили: 2208 раз в 1723 постах
|
Цитата:2. Третья часть маркера доступа представляет собой подпись в кодировке UTF-8 от значений первых двух частей маркера доступа (HEADER.PAYLOAD). Варианты: 1. HEADER.PAYLOAD - как 2 строки через точку: Цитата: {"ver":1,"typ":"JWT","sbt":"access","alg":"GOST3410_2012_256"}.{"текст из PAYLOAD"}
2. HEADER.PAYLOAD - как 2 строки из токена, т.е. base64 Открываю https://jwt.io/ справа написано, как пример: ( base64UrlEncode(header) + "." + base64UrlEncode(payload) ) т.е. вычисляется от значений (base64.base64) => и проверять тоже нужно также |
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,322 Сказал «Спасибо»: 549 раз Поблагодарили: 2208 раз в 1723 постах
|
Автор: PeterPan Автор: Андрей * Можете прислать пример токена и сертификат (в ЛС)? В личку отправить не могу, прикрепляю файлы, а они не прикрепляются. Ссылка на сервтификат https://esia.gosuslugi.ru/public/esia.zip имя ГОСТ ТЕСИА 2012.cer Токен я прикреплял выше. Я пробовал так ранее Цитата: private static bool VerifyRawSignString(string message, string signature, X509Certificate2Collection certificates) { byte[] messageBytes = Encoding.UTF8.GetBytes(Base64UrlEncoder.Decode(message.Split(new[] { '.' })[0]) + "." + Base64UrlEncoder.Decode(message.Split(new[] { '.' })[1])); byte[] signatureBytes = Base64UrlEncoder.DecodeBytes(signature);
Gost3411_2012_256CryptoServiceProvider GostHash = new Gost3411_2012_256CryptoServiceProvider(); var csp = (Gost3410_2012_256CryptoServiceProvider)certificates[0].PublicKey.Key; var res = csp.VerifyData(messageBytes, GostHash, signatureBytes); return res; }
Возвращает false. signatureBytes - переверните байты и подпись будет проходить проверку |
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,322 Сказал «Спасибо»: 549 раз Поблагодарили: 2208 раз в 1723 постах
|
Ваш токен прошёл проверку В архиве - перевернутая подпись. TestESIA.zip (3kb) загружен 27 раз(а).token.txt.extracted - HEADER.PAYLOAD (две строки в base64 с точкой, как разделитель) token.txt.extracted.sign.raw.reverse.all - перевернутая подпись |
|
3 пользователей поблагодарили Андрей * за этот пост.
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 11.08.2020(UTC) Сообщений: 4
Сказал(а) «Спасибо»: 1 раз Поблагодарили: 2 раз в 1 постах
|
Огромное спасибо за наводку! Делюсь работающим кодом. Цитата: /// <summary> /// Проверка подписи JWT в формате HEADER.PAYLOAD.SIGNATURE. /// </summary> /// <param name="message">HEADER.PAYLOAD в формате Base64url</param> /// <param name="signature">SIGNATURE в формате Base64url</param> /// <param name="certificates">Сертификаты для проверки</param> /// <returns></returns> private static bool VerifyRawSignString(string message, string signature, X509Certificate2Collection certificates) { byte[] messageBytes = Encoding.UTF8.GetBytes(message); byte[] signatureBytes = Base64UrlEncoder.DecodeBytes(signature); Array.Reverse(signatureBytes, 0, signatureBytes.Length);
using (Gost3411_2012_256CryptoServiceProvider GostHash = new Gost3411_2012_256CryptoServiceProvider()) { var csp = (Gost3410_2012_256CryptoServiceProvider)certificates[0].PublicKey.Key; return csp.VerifyData(messageBytes, GostHash, signatureBytes); } }
|
2 пользователей поблагодарили PeterPan за этот пост.
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close