Прежде чем переходить к двустороннему SSL, нам нужно понять, что такое асимметричная криптография.

Асимметричная криптография - это процесс, который использует пару связанных ключей - один открытый ключ и один закрытый ключ - для шифрования и дешифрования сообщения.

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

Как работает асимметричная криптография?

Первоначально пара закрытого и открытого ключей создается на стороне отправителя и получателя. Эти ключи могут быть созданы с использованием алгоритмов DSA. Чтобы узнать об алгоритмах DSA, нажмите здесь. Затем открытые ключи распределяются между отправителем и получателем. Затем отправитель шифрует полезную нагрузку или сообщение, которое он / она хочет отправить, с помощью открытого ключа получателя, создавая, таким образом, зашифрованный текст. Затем этот зашифрованный текст отправляется получателю, который расшифровывает его своим закрытым ключом. Хотя открытый ключ может использоваться несколькими получателями, его можно расшифровать только с помощью соответствующего закрытого ключа, что обеспечивает определенный уровень безопасности.

Если открытый ключ используется для шифрования, то соответствующий закрытый ключ используется для дешифрования. Если закрытый ключ используется для шифрования, то соответствующий открытый ключ используется для дешифрования.

Возвращение к 2-стороннему SSL

SSL (Secure Socket Layer) - это криптографический протокол, используемый для обеспечения безопасной связи между клиентом и сервером для обеспечения безопасности и целостности данных.

Обмен данными по SSL всегда начинается с подтверждения SSL. Подтверждение связи SSL - это асимметричная криптография, которая позволяет клиенту проверить веб-сервер и установить безопасное соединение до начала фактической передачи данных. Обе стороны передают друг другу свои общедоступные сертификаты (X.509 сертификаты, подписанные CA), после чего на их основе выполняется проверка / проверка.

Ниже приведены этапы процесса подтверждения и фактической передачи данных:

  • Клиент запрашивает защищенный ресурс по протоколу HTTPS, и начинается процесс подтверждения SSL. Это сообщение включает номер версии SSL клиента, настройки шифра, данные для конкретного сеанса и другую информацию, которая необходима серверу для связи с клиентом с помощью SSL.
  • Сервер отправляет клиенту копию своего публичного сертификата. Это сообщение включает номер версии SSL сервера, настройки шифров, данные для конкретного сеанса, сертификат SSL с открытым ключом и другую информацию, которая необходима клиенту для связи с сервером через SSL.
  • Клиент проверяет корневой сертификат по списку доверенных центров сертификации и проверяет действительность сертификата. Если аутентификация не удалась, клиент отказывается от SSL-соединения и выдает исключение. Если клиент доверяет сертификату, он создает, шифрует, отправляет обратно свой общедоступный сертификат на сервер и переходит к следующему шагу.
  • Сервер проверяет / проверяет полученный сертификат через центр сертификации (ЦС) для сертификатов, подписанных ЦС.
  • После завершения процесса рукопожатия клиент и сервер обмениваются данными и передают друг другу данные, зашифрованные с помощью секретных ключей, совместно используемых между ними во время рукопожатия. Пожалуйста, посмотрите графическое изображение всего процесса ниже:

Пожалуйста, ознакомьтесь с приведенным ниже примером кода golang для фактической передачи данных, то есть когда было установлено рукопожатие:

import (
"bytes"
"crypto/tls"
"crypto/x509"
"encoding/base64"
"flag"
"io/ioutil"
"log"
"net/http"
)
var (
caFile = flag.String("CA", "publicTest.pem", "A PEM encoded CA's certificate file.")
)
func main() {
  flag.Parse()
  
  // Load CA cert
  caCert, err := ioutil.ReadFile(*caFile)
  if err != nil {
    log.Fatal(err)
  }
  caCertPool := x509.NewCertPool()
  caCertPool.AppendCertsFromPEM(caCert)
  // Setup HTTPS client
  tlsConfig := &tls.Config{
    RootCAs: caCertPool,
  }
  tlsConfig.BuildNameToCertificate()
  transport := &http.Transport{TLSClientConfig: tlsConfig}
  headers := http.Header{}
  headers.Set("xyz-Client-Id", "abc-def-ghi-jkl")
  headers.Set("xyz-Client-Secret", "jasbdjkabckasnclasncdsv")
  var body = []byte(`{
    "order_id": 1223
  }`)
request, err := http.NewRequest("POST", "https://staging-    abc/order/update", bytes.NewBuffer(body))
  if err != nil {
    log.Fatal(err)
  }
  request.Header = headers
  client := &http.Client{
    Transport: transport,
  }
  // Do POST something
  resp, err := client.Do(request)
  if err != nil {
    log.Fatal(err)
  }
  defer resp.Body.Close()
  // Dump response
  data, err := ioutil.ReadAll(resp.Body)
  if err != nil {
    log.Fatal(err)
  }
  log.Println("data: ", string(data))
}

Если вы хотите узнать разницу между односторонним и двусторонним SSL, перейдите по этой ссылке.