1 Star 0 Fork 0

叶明志/golang练习

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
main.go 7.54 KB
一键复制 编辑 原始数据 按行查看 历史
package main
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"errors"
"fmt"
"log"
"math/big"
"net"
"net/http"
"net/http/httptest"
"net/http/httputil"
"time"
)
func test1() {
src := []byte("观察输出,加密后的数据已经是不可读的了。接下来,用私钥对加密数据进行解密")
privateKey, _ := rsa.GenerateKey(rand.Reader, 4096)
// cipherText, _ := rsa.EncryptPKCS1v15(rand.Reader, &privateKey.PublicKey, src)
// fmt.Println(string(cipherText))
// src, _ = rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherText)
// fmt.Println(string(src))
hash := sha256.Sum256(src)
// fmt.Println("hash值是:", hash)
signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hash[:])
if err != nil {
log.Fatalf("error creating signature:%v", err)
}
verify := func(pub *rsa.PublicKey, msg, signature []byte) error {
hash := sha256.Sum256(msg)
return rsa.VerifyPKCS1v15(&privateKey.PublicKey, crypto.SHA256, hash[:], signature)
}
fmt.Println(verify(&privateKey.PublicKey, src, []byte("a bad signature")))
fmt.Println(verify(&privateKey.PublicKey, []byte("a different plain text"), signature))
fmt.Println(verify(&privateKey.PublicKey, src, signature))
}
func test2() {
src := []byte("在介绍证书链之前")
//构造私钥
privKey, _ := rsa.GenerateKey(rand.Reader, 4096)
//对明文进行hash计算
hash := sha256.Sum256(src)
//生成签名
signature, _ := rsa.SignPKCS1v15(rand.Reader, privKey, crypto.SHA256, hash[:])
//定义验证算法
verify := func(pub *rsa.PublicKey, msg []byte, signature []byte) error {
hash := sha256.Sum256(msg)
return rsa.VerifyPKCS1v15(pub, crypto.SHA256, hash[:], signature)
}
//验证签名与验证
fmt.Println(verify(&privKey.PublicKey, src, []byte("wrong signature")))
fmt.Println(verify(&privKey.PublicKey, []byte("介绍整数两"), signature))
fmt.Println(verify(&privKey.PublicKey, src, signature))
}
//CreateCert 创建证书
func CreateCert(template, parent *x509.Certificate, pub interface{}, parentPriv interface{}) (
cert *x509.Certificate, certPEM []byte, err error) {
certDER, err := x509.CreateCertificate(rand.Reader, template, parent, pub, parentPriv)
if err != nil {
return
}
// parse the resulting certificate so we can use it again
cert, err = x509.ParseCertificate(certDER)
if err != nil {
return
}
//将 certDER 用 pem 编码,生成 certPEM 证书
b := pem.Block{Type: "CERTIFICATE", Bytes: certDER}
certPEM = pem.EncodeToMemory(&b)
return
}
//CertTemplate 证书模板,通过该模板默认设置一些证书需要的字段,比如序列号,组织信息,有效期等等
func CertTemplate() (*x509.Certificate, error) {
//生成随机的序列号 (不同组织可以有不同的序列号生成方式)
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return nil, errors.New("failed to generate serial number: " + err.Error())
}
tmpl := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{Organization: []string{"Yhat, Inc."}},
SignatureAlgorithm: x509.SHA256WithRSA,
NotBefore: time.Now(),
NotAfter: time.Now().Add(time.Hour), //1小时的有效期
BasicConstraintsValid: true,
}
return &tmpl, nil
}
func test3() {
//创建一对密钥
rootKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
log.Fatalln("创建一对密钥失败", err)
}
//构造证书模板
rootCertTmpl, err := CertTemplate()
if err != nil {
log.Fatalln("构造证书模板出错", err)
}
rootCertTmpl.IsCA = true
rootCertTmpl.KeyUsage = x509.KeyUsageCertSign | x509.KeyUsageDigitalSignature
rootCertTmpl.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}
rootCertTmpl.IPAddresses = []net.IP{net.ParseIP("127.0.0.1")}
//根据模板和密钥构造证书
rootCert, rootCertPEM, err := CreateCert(rootCertTmpl, rootCertTmpl, &rootKey.PublicKey, rootKey)
if err != nil {
log.Fatalln("创建证书失败")
}
//构造私钥
rootKeyPEM := pem.EncodeToMemory(&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(rootKey),
})
//构造证书
_, err = tls.X509KeyPair(rootCertPEM, rootKeyPEM)
if err != nil {
log.Fatalln("构造证书失败")
}
//客户端设置
ok := func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hi!"))
}
//第一种情况,服务端的证书不受客户端信任,因此客户端拒绝了连接.
/*
//服务器设置
s := httptest.NewUnstartedServer(http.HandlerFunc(ok))
//配置TLS到服务器上
s.TLS = &tls.Config{
Certificates: []tls.Certificate{rootTLSCert},
}
//启动服务器
s.StartTLS()
fmt.Println(s.URL)
//启动客户端
_, err = http.Get(s.URL)
s.Close()
fmt.Println(err)
*/
//对服务器进行设置,
serverKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
log.Fatalln("生成服务器密钥失败")
}
serverCertTmpl, err := CertTemplate()
if err != nil {
log.Fatalln("生成服务器证书模板失败")
}
serverCertTmpl.KeyUsage = x509.KeyUsageDigitalSignature
serverCertTmpl.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
serverCertTmpl.IPAddresses = []net.IP{net.ParseIP("127.0.0.1")}
_, serverCertPEM, err := CreateCert(serverCertTmpl, rootCert, &serverKey.PublicKey, rootKey)
if err != nil {
log.Fatalln("生成服务器证书失败")
}
//得到服务器私钥的pem文件
serverKeyPEM := pem.EncodeToMemory(&pem.Block{
Type: "RSA SERVER PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(serverKey),
})
//将服务器证书与私钥一起,构造服务器TLS文件
serverTLSCert, err := tls.X509KeyPair(serverCertPEM, serverKeyPEM)
if err != nil {
log.Fatalln("生成服务器TLS文件失败")
}
//将客户端用到的授信证书池也配置到服务端,后面也放到客户端内
certPool := x509.NewCertPool()
certPool.AppendCertsFromPEM(rootCertPEM)
s := httptest.NewUnstartedServer(http.HandlerFunc(ok))
s.TLS = &tls.Config{
Certificates: []tls.Certificate{serverTLSCert},
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: certPool,
}
//配置客户端
//生成密钥对
clientKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
log.Fatalln("客户端密钥生成失败")
}
//生成客户端证书模板
clientCertTmpl, err := CertTemplate()
if err != nil {
log.Fatalln("生成客户端证书模板失败")
}
clientCertTmpl.KeyUsage = x509.KeyUsageDigitalSignature
clientCertTmpl.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}
//根据模板生成证书
_, clientCertPEM, err := CreateCert(clientCertTmpl, rootCert, &clientKey.PublicKey, rootKey)
//生成私钥pem文件
clientKeyPEM := pem.EncodeToMemory(&pem.Block{
Type: "CLIENT PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(clientKey),
})
clientTLSCert, err := tls.X509KeyPair(clientCertPEM, clientKeyPEM)
if err != nil {
log.Fatalln("生成客户端TLS文件出错")
}
//将根CA文件放到客户端允许的证书池内
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: certPool,
Certificates: []tls.Certificate{clientTLSCert},
},
},
}
//启动服务端
s.StartTLS()
resp, err := client.Get(s.URL)
if err != nil {
log.Fatalln("启动服务端失败")
}
dump, err := httputil.DumpResponse(resp, true)
if err != nil {
log.Fatalln("没得到服务端反应")
}
fmt.Printf("%s\n", dump)
}
func main() {
// test1()
// test2()
test3()
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/yemingzhi/GolangLearnPractice1.git
git@gitee.com:yemingzhi/GolangLearnPractice1.git
yemingzhi
GolangLearnPractice1
golang练习
2bf136849dce

搜索帮助