Golang Mqtt客户端TLS实现

huangapple go评论88阅读模式
英文:

Golang Mqtt Client TLS Implementation

问题

我尝试给"github.com/eclipse/paho.mqtt.golang"客户端包添加TLS配置。然而,在配置中,PEM证书是从文件中加载的。我想要将PEM证书作为字符串格式使用。例如,一个对象有一个"caPem"键,其值是作为字符串的CA PEM证书。

如上所示的代码中,pemCerts从文件中获取公钥。函数参数"caCertificate..."是字符串。我只想像这样使用它们:"pemCerts := caCertificate"。我该如何实现这个?

英文:

I try to add tls config to "github.com/eclipse/paho.mqtt.golang" client package. However in the config pems load from a file. I want to use pem as string format. For example an object has "caPem" key and its value CA pem as string.

func NewTLSConfig(cACertificate, clientCertificate, clientKey string) *tls.Config {

	certpool := x509.NewCertPool()

	pemCerts, err := ioutil.ReadFile("/ca.pem")
	if err == nil {
		certpool.AppendCertsFromPEM(pemCerts)
	}

	cert, err := tls.LoadX509KeyPair("/client.pem", "/client.key")
	if err != nil {
		panic(err)
	}

	cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
	if err != nil {
		panic(err)
	}
	fmt.Println(cert.Leaf)

	return &tls.Config{

		RootCAs: certpool,

		ClientAuth: tls.RequestClientCert,

		ClientCAs: nil,

		InsecureSkipVerify: false,

		Certificates: []tls.Certificate{cert},
	}
}

As you see above code , pemCerts get public key from a file. Functions parameters "caCertificate..." are string. I just want to use them like "pemCerts := caCertificate". How can I implement this

答案1

得分: 2

这是一个示例,演示了如何进行操作。它假设您的字符串中只有一个PEM块。如果有多个PEM块,您需要适应性地多次调用strPEMToPubCert

package main

import (
	"crypto/x509"
	"encoding/pem"
	"errors"
	"fmt"
)

