Skip to content

Commit

Permalink
Replace System.Security.Cryptography.Pkcs by own ASN1
Browse files Browse the repository at this point in the history
  • Loading branch information
diev committed Jun 27, 2024
1 parent ed43765 commit 9a5d957
Show file tree
Hide file tree
Showing 8 changed files with 514 additions and 29 deletions.
438 changes: 438 additions & 0 deletions Api5704/ASN1.cs

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions Api5704/Api5704.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<RootNamespace>Api5704</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>8.2024.626</Version>
<Version>8.2024.627</Version>
<Company>diev</Company>
<Copyright>2022-2024 Dmitrii Evdokimov</Copyright>
<Description>Предоставление ССП при обращении пользователя к НБКИ как КБКИ-контрагенту в режиме «одного окна» по Указанию Банка России № 5704-У.</Description>
Expand All @@ -25,8 +25,4 @@
<DebugType>embedded</DebugType>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="8.0.0" />
</ItemGroup>

</Project>
24 changes: 16 additions & 8 deletions Api5704/ApiExtra.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,33 @@ public static class ApiExtra
/// Пакетная обработка папок с запросами (Extra).
/// </summary>
/// <param name="dir">Папка с исходными запросами.</param>
/// <param name="requests">Папка с готовыми запросами.</param>
/// <param name="results">Папка с готовыми результатами.</param>
/// <param name="answers">Папка с готовыми ответами.</param>
/// <param name="requests">Папка с отправленными запросами.</param>
/// <param name="results">Папка с полученными квитанциями.</param>
/// <param name="answers">Папка с полученными сведениями.</param>
public static async Task PostRequestFolderAsync(string dir, string requests, string results, string answers)
{
Directory.CreateDirectory(requests);
Directory.CreateDirectory(results);
Directory.CreateDirectory(answers);
if (!requests.Equals(string.Empty)) Directory.CreateDirectory(requests);
if (!results.Equals(string.Empty)) Directory.CreateDirectory(results);
if (!answers.Equals(string.Empty)) Directory.CreateDirectory(answers);

int count = 0;

foreach (var file in Directory.GetFiles(dir, "*.xml"))
{
byte[] data = File.ReadAllBytes(file);

if (data[0] == 0x30)
{
data = PKCS7.CleanSign(data);
//data = PKCS7.CleanSign(data);
data = await ASN1.CleanSignAsync(data);
}

XmlDocument doc = new();
doc.LoadXml(Encoding.UTF8.GetString(data));
string id = doc.DocumentElement!.GetAttribute("ИдентификаторЗапроса");

string date = DateTime.Now.ToString("yyyy-MM-dd");
string name = $"{date}.{id}";
string name = $"{Path.GetFileName(file)}.{date}.{id}";

string request = Path.Combine(results, name + ".request.xml");
string result = Path.Combine(results, name + ".result.xml");
Expand All @@ -64,9 +67,14 @@ public static async Task PostRequestFolderAsync(string dir, string requests, str
if (File.Exists(answer))
{
File.Delete(file);
count++;
}

Thread.Sleep(1000);
}

Console.WriteLine($"Сведений получено: {count}.");

Environment.Exit(0);
}
}
6 changes: 4 additions & 2 deletions Api5704/ApiHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ public class ApiHelper
await File.WriteAllBytesAsync(file + ".sig", data);

// Clean data
data = PKCS7.CleanSign(data);
//data = PKCS7.CleanSign(data);
data = await ASN1.CleanSignAsync(data);

// Write clean XML
await File.WriteAllBytesAsync(file, data);
Expand All @@ -65,7 +66,8 @@ public class ApiHelper
await File.WriteAllBytesAsync(file, data);

// Clean data
data = PKCS7.CleanSign(data);
//data = PKCS7.CleanSign(data);
data = await ASN1.CleanSignAsync(data);
}

string content = Encoding.UTF8.GetString(data);
Expand Down
4 changes: 4 additions & 0 deletions Api5704/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public class Config
public bool SignFile { get; set; } = true;
public bool CleanSign { get; set; } = true;
public int MaxRetries { get; set; } = 10;
public string DirSources { get; set; } = string.Empty;
public string DirRequests { get; set; } = string.Empty;
public string DirResults { get; set; } = string.Empty;
public string DirAnswers { get; set; } = string.Empty;
public string CspTest { get; set; } =
@"C:\Program Files\Crypto Pro\CSP\csptest.exe";
public string CspTestSignFile { get; set; } =
Expand Down
10 changes: 6 additions & 4 deletions Api5704/PKCS7.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ internal static class PKCS7
/// </summary>
/// <param name="data">Массив байтов с сообщением в формате PKCS#7.</param>
/// <returns>Массив байтов с исходным сообщением без ЭП.</returns>
public static byte[] CleanSign(byte[] data)
public static async Task<byte[]> CleanSign(byte[] data)
{
var signedCms = new SignedCms();
signedCms.Decode(data);
//var signedCms = new SignedCms();
//signedCms.Decode(data);

return signedCms.ContentInfo.Content;
//return signedCms.ContentInfo.Content;

return await ASN1.CleanSignAsync(data);
}

