Simple Golang HTTPS/TLS Examples
# Key considerations for algorithm "RSA" ≥ 2048-bit
openssl genrsa -out server.key 2048
# Key considerations for algorithm "ECDSA" (X25519 || ≥ secp384r1)
# https://safecurves.cr.yp.to/
# List ECDSA the supported curves (openssl ecparam -list_curves)
openssl ecparam -genkey -name secp384r1 -out server.key
.pem
|.crt
) based on the private (.key
)openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650
package main
import (
// "fmt"
// "io"
"net/http"
"log"
)
func HelloServer(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte("This is an example server.\n"))
// fmt.Fprintf(w, "This is an example server.\n")
// io.WriteString(w, "This is an example server.\n")
}
func main() {
http.HandleFunc("/hello", HelloServer)
err := http.ListenAndServeTLS(":443", "server.crt", "server.key", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
Hint: visit, please do not forget to use https begins, otherwise chrome will download a file as follows:
$ curl -sL https://localhost:443 | xxd
0000000: 1503 0100 0202 0a .......
Server
package main
import (
"log"
"crypto/tls"
"net"
"bufio"
)
func main() {
log.SetFlags(log.Lshortfile)
cer, err := tls.LoadX509KeyPair("server.crt", "server.key")
if err != nil {
log.Println(err)
return
}
config := &tls.Config{Certificates: []tls.Certificate{cer}}
ln, err := tls.Listen("tcp", ":443", 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 {
msg, err := r.ReadString('\n')
if err != nil {
log.Println(err)
return
}
println(msg)
n, err := conn.Write([]byte("world\n"))
if err != nil {
log.Println(n, err)
return
}
}
}
Client
package main
import (
"log"
"crypto/tls"
)
func main() {
log.SetFlags(log.Lshortfile)
conf := &tls.Config{
//InsecureSkipVerify: true,
}
conn, err := tls.Dial("tcp", "127.0.0.1:443", conf)
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 (
"crypto/tls"
"log"
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
w.Write([]byte("This is an example server.\n"))
})
cfg := &tls.Config{
MinVersion: tls.VersionTLS12,
CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
PreferServerCipherSuites: true,
CipherSuites: []uint16{
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_RSA_WITH_AES_256_CBC_SHA,
},
}
srv := &http.Server{
Addr: ":443",
Handler: mux,
TLSConfig: cfg,
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),
}
log.Fatal(srv.ListenAndServeTLS("tls.crt", "tls.key"))
}
.key
) and public key (PEM-encodings .pem
|.crt
) in one command:# ECDSA recommendation key ≥ secp384r1
# List ECDSA the supported curves (openssl ecparam -list_curves)
openssl req -x509 -nodes -newkey ec:secp384r1 -keyout server.ecdsa.key -out server.ecdsa.crt -days 3650
# openssl req -x509 -nodes -newkey ec:<(openssl ecparam -name secp384r1) -keyout server.ecdsa.key -out server.ecdsa.crt -days 3650
# -pkeyopt ec_paramgen_curve:… / ec:<(openssl ecparam -name …) / -newkey ec:…
ln -sf server.ecdsa.key server.key
ln -sf server.ecdsa.crt server.crt
# RSA recommendation key ≥ 2048-bit
openssl req -x509 -nodes -newkey rsa:2048 -keyout server.rsa.key -out server.rsa.crt -days 3650
ln -sf server.rsa.key server.key
ln -sf server.rsa.crt server.crt
.crt
— Alternate synonymous most common among *nix systems .pem
(pubkey)..csr
— Certficate Signing Requests (synonymous most common among *nix systems)..cer
— Microsoft alternate form of .crt
, you can use MS to convert .crt
to .cer
(DER
encoded .cer
, or base64[PEM]
encoded .cer
)..pem
= The PEM extension is used for different types of X.509v3 files which contain ASCII (Base64) armored data prefixed with a «—– BEGIN …» line. These files may also bear the cer
or the crt
extension..der
— The DER extension is used for binary DER encoded certificates.openssl req -new -sha256 -key server.key -out server.csr
openssl x509 -req -sha256 -in server.csr -signkey server.key -out server.crt -days 3650
-check
openssl ecparam -list_curves
-param_enc explicit
-conv_form compressed
-genkey
Distro | Package | Path to CA |
---|---|---|
Fedora, RHEL, CentOS | ca-certificates | /etc/pki/tls/certs/ca-bundle.crt |
Debian, Ubuntu, Gentoo, Arch Linux | ca-certificates | /etc/ssl/certs/ca-certificates.crt |
SUSE, openSUSE | ca-certificates | /etc/ssl/ca-bundle.pem |
FreeBSD | ca_root_nss | /usr/local/share/certs/ca-root-nss.crt |
Cygwin | - | /usr/ssl/certs/ca-bundle.crt |
macOS (MacPorts) | curl-ca-bundle | /opt/local/share/curl/curl-ca-bundle.crt |
Default cURL CA bunde path (without --with-ca-bundle option) | /usr/local/share/curl/curl-ca-bundle.crt | |
Really old RedHat? | /usr/share/ssl/certs/ca-bundle.crt |
blog.bracelab.com
superuser.com
(Stack Exchange)
gist.github.com/spikebike
echo.labstack.com/guide
guyrutenberg.com
kaihag.com
blog.cloudflare.com
gist.github.com
gist.github.com
net.Listener
with various performance-related options