Skip to content

Instantly share code, notes, and snippets.

@apacheservices68
Last active September 26, 2023 04:05
Show Gist options
  • Save apacheservices68/a322a3b879b6c69a416f3cada27a868d to your computer and use it in GitHub Desktop.
Save apacheservices68/a322a3b879b6c69a416f3cada27a868d to your computer and use it in GitHub Desktop.
asymmetric encryption (mã hóa bất đối xứng dùng RSA)
  1. Tạo chữ ký số certificate authority (CA) và yêu cầu ký:

openssl req -x509 -newkey rsa:4096 -days 365 -nodes -keyout ca-key.pem -out ca-cert.pem -subj "/C=VN/ST=BINHTAN/L=HCM/O=FREELANCER/OU=Education/CN=localhost/[email protected]"

-> -subj có thể thay đổi theo từng environment. 2. Tự ký vào chứng chỉ của chữ ký (self-signed certificate)

openssl x509 -in ca-cert.pem -noout -text 3. Tạo server private key cho server đồng thời yêu cầu ký chứng chỉ cho key này(certificate signing request CSR):

openssl req -newkey rsa:4096 -nodes -keyout server-key.pem -out server-req.pem -subj "/C=VN/ST=BINHCHANH/L=HCM/O=FREELANCER/OU=Computer/CN=localhost/[email protected]"

  1. Sử dụng chữ ký số CA để ký (param -req -in) chứng chỉ của key server và lấy lại chứng chỉ đã ký:

openssl x509 -req -in server-req.pem -days 60 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile server-ext.cnf

  1. Tạo client private key và yêu cầu ký chứng chỉ cho key này (CSR):

openssl req -newkey rsa:4096 -nodes -keyout client-key.pem -out client-req.pem -subj "/C=FR/ST=Alsace/L=Strasbourg/O=PC Client/OU=Computer/CN=localhost/[email protected]"

  1. Sử dụng chữ ký số CA để ký chứng chỉ của client key và lấy lại chứng chỉ đã ký

openssl x509 -req -in client-req.pem -days 60 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -extfile client-ext.cnf

  1. Client tự ký vào chứng chỉ (self-signed certificate):

openssl x509 -in client-cert.pem -noout -text

Note: nội dung trong file server-ext , client-ext có thể thay đổi theo từng môi trường.

Note: openssl req => create certificate authority CSR

package main
import (
"crypto/tls"
"crypto/x509"
"log"
"os"
)
func main() {
log.SetFlags(log.Lshortfile)
// Load certificate of the CA who signed server's certificate
pemServerCA, err := os.ReadFile("cert/ca-cert.pem")
if err != nil {
log.Println(err)
return
}
certPool := x509.NewCertPool()
if !certPool.AppendCertsFromPEM(pemServerCA) {
log.Println(err)
return
}
// Load client's certificate and private key
clientCert, err := tls.LoadX509KeyPair("cert/client-cert.pem", "cert/client-key.pem")
if err != nil {
log.Println(err)
return
}
// Create the credentials and return it
config := &tls.Config{
RootCAs: certPool,
//ClientAuth: tls.RequireAndVerifyClientCert,
Certificates: []tls.Certificate{clientCert},
}
conn, err := tls.Dial("tcp", "0.0.0.0:10443", config)
if err != nil {
log.Println(err)
return
}
defer conn.Close()
n, err := conn.Write([]byte("hello\n"))
if err != nil {
log.Println(n, err)
return
}
buf := make([]byte, 100)
n, err = conn.Read(buf)
if err != nil {
log.Println(n, err)
return
}
println(string(buf[:n]))
}
package main
import (
"bufio"
"crypto/tls"
"crypto/x509"
"fmt"
"io"
"log"
"net"
"os"
"strings"
)
func main() {
log.SetFlags(log.Lshortfile)
// Load certificate of the CA who signed client's certificate
pemClientCA, err := os.ReadFile("cert/ca-cert.pem")
if err != nil {
log.Println(err)
return
}
certPool := x509.NewCertPool()
if !certPool.AppendCertsFromPEM(pemClientCA) {
log.Println(err)
return
}
// Load server's certificate and private key
serverCert, err := tls.LoadX509KeyPair("cert/server-cert.pem", "cert/server-key.pem")
if err != nil {
log.Println(err)
return
}
// Create the credentials and return it
config := &tls.Config{
Certificates: []tls.Certificate{serverCert},
ClientAuth: tls.NoClientCert,
ClientCAs: certPool,
}
ln, err := tls.Listen("tcp", ":10443", config)
if err != nil {
log.Println(err)
return
}
defer ln.Close()
for {
conn, err := ln.Accept()
if err != nil {
log.Println(err)
continue
}
go handleConnection(conn)
}
}
func handleConnection(conn net.Conn) {
defer conn.Close()
r := bufio.NewReader(conn)
for {
line, err := r.ReadString('\n')
if len(line) == 0 && err != nil {
if err == io.EOF {
break
}
return
}
line = strings.TrimSuffix(line, "\n")
fmt.Println(line)
_, err = conn.Write([]byte("world\n"))
if err != nil {
if err == io.EOF {
break
}
return
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment