GoKalkan - это библиотека-обертка над KalkanCrypt для Golang.
KalkanCrypt - это набор библиотек для шифрования, дешифрования данных.
Основные методы KalkanCrypt реализованы в libkalkancryptwr-64
. Это файл доступными методами
для подписания файлов, текста используя ЭЦП. Подробнее про PKI можно почитать здесь.
// Kalkan - интерфейс с методами KalkanCrypt
type Kalkan interface {
Init() error
LoadKeyStore(password, containerPath string) error
SignXML(data string) (string, error)
SignWSSE(data string) (string, error)
SignData(data string) (string, error)
VerifyXML(xml string) (string, error)
VerifyData(data string) (*VerifiedData, error)
X509ExportCertificateFromStore() (string, error)
GetLastErrorString() string
Close() error
}
Не все доступные методы пока были реализованы. Для знакомства со всеми функциями перейти сюда.
Чтобы использовать библиотеку требуется провести подготовку:
1. Обратиться в pki.gov.kz чтобы получить SDK
SDK представляет собой набор библиотек для Java и C.
Сертификаты будут лежать по пути SDK/C/Linux/ca-certs/Ubuntu
. Будут два типа сертфикатов - production
и test
.
В папке будут скрипты для установки сертификатов, понадобится sudo права.
Файлы лежат в директории SDK/C/Linux/C
. Команда для копирования:
sudo cp -f libkalkancryptwr-64.so libkalkancryptwr-64.so.1.1.0 /usr/lib/
kalkancrypt
- представляет набор из общих библиотек и состоит из файлов расширения .so
.
Скопируйте папку SDK/C/Linux/libs_for_linux/kalkancrypt
в /opt/
sudo cp -r kalkancrypt /opt/
sudo chmod -R 555 /opt/kalkancrypt
При обращении к GoKalkan убедитесь что экспортирована переменная окружения
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/kalkancrypt/:/opt/kalkancrypt/lib/engines
Это переменная нужна для динамического обращения к библиотеке KalkanCrypt.
Версия Go 1.17+
go get github.com/Zulbukharov/GoKalkan
Начнем с загрузки сертификатов (можно ЭЦП, который начинается с RSA...
):
package main
import (
"fmt"
"log"
kalkan "github.com/Zulbukharov/GoKalkan"
)
var (
// certPath хранит путь к сертификату
certPath = "test_cert/GOSTKNCA.p12"
// certPassword пароль
// P.S. никогда не храните пароли в коде
certPassword = "Qwerty12"
)
func main() {
cli, err := kalkan.NewClient()
if err != nil {
log.Fatal("NewClient", err)
}
// Обязательно закрывайте клиент, иначе приведет утечкам ресурсов
defer cli.Close()
// Подгружаем сертификат с паролем
if err := cli.LoadKeyStore(certPassword, certPath); err != nil {
log.Fatal("cli.LoadKeyStore", err)
}
}
Для того чтобы подписать XML документ, нужно передать документ в виде строки:
signedXML, err := cli.SignXML("<root>GoKalkan</root>")
fmt.Println("Подписанный XML", signedXML)
fmt.Println("Ошибка", err)
Проверка подписи документа вернет ошибку, если документ подписан неверно либо срок у сертификата с которым подписан истёк.
serial, err := cli.VerifyXML(signedXML)
fmt.Println("Серийный номер", serial)
fmt.Println("Ошибка", err)
Для того чтобы подписать XML документ в формате SignWSSE, нужно передать документ в виде строки.
Функция обернет документ в soap:Envelope
и запишет внутри soap:Body
.
signedXML, err := cli.SignWSSE("<root>GoKalkan</root>")
fmt.Println("Подписанный XML в формате WSSE", signedXML)
fmt.Println("Ошибка", err)
GoKalkan можно использовать для:
- подписывания XML документов c помощью ЭЦП
- реализовывания авторизации через ЭЦП
- подпись документов для гос. сервисов
- подпись XML для SmartBridge
Библиотека GoKalkan может работать мультипоточно. Вызовы методов являются concurrency-safe.
Команда запуска бенчмарка:
go test -bench SignXML -run=^$ -benchmem
Характеристики хост машины:
- goos: linux
- goarch: amd64
- cpu: Intel(R) Core(TM) i5-8500 CPU @ 3.00GHz
Бенчмарк | Кол-во циклов | Средн. время выполнения | Средн. потребление ОЗУ | Средн. кол-во аллокаций |
---|---|---|---|---|
BenchmarkSignXML-6 | 2809 | 422310 ns/op | 2792 B/op | 8 allocs/op |
Cпасибо за помощь в развитии проекта:
Tlekbai Ali 💻 💡 |
The MIT License (MIT) 2021 - Abylaikhan Zulbukharov.
Please have a look at the LICENSE.md for more details.