/// <summary>
Expand Down
19 changes: 18 additions & 1 deletion Api5704/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,23 @@ static async Task Main(string[] args)
Environment.Exit(2);
}

if (args.Length == 0) Usage();
if (args.Length == 0)
{
string sources = Config.DirSources;

if (!string.IsNullOrEmpty(sources) && Directory.Exists(sources))
{
Console.WriteLine(@$"Параметры не указаны, но есть папка ""{sources}"".");
// dir requests results answers
await ApiExtra.PostRequestFolderAsync(sources,
Config.DirRequests, Config.DirResults, Config.DirAnswers);
}
else
{
Usage();
}
}

string cmd = args[0].ToLower();

try
Expand Down Expand Up @@ -135,6 +151,7 @@ result.xml answer.xml
Параметры: request.xml result.xml answer.xml
dir - пакетная обработка запросов (auto) из папки.
Это действие по умолчанию, если параметров не указано, но есть папка DirSources в конфиге.
Параметры: sources requests results answers";

Expand Down
36 changes: 27 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
## Config

При первом запуске будет создан файл настроек `Api5704.config.json`
с параметрами по умолчанию. Откорректируйте его перед новым запуском:
(в папке с программой) с параметрами по умолчанию.
Откорректируйте его перед новым запуском:

* `MyThumbprint` = отпечаток вашего сертификата для его выбора в Хранилище;
* `VerboseClient` = отображать содержимое вашего сертификата;
Expand All @@ -76,6 +77,14 @@
* `ProxyAddress` = url прокси-сервера (опционально);
* `SignFile` = подписывать запросы в программе;
* `CleanSign` = удалять подписи ответов в программе;
* `MaxRetries` = число попыток с предписанным интервалом в 1 сек.,
чтобы получить сведения по запросу;
* `DirSources` = папка с исходными запросами для пакетной обработки
(должна существовать, чтобы при запуске без параметров, файлы брались
оттуда;
* `DirRequests` = папка с отправленными запросами;
* `DirResults` = папка с полученными квитанциями;
* `DirAnswers` = папка с полученными сведениями.
* `CspTest` = путь к программе КриптоПро `csptest.exe` (опционально);
* `CspTestSignFile` = команда с параметрами для подписи запросов в
программе, где:
Expand Down Expand Up @@ -174,21 +183,26 @@
Api5704 AUTO request.xml result.xml answer.xml

Пакетная обработка запросов (`auto`) из папки за один запуск -
команда `dir`:
команда `dir` (это и действие по умолчанию, если параметров не указано
вовсе, но есть папка `DirSources` в конфиге, а также там указаны папки
`DirRequests`, `DirResults`, `DirAnswers`):

Api5704 DIR sources requests results answers
Api5704

где:

- `sources` - папка с исходными запросами `*.xml` (имена файлов любые);
- `sources` - папка с исходными запросами `*.xml` (имена файлов любые -
рекомендуется использовать ФИО);
- `requests` - папка, куда будут сложены копии исходных файлов,
переименованные по маске `yyyy-MM-dd.guid.request.xml`
переименованные по маске `ФИО.yyyy-MM-dd.guid.request.xml`:
- `ФИО` - исходное имя файла (например, ФИО),
- `yyyy-MM-dd` - текущая дата,
- `guid` - ИдентификаторЗапроса из XML;
- `results` - папка, куда будут сложены квитанции,
переименованные по аналогичной маске `yyyy-MM-dd.guid.result.xml`;
- `answers` - папка, куда будут сложены квитанции,
переименованные по аналогичной маске `yyyy-MM-dd.guid.answer.xml`.
- `results` - папка, куда будут сложены полученные квитанции,
переименованные по аналогичной маске `ФИО.yyyy-MM-dd.guid.result.xml`;
- `answers` - папка, куда будут сложены полученные сведения,
переименованные по аналогичной маске `ФИО.yyyy-MM-dd.guid.answer.xml`.

После получения файла в папке `answers`, соответствующий ему исходный
файл будет считаться обработанным и удален из папки `sources`, при этом
Expand All @@ -212,9 +226,13 @@
Номер версии программы указывается по нарастающему принципу:

* Требуемая версия .NET (8);
* Год разработки (2024);
* Год текущей разработки (2024);
* Месяц без первого нуля и день редакции (624 - 24.06.2024);
* Номер билда - просто нарастающее число для внутренних отличий.
Если настроен сервис AppVeyor, то это его автоинкремент.

Продукт развивается для собственных нужд, и поэтому
Breaking Changes могут случаться чаще, чем это в SemVer.

## License

Expand Down

0 comments on commit 9a5d957

Please sign in to comment.