Проверка цепочки: без отдельного звена подписи — пакеты НРД подписывает шлюз (ИШ — единственный владелец ключа), подпись проверяется звеном НРД; образ: дистрибутив ИШ в составе (IGATE=…), установка с образа без интернета

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
zuevav
2026-10-05 18:09:33 +03:00
parent f0dec0c238
commit d88963bd8d
2 changed files with 5 additions and 22 deletions
+4 -21
View File
@@ -5,14 +5,13 @@ package lkgateway
// - учёт DEPO: проверочное событие BJ_PING обработано процедурами обмена; // - учёт DEPO: проверочное событие BJ_PING обработано процедурами обмена;
// - QUIK МНП: объекты, инструменты, справочник получателей (только чтение); // - QUIK МНП: объекты, инструменты, справочник получателей (только чтение);
// - QUIK МНП, по желанию: пробная блокировка 1 шт. бумаги клиента («Вывод ЦБ (M2M)») и сразу снятие; // - QUIK МНП, по желанию: пробная блокировка 1 шт. бумаги клиента («Вывод ЦБ (M2M)») и сразу снятие;
// - подпись ключом организации (Валидата); // - НРД: запрос справочника участников уходит через шлюз — шлюз подписывает его ключом организации (ИШ —
// - НРД: запрос справочника участников уходит через шлюз и подписывается, ответ приходит во входящие. // единственный владелец ключа для НРД), НРД принимает и отвечает, ответ приходит во входящие.
// Звенья идут по очереди; упавшее не останавливает остальные — видно всю картину. // Звенья идут по очереди; упавшее не останавливает остальные — видно всю картину.
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"fmt"
"net/http" "net/http"
"regexp" "regexp"
"sort" "sort"
@@ -20,8 +19,6 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/cryptocli"
) )
// ChainStep — звено проверки. // ChainStep — звено проверки.
@@ -69,7 +66,7 @@ func chainRun(rc *RuntimeConfig, nsdReal bool, blk *chainQuikBlock) {
steps = append(steps, ChainStep{Key: "quik-block", Title: "QUIK МНП: пробная блокировка 1 бумаги и снятие"}) steps = append(steps, ChainStep{Key: "quik-block", Title: "QUIK МНП: пробная блокировка 1 бумаги и снятие"})
} }
} }
steps = append(steps, ChainStep{Key: "sign", Title: "Подпись ключом организации"}, ChainStep{Key: "nsd", Title: "НРД: запрос через шлюз — ответ получен"}) steps = append(steps, ChainStep{Key: "nsd", Title: "НРД: запрос через шлюз подписан ключом, доставлен, ответ получен"})
for i := range steps { for i := range steps {
steps[i].State = "wait" steps[i].State = "wait"
} }
@@ -126,20 +123,6 @@ func chainStepRun(rc *RuntimeConfig, s Settings, key string, nsdReal bool, blk *
return "ok", "подключение, объекты M2M, инструменты и справочник получателей на месте" return "ok", "подключение, объекты M2M, инструменты и справочник получателей на месте"
case "quik-block": case "quik-block":
return chainQuikBlockRun(s, blk) return chainQuikBlockRun(s, blk)
case "sign":
if s.Crypto.Provider == "" || s.Crypto.Provider == "stub" {
return "err", "средство подписи не настроено"
}
cli := cryptocli.New(cryptocli.Config{Provider: cryptocli.Provider(s.Crypto.Provider), SocketPath: s.Crypto.SocketPath, ModulePath: s.Crypto.ModulePath})
defer cli.Close()
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
payload := []byte("<bj-chain-test ts=\"" + time.Now().UTC().Format(time.RFC3339) + "\"/>")
sig, err := cli.SignXMLDSig(ctx, payload, "", s.Crypto.Profile)
if err != nil {
return "err", "подпись не получилась: " + err.Error()
}
return "ok", fmt.Sprintf("подпись получена (%d байт)", len(sig))
case "nsd": case "nsd":
if !nsdReal { if !nsdReal {
return "err", "шлюз НРД не настроен — bj работает в режиме имитации (раздел «Шлюз НРД»)" return "err", "шлюз НРД не настроен — bj работает в режиме имитации (раздел «Шлюз НРД»)"
@@ -159,7 +142,7 @@ func chainStepRun(rc *RuntimeConfig, s Settings, key string, nsdReal bool, blk *
return "err", "шлюз не доставил пакет в НРД: " + delErr return "err", "шлюз не доставил пакет в НРД: " + delErr
} }
if reply.After(start) { if reply.After(start) {
d := "НРД ответил за " + humanDur(reply.Sub(sent)) + " — подпись, шлюз, доставка и входящие работают" d := "НРД ответил за " + humanDur(reply.Sub(sent)) + " — ключ организации, шлюз, доставка и входящие работают"
if deliv.After(start) { if deliv.After(start) {
d = "пакет доставлен в НРД, " + d d = "пакет доставлен в НРД, " + d
} }
@@ -16,7 +16,7 @@
{{define "chainTest"}} {{define "chainTest"}}
<div class="card" id="chain"> <div class="card" id="chain">
<h2><span class="dot" id="ch-dot"></span>Проверить всю цепочку</h2> <h2><span class="dot" id="ch-dot"></span>Проверить всю цепочку</h2>
<p class="muted" style="margin:0 0 8px">Сквозная проверка без настоящего перевода: bj по очереди проходит каждое звено и показывает, какое работает, а какое нет.{{if .DepoLicensed}} Учёт DEPO — проверочное событие, QUIK — только чтение (пробная блокировка — по желанию, ниже).{{end}} Подпись — ключом организации. НРД — запрос справочника участников через шлюз с ответом НРД.</p> <p class="muted" style="margin:0 0 8px">Сквозная проверка без настоящего перевода: bj по очереди проходит каждое звено и показывает, какое работает, а какое нет.{{if .DepoLicensed}} Учёт DEPO — проверочное событие, QUIK — только чтение (пробная блокировка — по желанию, ниже).{{end}} НРД — запрос справочника участников через шлюз: шлюз подписывает его ключом организации, НРД отвечает.</p>
{{if .DepoLicensed}} {{if .DepoLicensed}}
<details style="margin:6px 0 10px"> <details style="margin:6px 0 10px">
<summary style="cursor:pointer;color:var(--accent);font-size:13px">Добавить пробную блокировку в QUIK (1 бумага клиента — заблокировать и сразу снять)</summary> <summary style="cursor:pointer;color:var(--accent);font-size:13px">Добавить пробную блокировку в QUIK (1 бумага клиента — заблокировать и сразу снять)</summary>