func main() {
	var pubPEMData = `-----BEGIN CERTIFICATE-----
MIIG9TCCBd2gAwIBAgISBLS106X/pLzr6OgL1QIQaFjHMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yMTEyMDUxNDE1NTJaFw0yMjAzMDUxNDE1NTFaMB4xHDAaBgNVBAMM
Eyouc3RhY2tleGNoYW5nZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQCad2WyTsmxXwoyz/iQST49XuSAciGr8GcyUtrestK82l4uHvU0/eCsxkUa
nT6xpm60l9OaAXCjJHEl9+0qKOUQ8+FJzr4W9PuiALE1E6j5mpYk3FRERZwX+AFZ
dN2G1rSb+uZvDSiR9eUikj0ueR5TTA+ZUsNLaByE+/EzcUqja9Qxyq7zkizSolxy
/RVTRPB2BaDkGY4I46avu8PJPm6R3skp0L96MnWSDVtJhIGc5lisoUEozrlTbTuT
SfBvPAAIqFT6702LJqFIF5rW04++GrEBh6S1I+17IZxneTMcorx0sYmXVzRGvz6e
0nOfXo6a80hAFgs+vci3UWEze7vrAgMBAAGjggQXMIIEEzAOBgNVHQ8BAf8EBAMC
BaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAw
HQYDVR0OBBYEFMbQN0TT6bdr8CA4WpQ9UwT/XKTZMB8GA1UdIwQYMBaAFBQusxe3
WFbLrlAJQOYfr52LFMLGMFUGCCsGAQUFBwEBBEkwRzAhBggrBgEFBQcwAYYVaHR0
cDovL3IzLm8ubGVuY3Iub3JnMCIGCCsGAQUFBzAChhZodHRwOi8vcjMuaS5sZW5j
ci5vcmcvMIIB5AYDVR0RBIIB2zCCAdeCDyouYXNrdWJ1bnR1LmNvbYISKi5ibG9n
b3ZlcmZsb3cuY29tghIqLm1hdGhvdmVyZmxvdy5uZXSCGCoubWV0YS5zdGFja2V4
Y2hhbmdlLmNvbYIYKi5tZXRhLnN0YWNrb3ZlcmZsb3cuY29tghEqLnNlcnZlcmZh
dWx0LmNvbYINKi5zc3RhdGljLm5ldIITKi5zdGFja2V4Y2hhbmdlLmNvbYITKi5z
dGFja292ZXJmbG93LmNvbYIVKi5zdGFja292ZXJmbG93LmVtYWlsgg8qLnN1cGVy
dXNlci5jb22CDWFza3VidW50dS5jb22CEGJsb2dvdmVyZmxvdy5jb22CEG1hdGhv
dmVyZmxvdy5uZXSCFG9wZW5pZC5zdGFja2F1dGguY29tgg9zZXJ2ZXJmYXVsdC5j
b22CC3NzdGF0aWMubmV0gg1zdGFja2FwcHMuY29tgg1zdGFja2F1dGguY29tghFz
dGFja2V4Y2hhbmdlLmNvbYISc3RhY2tvdmVyZmxvdy5ibG9nghFzdGFja292ZXJm
bG93LmNvbYITc3RhY2tvdmVyZmxvdy5lbWFpbIIRc3RhY2tzbmlwcGV0cy5uZXSC
DXN1cGVydXNlci5jb20wTAYDVR0gBEUwQzAIBgZngQwBAgEwNwYLKwYBBAGC3xMB
AQEwKDAmBggrBgEFBQcCARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcwggEF
BgorBgEEAdZ5AgQCBIH2BIHzAPEAdwDfpV6raIJPH2yt7rhfTj5a6s2iEqRqXo47
EsAgRFwqcwAAAX2LKmpMAAAEAwBIMEYCIQC1jB7OwpQiHacbVnEZgWegpCOksm6Z
TYkTjXCmIo9m1AIhAPjs+1PPNr/avFzSydhUROI+Rvqx0iZqXzNc24PIOXjBAHYA
KXm+8J45OSHwVnOfY6V35b5XfZxgCvj5TV0mXCVdx4QAAAF9iypqRAAABAMARzBF
AiEA0oJ418l3aDXj4EVAtzf5o2nUdYiZiH7pLvA1hd7ZSKUCICFeACPl73NNLSzR
7yoKEV6nO7Zlk4rUd/fUyROY35OMMA0GCSqGSIb3DQEBCwUAA4IBAQB+hvmbEaHF
jEkSZiTllNe+XWtfz6TiWIugoqdDL67app49ZTTZ94oLRGxybm62nBIEX/2gCRgd
fqnDecg4BWIyl2jti73eKkmt9+pcCDqZ1JcbW8rDLmZJnzdcC0o739BGRq/ufP5R
Fb8qXAap2VH/29MQImxB166PsAb9rKdS1kNSfg4Zsu7nisg7q47dyzZMT9cTbajf
D/T6hl30nHOyJFvny5vYwDLtiNg5BJ2xZzZFh4B73mY53jjN2EXn4S5LI9J+0NmY
dic7TY+lsttvfrJ+cySMO7E1T1SkgEgHtfsadlRRWNFl80R91sS98FHbhBg/MSMk
yAm4xgff5rYD
-----END CERTIFICATE-----`

	crt, _, err := strPEMToPubCert(pubPEMData)
	if err != nil {
		panic(err)
	}

	fmt.Println(crt.DNSNames)
}

func strPEMToPubCert(pemStr string) (*x509.Certificate, []byte, error) {
	block, rest := pem.Decode([]byte(pemStr))
	if block == nil || block.Type != "CERTIFICATE" {
		return nil, rest, errors.New("failed to decode PEM block containing certificate")
	}

	cert, err := x509.ParseCertificate(block.Bytes)
	if err != nil {
		return nil, rest, err
	}

	return cert, rest, nil
}

playground链接

英文:

Made an example, of how to this this. It does assume that you do not have more than 1 PEM block in the string. If you do you should adapt it to call strPEMToPubCert multiple times.

(playground link)

package main

import (
	"crypto/x509"
	"encoding/pem"
	"errors"
	"fmt"
)

