Вы получаете письмо от бабушки о переводе денег, но на письме нет ее подписи. Вы переведете деньги? Я желаю тебе этого.

Подпись является наиболее распространенным способом обеспечения подлинности информации. Это было со времен Римской империи. И иронично, что в наш цифровой век есть много компаний и приложений, которые взаимодействуют без надлежащей цифровой подписи.

Объем проекта

Создайте простое приложение go, которое создает подпись на основе образца текста. Затем проверьте подпись, если она действительна.

Общественная библиотека

Предварительный просмотр готового проекта

Запустите приложение в командной оболочке, вызвав файл сборки go.

go run main.go

Сначала приложение распечатывает фиктивный открытый текст. Затем он создает подпись. При успешном создании подписи подпись будет распечатана. Последняя часть — это приложение, проверяющее подпись к открытому тексту. Если проверка прошла успешно, выводится сообщение об успехе.

Дизайн приложения

Прежде чем продолжить, подпишитесь на наш веб-сайт, чтобы получать уведомления о новых обучающих материалах.

Код

Основное приложение

package main
import (
	"log"
	"github.com/purnaresa/bulwark/crypto"
)
func main() {
	// provision key pair
	privateKey, publicKey, err := crypto.GenerateKeyPair()
	if err != nil {
		log.Fatalln(err)
	}
	// create dummy plaintext
	plaintext := []byte("hello, my name is plaintext")
	log.Printf("plaintext : %s\n\n", string(plaintext))
	// create signature
	log.Println("creating signature...")
	signature, err := crypto.SignDefault(plaintext, privateKey)
	if err != nil {
		log.Fatalln(err)
	} else {
		log.Printf("signature : %s\n\n", string(signature))
	}
	// verify signature
	log.Println("verifying signature and plaintext...")
	errVerify := crypto.VerifyDefault(plaintext, publicKey, signature)
	if errVerify != nil {
		log.Fatalln(errVerify)
	} else {
		log.Println("verification success!")
	}
}

Приведенный выше код — это полный код main.go. Мы разберем код с объяснением ниже.

Раздел 1: предоставление пары ключей

privateKey, publicKey, err := crypto.GenerateKeyPair()
	if err != nil {
		log.Fatalln(err)
	}

В производственной среде пара ключей RSA предоставляется вне системы. Вы должны хранить закрытый ключ в надежном месте. Целостно — если ваш закрытый ключ просочился, подпись ошибочна, потому что подпись не может гарантировать ее подлинность. Открытый ключ должен быть передан партнеру, который общается с вами. Если ваш закрытый ключ просочился, сгенерируйте новую пару ключей!

Пара ключей в этом проекте генерируется на лету для простоты.

Раздел 2: создание фиктивного открытого текста

plaintext := []byte("hello, my name is plaintext")
log.Printf("plaintext : %s\n\n", string(plaintext))

Вы можете зашифровать что угодно, пока оно находится в байтовом формате. Важным моментом является размер открытого текста. RSA может шифровать только открытый текст ограниченного размера. Этого будет достаточно для большинства случаев при шифровании текстового сообщения. Если вам нужно зашифровать данные большого размера, такие как изображение или PDF-файл, используйте метод двойного шифрования. Сначала вы шифруете файл случайно сгенерированным ключом, используя AES/симметричный. Затем вы шифруете сгенерированный ключ с помощью RSA.

Раздел 3: создание подписи

log.Println("creating signature...")
signature, err := crypto.SignDefault(plaintext, privateKey)
	if err != nil {
		log.Fatalln(err)
	} else {
		log.Printf("signature : %s\n\n", string(signature))
	}

Подпишите открытый текст закрытым ключом. Результатом является подпись, которую можно проверить с помощью открытого ключа из пары ключей. Подпись создается с помощью рандомизатора. Подпись будет отличаться каждый раз, даже если открытый текст одинаков.

Вариант использования для создания подписи — непосредственно перед отправкой данных вашему партнеру вместе с подписью. Если ваше приложение обрабатывает личную информацию (PII), вам необходимо зашифровать данные. Создайте подпись на основе открытого текста перед шифрованием. Если вы создаете подпись после шифрования, злоумышленник может саботировать (изменить) подпись, поэтому проверка не удалась, поэтому информация не обрабатывается. Защитите информацию, зашифровав как зашифрованный текст, так и подпись.

Раздел 4. Проверка подписи

log.Println("verifying signature and plaintext...")
errVerify := crypto.VerifyDefault(plaintext, publicKey, signature)
	if errVerify != nil {
		log.Fatalln(errVerify)
	} else {
		log.Println("verification success!")
	}

Подпись должна быть проверена с использованием открытого ключа создателя подписи. Открытый текст необходим для проверки того, является ли подпись действительной или нет. Если проверка не удалась, она вернется с объектом ошибки.

В рабочем сценарии тот, кто проверяет подпись, является партнером, с которым вы общаетесь. Поэтому вы должны поделиться с ними своим открытым ключом, чтобы они могли проверить подпись.

Библиотека

Основное приложение выше — это импорт библиотеки из

"github.com/purnaresa/bulwark/crypto"

Это библиотека для безопасной архитектуры приложений. Три функции, которые используются в этом приложении:

  • Создать пару ключей ()
  • SignDefault(открытый текст []byte, privateKey []byte) (строка подписи, ошибочная ошибка)
  • VerifyDefault (открытый текст [] байт, publicKey [] байт, строка подписи) (ошибка ошибки)

GenerateKeyPair – это функция для создания пары ключей RSA. Подробности и пример функции доступны в этом посте Создание пары закрытый-открытый ключ RSA в Go

SignDefault — это функция для создания подписи. Входные данные представляют собой открытый текст и закрытый ключ. Вывод представляет собой подпись в строке base64 с целью удобного хранения и доставки. Функция является гибкой для большинства случаев использования. Проверьте этот Github Code, если вам нужно знать что под капотом.

VerifyDefault — это функция для проверки подписи. Ввод представляет собой открытый текст, открытый ключ и открытый ключ. Вывод — пустой объект ошибки, если проверка прошла успешно. Проверьте этот Github Code, если вам нужно знать что под капотом.

Резюме

Создать цифровую подпись несложно. Многие общественные библиотеки доступны для использования. Вы можете использовать тот, которому доверяете. Важно убедиться, что спецификация этих библиотек соответствует отраслевому стандарту. Если спецификация не соответствует отраслевому стандарту, партнеру, с которым вы общаетесь, будет сложно проверить подпись.

Пример кода доступен здесь:

https://github.com/purnaresa/bulwark/blob/master/crypto/example/create_signature/main.go