Авторизация на ЧестныйЗнак.РФ с помощью C#
Решил поделиться методом C# для авторизации на ЧестныйЗнак.РФ так как сам маялся с поиском нужной информации.
Ответы (2 шт):
Автор решения: MaxDown
→ Ссылка
using System.Collections.Generic;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.IO;
using System.Net;
using System;
using Newtonsoft.Json.Linq;
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;
namespace Check_SSCC
{
public partial class Form1 : Form
{
const String signerName = "*****@*****.***", //Константа для поиска сертификата, легче всего взять e-mail
client_secret = "********-****-****-****-************", //Взят из ЧЗ
client_id = "********-****-****-****-************", //Взят из ЧЗ
user_id = "****************************************", //Можно взять как на ЧЗ, так и самому посмотреть (отпечаток сертификата)
auth_type = "SIGNED_CODE"; //Взят из ЧЗ
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string MyToken = token();
. . . // Дальше делаем что хотели
}
private string token()
{
//code
dynamic stuff, stuff2;
string code_json, token_json;
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://api.mdlp.crpt.ru/api/v1/auth");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"client_secret\":\""+ client_secret + "\","+
"\"client_id\":\""+ client_id + "\","+
"\"user_id\":\""+ user_id + "\","+
"\"auth_type\":\""+ auth_type + "\"}";
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
code_json = streamReader.ReadToEnd();
stuff = JObject.Parse(code_json);
}
//signature
// Переводим исходное сообщение в массив байтов.
byte[] msgBytes = System.Text.Encoding.Unicode.GetBytes(Convert.ToString(stuff.code));
//Поиск сертификата
X509Certificate2 signerCert = GetSignerCert();
//создаем подпись
byte[] encodedSignature = SignMsg(msgBytes, signerCert);
string signature = Convert.ToBase64String(encodedSignature);
//token
var httpWebRequest2 = (HttpWebRequest)WebRequest.Create("https://api.mdlp.crpt.ru/api/v1/token");
httpWebRequest2.ContentType = "application/json";
httpWebRequest2.Method = "POST";
using (var streamWriter2 = new StreamWriter(httpWebRequest2.GetRequestStream()))
{
string json2 = "{\"code\":\"" + Convert.ToString(stuff.code) + "\",\"signature\":\"" + signature + "\"}";
streamWriter2.Write(json2);
}
var httpResponse2 = (HttpWebResponse)httpWebRequest2.GetResponse();
using (var streamReader2 = new StreamReader(httpResponse2.GetResponseStream()))
{
token_json = streamReader2.ReadToEnd();
stuff2 = JObject.Parse(token_json);
}
string token = Convert.ToString(stuff2.token);
return token;
}
// Открываем хранилище 'My' и ищем сертификат
// для подписи сообщения. Сертификат должен
// иметь поля Субъект (subject name) "*****@****.***".
static public X509Certificate2 GetSignerCert()
{
// Открываем хранилище My.
X509Store storeMy = new X509Store(StoreName.My, StoreLocation.CurrentUser);
storeMy.Open(OpenFlags.ReadOnly);
// Ищем сертификат для подписи.
X509Certificate2Collection certColl = storeMy.Certificates.Find(X509FindType.FindBySubjectName, signerName, false);
// Проверяем, что нашли требуемый сертификат
if (certColl.Count == 0)
{
MessageBox.Show("Сертификат не найден");
}
storeMy.Close();
// Если найдено более одного сертификата,
// возвращаем первый попавшийся.
return certColl[0];
}
// Подписываем сообщение секретным ключом.
static public byte[] SignMsg(Byte[] msg, X509Certificate2 signerCert)
{
// Создаем объект ContentInfo по сообщению.
// Это необходимо для создания объекта SignedCms.
ContentInfo contentInfo = new ContentInfo(msg);
// Создаем объект SignedCms по только что созданному
// объекту ContentInfo.
// SubjectIdentifierType установлен по умолчанию в
// IssuerAndSerialNumber.
// Свойство Detached устанавливаем явно в true, таким
// образом сообщение будет отделено от подписи.
SignedCms signedCms = new SignedCms(contentInfo, true);
// Определяем подписывающего, объектом CmsSigner.
CmsSigner cmsSigner = new CmsSigner(signerCert);
// Подписываем CMS/PKCS #7 сообщение.
signedCms.ComputeSignature(cmsSigner);
// Кодируем CMS/PKCS #7 подпись сообщения.
return signedCms.Encode();
}
}
}
Всё что Вам нужно, так:
- изменить константы;
- вставить
string MyToken = token()в своё событие; - скопировать к себе функции
private string token(),static public X509Certificate2 GetSignerCert()иstatic public byte[] SignMsg(Byte[] msg, X509Certificate2 signerCert); - Установить пакет Newtonsoft.Json (так парсить JSON легче, использовал его).
Автор решения: Rustam Ismagilov
→ Ссылка
Альтернативно на github есть хорошая библиотека yallie/MdlpClient для работы с МДЛП из C#, там не только авторизация, но и почти все выгрузки данных. Вот пример авторизации:
- Скачиваем библиотеку, подключаем отдельным проектом в солюшен
- Код:
var credentials = new ResidentCredentials
{
// ClientID и ClientSecret - GUID,
// в ЛК Честный знак они в строке в разделе Учётных систем
ClientID = ConfigurationManager.AppSettings["ClientID"],
ClientSecret = ConfigurationManager.AppSettings["ClientSecret"],
//отпечаток сертификата, чтобы найти открыть серт на компьтере
// -> поле Thumbprint
UserID = ConfigurationManager.AppSettings["UserID"]
};
_client = new MdlpClient(credentials: credentials);
var authToken = credentials.Authenticate(_client);
var token = authToken.Token;//получили токен для запросов
Не стал копировать сюда исходники библиотеки, можно разобраться как внутри работает. С библиотекой теперь это несколько строк.