英文:
"failed to find any PEM data in certificate input" error popup by tls.X509KeyPair
问题
我正在尝试使用Golang的x509包为HTTPS服务器生成TLS证书,但是遇到了以下错误:
tls: 在证书输入中找不到任何PEM数据
经过一些研究,我按照以下方式创建了我的证书:
func Generatecert() {
ca := &x509.Certificate{
SerialNumber: big.NewInt(2023),
Subject: pkix.Name{
Organization: []string{"Company"},
OrganizationalUnit: []string{"lol"},
Country: []string{"US"},
Province: []string{""},
Locality: []string{"NY"},
StreetAddress: []string{"No street"},
PostalCode: []string{"77777"},
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
SubjectKeyId: []byte{1, 2, 3, 4, 5},
BasicConstraintsValid: true,
IsCA: true,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
}
certpubl, certpriv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
log.Println("key generate failed", err)
return
}
certCert, err := x509.CreateCertificate(rand.Reader, ca, ca, certpubl, certpriv)
if err != nil {
log.Println("create cert failed", err)
return
}
out := &bytes.Buffer{}
// 编码证书
certtestpem := &pem.Block{Type: "CERTIFICATE", Bytes: certCert}
pem.Encode(out, certtestpem)
publicCert := out.Bytes()
certDERBlock, publicCert := pem.Decode(publicCert)
// 检查解码后的证书
print(certDERBlock.Type, "\n")
if publicCert != nil {
print("publicCert nil\n")
}
// 编码私钥
out.Reset()
privatepem, _ := x509.MarshalPKCS8PrivateKey(certpriv)
pem.Encode(out, &pem.Block{Type: "PRIVATE KEY", Bytes: privatepem})
privitKey := out.Bytes()
// 检查密钥对
_, err = tls.X509KeyPair(publicCert, privitKey)
if err != nil {
print(err.Error())
}
}
它显示以下错误:
CERTIFICATE
publicCert nil
tls: 在证书输入中找不到任何PEM数据
我尝试在pem.EncodeToMemory
之后进行解码,pem.Type
是正确的,但变量publicCert
是nil
。我尝试在证书前面添加\n
,但没有任何效果,但证书本身不是nil
。有人可以帮我解决这个问题吗?
我应该怎么做才能创建一个可用的TLS证书?
英文:
I am trying to make are tls cert for HTTPS server by golang x509 package
and i got this error
> tls: failed to find any PEM data in certificate input
After some research, I create my Cert like this
func Generatecert() {
ca := &x509.Certificate{
SerialNumber: big.NewInt(2023),
Subject: pkix.Name{
Organization: []string{"Company"},
OrganizationalUnit: []string{"lol"},
Country: []string{"US"},
Province: []string{""},
Locality: []string{"NY"},
StreetAddress: []string{"No street"},
PostalCode: []string{"77777"},
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
SubjectKeyId: []byte{1, 2, 3, 4, 5},
BasicConstraintsValid: true,
IsCA: true,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
}
certpubl, certpriv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
log.Println("key generate failed", err)
return
}
certCert, err := x509.CreateCertificate(rand.Reader, ca, ca, certpubl, certpriv)
if err != nil {
log.Println("create cert failed", err)
return
}
out := &bytes.Buffer{}
//Encoding cert
certtestpem := &pem.Block{Type: "CERTIFICATE", Bytes: certCert}
pem.Encode(out, certtestpem)
publicCert := out.Bytes()
certDERBlock, publicCert := pem.Decode(publicCert)
//Check Decoded cert
print(certDERBlock.Type, "\n")
if publicCert != nil {
print("publicCert nil\n")
}
//Encoding Private Key
out.Reset()
privatepem, _ := x509.MarshalPKCS8PrivateKey(certpriv)
pem.Encode(out, &pem.Block{Type: "PRIVATE KEY", Bytes: privatepem})
privitKey := out.Bytes()
//check KeyPair
_, err = tls.X509KeyPair(publicCert, privitKey)
if err != nil {
print(err.Error())
}
}
it show the error like under
> CERTIFICATE
>
> publicCert nil
>
> tls: failed to find any PEM data in certificate input
I try Decode after pem.EncodeToMemory
the pem.Type are correct, but variable "publicCert" is nil, And I try add are \n begin of the cert, it did nothing, but the cert itself is not nil, Can Somebody Help me with this
What sould I do to make a working Tls???
答案1
得分: 0
经过一些调试,似乎 pem.Encode 函数对我不起作用,
所以我将其更改为 pem.EncodeToMemory,现在它可以工作了,谢谢你的帮助。
英文:
after some debug, it seem like the pem.Encode function not working for me,
so i change it to pem.EncodeToMemory and it working thank you for the help.
答案2
得分: 0
这段代码存在几个问题:
publicCert := out.Bytes()
在这个阶段检查publicCert
的内容显示了预期的值。但是接下来的语句会简单地覆盖publicCert
:
certDERBlock, publicCert := pem.Decode(publicCert)
通过在这个语句之后检查publicCert
可以看出这一点。根据文档所述,publicCert
现在将显示实际证书之后的数据。
应该改为:
certDERBlock, _ := pem.Decode(publicCert)
在纠正了这个语句之后,检查publicCert
的内容再次显示了预期的值。
out.Reset()
privatepem, _ := x509.MarshalPKCS8PrivateKey(certpriv)
pem.Encode(out, &pem.Block{Type: "PRIVATE KEY", Bytes: privatepem})
privitKey := out.Bytes()
这将把预期的值放入privitKey
中。但是,它会改变publicCert
,因为它只是out
的一个切片,而out
已经被这些操作改变了。因此,out
现在在开头包含privitKey
,而不再包含证书的开头部分,这在publicCert
的值中反映出来。
切片只在下一次缓冲区修改之前有效使用(也就是说,只在下一次调用Read、Write、Reset或Truncate等方法之前有效)。
所以,不仅仅重置现有的缓冲区:
out.Reset()
更好的做法是为privitKey
创建一个新的缓冲区,并保留现有的缓冲区用于publicCert
:
out = &bytes.Buffer{}
英文:
There are several problems in this code
> publicCert := out.Bytes()
Checking the content of publicCert
at this stage shows the expect value. But the following statement will simply overwrite publicCert
:
> certDERBlock, publicCert := pem.Decode(publicCert)
This can be seen by checking publicCert
after this statement. As documented publicCert
will now show the data after the actual certificate.
It should be instead
certDERBlock, _ := pem.Decode(publicCert)
Checking the content of publicCert
after this corrected statement shows the expected value again.
> out.Reset()
> privatepem, _ := x509.MarshalPKCS8PrivateKey(certpriv)
> pem.Encode(out, &pem.Block{Type: "PRIVATE KEY", Bytes: privatepem})
> privitKey := out.Bytes()
This will get the expected value into privitKey
. But, it will change publicCert
since it is just a slice of out
and out
has been changed the the operations. Thus out
will now contain at the beginning the privitKey
and no longer the start of the certificate - and this is reflected in the value of publicCert
.
See also the documentation for bytes.Buffer.Bytes
> The slice is valid for use only until the next buffer modification (that is, only until the next call to a method like Read, Write, Reset, or Truncate)
So instead of just resetting the existing buffer
> out.Reset()
it would be better to create a new buffer for privitKey
and keep the existing one for publicCert
> out = &bytes.Buffer{}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论