برنامه نویسی

گردش کار کامل TLS در Golang ساخته شده ساده: فرآیند کامل توضیح داده شده است

شرح تصویر

Leapcell: بهترین میزبانی وب بدون سرور

توضیح روند دست زدن TLS

دست زدن TLS (امنیت لایه حمل و نقل) یک روش حیاتی است که امکان برقراری ارتباط ایمن بین مشتری (مانند مرورگر وب) و یک سرور (مانند سرور وب) را فراهم می کند. در زیر تفصیل مفصلی از کل فرآیند دست زدن به TLS آورده شده است:

  1. مشتری سلام

    • مشتری با ارسال پیام “سلام مشتری” به سرور ، دستکاری را شروع می کند.
    • این پیام شامل:
      • نسخه های TLS پشتیبانی شده توسط مشتری.
      • لیستی از مجموعه های رمزگذاری (الگوریتم های رمزگذاری) که از آن پشتیبانی می کند.
      • یک رشته بایت تصادفی (به عنوان تصادفی مشتری گفته می شود).
  2. سرور سلام

    • سرور با یک پیام “سرور سلام” پاسخ می دهد.
    • این پیام شامل:
      • نسخه TLS انتخاب شده.
      • مجموعه رمزگذاری شده.
      • یک رشته بایت تصادفی (معروف به سرور تصادفی).
      • گواهی دیجیتالی سرور (صادر شده توسط یک مجوز معتبر ، CA).
  3. تأیید گواهینامه

    • مشتری گواهی سرور را از طریق زنجیره گواهینامه (CA) تأیید می کند.
    • تضمین می کند که گواهی معتبر ، منقضی نشده و به دامنه صحیح صادر شود.
  4. پیش – نسل مخفی

    • مشتری با استفاده از کلید عمومی سرور (استخراج شده از گواهی) “Pre – Master Secret” ایجاد می کند.
    • این راز رمزگذاری شده و به سرور ارسال می شود.
  5. استخراج مخفی

    • مشتری و سرور هم با استفاده از موارد زیر “راز اصلی” را تولید می کنند:
      • مشتری تصادفی.
      • سرور تصادفی.
      • راز پیش – استاد.
    • Master Secret برای استخراج کلیدهای جلسه برای رمزگذاری و بررسی های یکپارچگی استفاده می شود.
  6. ایجاد کلیدهای جلسه

    • با استفاده از Master Secret ، هر دو طرف ایجاد می کنند:
      • کلیدهای رمزگذاری برای رمزگذاری متقارن.
      • MAC (کد تأیید اعتبار پیام) کلیدهای بررسی یکپارچگی.
  7. مشتری تمام شد

    • مشتری پیام “تمام شده” را ارسال می کند ، که با کلیدهای جلسه رمزگذاری می شود.
    • این تأیید می کند که دست زدن به دست موفقیت آمیز بوده و پیام های آینده رمزگذاری می شوند.
  8. سرور تمام شد

    • سرور پیام “تمام شده” خود را ارسال می کند ، که با کلیدهای جلسه رمزگذاری شده است.
    • این نشانگر پایان دست دادن و شروع ارتباطات رمزگذاری شده است.
  9. انتقال داده ها

    • تمام ارتباطات بعدی با استفاده از کلیدهای جلسه مشتق شده رمزگذاری می شود.
    • داده ها در بسته های رمزگذاری شده با بررسی های یکپارچگی ارسال می شوند.

نمودار فرآیند دستی TLS