func main() {
	var pubPEMData = `-----BEGIN CERTIFICATE-----
MIIG9TCCBd2gAwIBAgISBLS106X/pLzr6OgL1QIQaFjHMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yMTEyMDUxNDE1NTJaFw0yMjAzMDUxNDE1NTFaMB4xHDAaBgNVBAMM
Eyouc3RhY2tleGNoYW5nZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQCad2WyTsmxXwoyz/iQST49XuSAciGr8GcyUtrestK82l4uHvU0/eCsxkUa
nT6xpm60l9OaAXCjJHEl9+0qKOUQ8+FJzr4W9PuiALE1E6j5mpYk3FRERZwX+AFZ
dN2G1rSb+uZvDSiR9eUikj0ueR5TTA+ZUsNLaByE+/EzcUqja9Qxyq7zkizSolxy
/RVTRPB2BaDkGY4I46avu8PJPm6R3skp0L96MnWSDVtJhIGc5lisoUEozrlTbTuT
SfBvPAAIqFT6702LJqFIF5rW04++GrEBh6S1I+17IZxneTMcorx0sYmXVzRGvz6e
0nOfXo6a80hAFgs+vci3UWEze7vrAgMBAAGjggQXMIIEEzAOBgNVHQ8BAf8EBAMC
BaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAw
HQYDVR0OBBYEFMbQN0TT6bdr8CA4WpQ9UwT/XKTZMB8GA1UdIwQYMBaAFBQusxe3
WFbLrlAJQOYfr52LFMLGMFUGCCsGAQUFBwEBBEkwRzAhBggrBgEFBQcwAYYVaHR0
cDovL3IzLm8ubGVuY3Iub3JnMCIGCCsGAQUFBzAChhZodHRwOi8vcjMuaS5sZW5j
ci5vcmcvMIIB5AYDVR0RBIIB2zCCAdeCDyouYXNrdWJ1bnR1LmNvbYISKi5ibG9n
b3ZlcmZsb3cuY29tghIqLm1hdGhvdmVyZmxvdy5uZXSCGCoubWV0YS5zdGFja2V4
Y2hhbmdlLmNvbYIYKi5tZXRhLnN0YWNrb3ZlcmZsb3cuY29tghEqLnNlcnZlcmZh
dWx0LmNvbYINKi5zc3RhdGljLm5ldIITKi5zdGFja2V4Y2hhbmdlLmNvbYITKi5z
dGFja292ZXJmbG93LmNvbYIVKi5zdGFja292ZXJmbG93LmVtYWlsgg8qLnN1cGVy
dXNlci5jb22CDWFza3VidW50dS5jb22CEGJsb2dvdmVyZmxvdy5jb22CEG1hdGhv
dmVyZmxvdy5uZXSCFG9wZW5pZC5zdGFja2F1dGguY29tgg9zZXJ2ZXJmYXVsdC5j
b22CC3NzdGF0aWMubmV0gg1zdGFja2FwcHMuY29tgg1zdGFja2F1dGguY29tghFz
dGFja2V4Y2hhbmdlLmNvbYISc3RhY2tvdmVyZmxvdy5ibG9nghFzdGFja292ZXJm
bG93LmNvbYITc3RhY2tvdmVyZmxvdy5lbWFpbIIRc3RhY2tzbmlwcGV0cy5uZXSC
DXN1cGVydXNlci5jb20wTAYDVR0gBEUwQzAIBgZngQwBAgEwNwYLKwYBBAGC3xMB
AQEwKDAmBggrBgEFBQcCARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcwggEF
BgorBgEEAdZ5AgQCBIH2BIHzAPEAdwDfpV6raIJPH2yt7rhfTj5a6s2iEqRqXo47
EsAgRFwqcwAAAX2LKmpMAAAEAwBIMEYCIQC1jB7OwpQiHacbVnEZgWegpCOksm6Z
TYkTjXCmIo9m1AIhAPjs+1PPNr/avFzSydhUROI+Rvqx0iZqXzNc24PIOXjBAHYA
KXm+8J45OSHwVnOfY6V35b5XfZxgCvj5TV0mXCVdx4QAAAF9iypqRAAABAMARzBF
AiEA0oJ418l3aDXj4EVAtzf5o2nUdYiZiH7pLvA1hd7ZSKUCICFeACPl73NNLSzR
7yoKEV6nO7Zlk4rUd/fUyROY35OMMA0GCSqGSIb3DQEBCwUAA4IBAQB+hvmbEaHF
jEkSZiTllNe+XWtfz6TiWIugoqdDL67app49ZTTZ94oLRGxybm62nBIEX/2gCRgd
fqnDecg4BWIyl2jti73eKkmt9+pcCDqZ1JcbW8rDLmZJnzdcC0o739BGRq/ufP5R
Fb8qXAap2VH/29MQImxB166PsAb9rKdS1kNSfg4Zsu7nisg7q47dyzZMT9cTbajf
D/T6hl30nHOyJFvny5vYwDLtiNg5BJ2xZzZFh4B73mY53jjN2EXn4S5LI9J+0NmY
dic7TY+lsttvfrJ+cySMO7E1T1SkgEgHtfsadlRRWNFl80R91sS98FHbhBg/MSMk
yAm4xgff5rYD
-----END CERTIFICATE-----`

	crt, _, err := strPEMToPubCert(pubPEMData)
	if err != nil {
		panic(err)
	}

	fmt.Println(crt.DNSNames)
}

func strPEMToPubCert(pemStr string) (*x509.Certificate, []byte, error) {
	block, rest := pem.Decode([]byte(pemStr))
	if block == nil || block.Type != "CERTIFICATE" {
		return nil, rest, errors.New("failed to decode PEM block containing certificate")
	}

	cert, err := x509.ParseCertificate(block.Bytes)
	if err != nil {
		return nil, rest, err
	}

	return cert, rest, nil
}

huangapple
  • 本文由 发表于 2022年1月4日 01:19:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/70569324.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定