+----------------------------------------+      +----------------------------------------+
|               Client                   |      |               Server                   |
+----------------------------------------+      +----------------------------------------+
|                                        |      |                                        |
|  ClientHello                           |----->|                                        |
|  [TLS Version, Cipher Suites, Random]  |      |                                        |
|                                        |      |                                        |
|                                        |      |  ServerHello                            |
|                                        |<-----|  [TLS Version, Cipher Suite, Random]  |
|                                        |      |                                        |
|                                        |<-----|  Certificate                           |
|                                        |      |  [Server's Public Key]                 |
|                                        |      |                                        |
|                                        |<-----|  ServerHelloDone                       |
|                                        |      |                                        |
|  CertificateVerify                     |      |                                        |
|  [Verify Server's Certificate]         |      |                                        |
|                                        |      |                                        |
|  ClientKeyExchange                     |----->|                                        |
|  [Encrypted Pre-Master Secret]         |      |                                        |
|                                        |      |                                        |
|  ChangeCipherSpec                      |----->|                                        |
|  [Start Using Encryption]              |      |                                        |
|                                        |      |                                        |
|  Finished                              |----->|                                        |
|  [Verifies Handshake Integrity]        |      |                                        |
|                                        |      |                                        |
|                                        |<-----|  ChangeCipherSpec                      |
|                                        |      |  [Start Using Encryption]              |
|                                        |      |                                        |
|                                        |<-----|  Finished                              |
|                                        |      |  [Verifies Handshake Integrity]        |
|                                        |      |                                        |
|  Secure Communication                  |<--->|  Secure Communication                  |
|  [Encrypted Data Transfer]             |      |  [Encrypted Data Transfer]             |
+----------------------------------------+      +----------------------------------------+
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

به دست آوردن پیام سلام مشتری TLS با Golang

در اینجا نحوه اجرای سرور که تمام پیام های ClientHello را با استفاده از Golang ضبط می کند آورده شده است:

تولید گواهینامه

ابتدا گواهینامه های SSL لازم را تولید کنید:

# Generate a private key
openssl genrsa -out server.key 2048
# Generate a public key (certificate)
openssl req -new -x509 -key server.key -out server.pem -days 3650
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اجرای سرور

در زیر کد سرور کامل برای ضبط اطلاعات ClientHello است:

package main

import (
    "bufio"
    "crypto/tls"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net"
    "os"
    "sync"
    "time"
)

type CollectInfos struct {
    ClientHellos []*tls.ClientHelloInfo
    sync.Mutex
}

var collectInfos CollectInfos
var currentClientHello *tls.ClientHelloInfo

func (c *CollectInfos) collectClientHello(clientHello *tls.ClientHelloInfo) {
    c.Lock()
    defer c.Unlock()
    c.ClientHellos = append(c.ClientHellos, clientHello)
}

func (c *CollectInfos) DumpInfo() {
    c.Lock()
    defer c.Unlock()
    data, err := json.Marshal(c.ClientHellos)
    if err != nil {
        log.Fatal(err)
    }
    ioutil.WriteFile("hello.json", data, os.ModePerm)
}

func getCert() *tls.Certificate {
    cert, err := tls.LoadX509KeyPair("server.pem", "server.key")
    if err != nil {
        log.Println(err)
        return nil
    }
    return &cert
}

func buildTlsConfig(cert *tls.Certificate) *tls.Config {
    cfg := &tls.Config{
        Certificates: []tls.Certificate{*cert},
        GetConfigForClient: func(clientHello *tls.ClientHelloInfo) (*tls.Config, error) {
            collectInfos.collectClientHello(clientHello)
            currentClientHello = clientHello
            return nil, nil
        },
    }
    return cfg
}

func serve(cfg *tls.Config) {
    ln, err := tls.Listen("tcp", ":443", cfg)
    if err != nil {
        log.Println(err)
        return
    }
    defer ln.Close()
    for {
        conn, err := ln.Accept()
        if err != nil {
            log.Println(err)
            continue
        }
        go handler(conn)
    }
}

func handler(conn net.Conn) {
    defer conn.Close()
    r := bufio.NewReader(conn)
    for {
        msg, err := r.ReadString('\n')
        if err != nil {
            log.Println(err)
            return
        }
        fmt.Println(msg)
        data, err := json.Marshal(currentClientHello)
        if err != nil {
            log.Fatal(err)
        }
        _, err = conn.Write(data)
        if err != nil {
            log.Println(err)
            return
        }
    }
}

func main() {
    go func() {
        for {
            collectInfos.DumpInfo()
            time.Sleep(10 * time.Second)
        }
    }()
    cert := getCert()
    if cert != nil {
        serve(buildTlsConfig(cert))
    }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اجرای مشتری

کد مشتری مربوطه به شرح زیر است:

func main() {
    conn, err := tls.Dial("tcp", "localhost:443", &tls.Config{InsecureSkipVerify: true})
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()
    _, err = conn.Write([]byte("hello\n"))
    if err != nil {
        log.Fatal(err)
    }
    buf := make([]byte, 1000)
    n, err := conn.Read(buf)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(buf[:n]))
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

این پیاده سازی شما را قادر می سازد تا اطلاعات مفصلی را از پیام های ClientHello در طی فرآیند دستی TLS ضبط کنید. سرور بطور دوره ای این اطلاعات را برای تجزیه و تحلیل به یک پرونده JSON صادر می کند.

در آخر ، بستری را توصیه کنید که برای استقرار خدمات GO مناسب باشد: جهش

شرح تصویر

🚀 با زبان مورد علاقه خود بسازید

با زحمت در JavaScript ، Python ، Go یا Rust.

🌍 پروژه های نامحدود را به صورت رایگان مستقر کنید

فقط هزینه آنچه را که استفاده می کنید بپردازید – در صورت عدم درخواست ، هیچ هزینه ای ندارد.

⚡ پرداخت – به عنوان – شما – بروید ، بدون هزینه پنهان

بدون هزینه بیکار ، فقط مقیاس پذیری بدون درز.

شرح تصویر

📖 اسناد ما را کاوش کنید

🔹 ما را در توییتر دنبال کنید: leapcellhq

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا