英文:
How to get CN from a certificate in Golang
问题
在Golang中,有几种方法可以从X509证书中提取CN(通用名称)。
一种方法是使用crypto/x509
包来解析证书并获取主题信息。以下是一个示例代码:
package main
import (
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
"log"
)
func getCNFromCertificate(certPath string) (string, error) {
// 读取证书文件
certBytes, err := ioutil.ReadFile(certPath)
if err != nil {
return "", err
}
// 解码PEM格式的证书
block, _ := pem.Decode(certBytes)
if block == nil {
return "", fmt.Errorf("failed to decode PEM certificate")
}
// 解析X509证书
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return "", err
}
// 获取通用名称
commonName := cert.Subject.CommonName
return commonName, nil
}
func main() {
certPath := "path/to/certificate.pem"
commonName, err := getCNFromCertificate(certPath)
if err != nil {
log.Fatal(err)
}
fmt.Println("Common Name:", commonName)
}
另一种方法是使用第三方包,例如github.com/fullsailor/pkcs7
。这个包提供了更高级的功能,可以处理PKCS#7格式的证书。以下是一个示例代码:
package main
import (
"fmt"
"log"
"github.com/fullsailor/pkcs7"
)
func getCNFromCertificate(certPath string) (string, error) {
// 解析PKCS#7格式的证书
p7, err := pkcs7.Parse(certPath)
if err != nil {
return "", err
}
// 获取第一个证书
cert := p7.Certificates[0]
// 获取通用名称
commonName := cert.Subject.CommonName
return commonName, nil
}
func main() {
certPath := "path/to/certificate.p7"
commonName, err := getCNFromCertificate(certPath)
if err != nil {
log.Fatal(err)
}
fmt.Println("Common Name:", commonName)
}
这些示例代码可以帮助你从证书中提取CN。你可以根据自己的需求选择其中一种方法来实现。希望对你有帮助!
英文:
Is there any way to extract CN from X509Certificate in Golang.
Previously we did something like this in Java.
private String getCNFromCertificate() throws InvalidNameException, CertificateException, IOException {
X509Certificate certificate = getCert(DeploymentConfiguration.getPemCertPath().get());
String commonName = new LdapName(certificate.getSubjectX500Principal().getName()).getRdns().stream()
.filter(i -> i.getType().equalsIgnoreCase("CN")).findFirst().get().getValue().toString();
return commonName;
}
Are there any packages in Golang which can do similar task. Or what could be better alternative to extract CN from Certificate in Golang.
Thank you in advance.
答案1
得分: 1
如何加载和解析公共证书的要点:
bs, err := os.ReadFile("/tmp/google.crt") // 处理错误
block, _ := pem.Decode(bs)
if block == nil {
log.Fatal("无法解析包含公钥的PEM块")
}
cert, err := x509.ParseCertificate(block.Bytes) // 处理错误
log.Printf("主题: %q", cert.Subject)
// 主题: "CN=*.google.com"
警告:自`go 1.15`起,使用[CN存储主机名已被弃用](https://go.dev/doc/go1.15#commonname):
> 默认情况下,已禁用将X.509证书上的CommonName字段视为主机名的旧行为,当不存在Subject Alternative Names时。可以通过将值x509ignoreCN=0添加到GODEBUG环境变量中临时重新启用。
如果要在证书中查找主机名(或主机名通配符),应使用`SAN`(Subject Alternative Names)部分,其中有一个`DNS`部分。这在[x509.Certificate](https://pkg.go.dev/crypto/x509#Certificate)结构的`DNSNames`字段中捕获:
log.Printf("DNS名称: %+v", cert.DNSNames)
// DNS名称: [*.google.com *.appengine.google.com *.bdn.dev *.origin-test.bdn.dev *.cloud.google.com ...
---
[Playground示例](https://go.dev/play/p/g7gKzfLw-Gn)
英文:
The gist of how to load & parse a public cert:
bs, err := os.ReadFile("/tmp/google.crt") // handle error
block, _ := pem.Decode(bs)
if block == nil {
log.Fatal("failed to parse PEM block containing the public key")
}
cert, err := x509.ParseCertificate(block.Bytes) // handle error
log.Printf("Subject: %q", cert.Subject)
// Subject: "CN=*.google.com"
Warning: since go 1.15
the use of CN to store hostnames is now deprecated:
> The deprecated, legacy behavior of treating the CommonName field on
> X.509 certificates as a host name when no Subject Alternative Names
> are present is now disabled by default. It can be temporarily
> re-enabled by adding the value x509ignoreCN=0 to the GODEBUG
> environment variable.
If you want to find a hostname (or hostname wildcard) within a certification, one should use the SAN
(Subject Alternative Names) section - where there is a DNS
section. This is captured in the DNSNames
field of the x509.Certificate struct:
log.Printf("DNS names: %+v", cert.DNSNames)
// DNS names: [*.google.com *.appengine.google.com *.bdn.dev *.origin-test.bdn.dev *.cloud.google.com ...
答案2
得分: 0
问题的形式不正确,我认为:在X.509证书中没有"CN"这样的东西。CN是"Common Name"的缩写,是在X.509 PKI中用来指代实体的一种形式。你可能想要的是证书的"Subject"字段,也就是该证书所颁发给的实体。
如果是这样,你需要使用x509.Certificate
的Subject
字段,它是一个特殊的复合数据类型,包含了CommonName
等信息。
参考这个链接快速了解CN在实体命名中的作用。
crypto/x509
是一个库包(即Go标准库提供的)。
英文:
The question is ill-formed, I tink: there's no such thing as "CN" in an X.509 certificate. CN is an abbreviation for "Common Name", which is one form of referring to entities in the X.509 PKI. What you're probably after is the "Subject" field of a certificate—that is, the entity who that certificate was issued for.
If so, you need the Subject
field of x509.Certificate
, which is a special compound data type containing CommonName
, among other things.
See this for a quick overview of what place the CN takes in naming an entity.
The crypto/x509
is a stock package (that is, provided by the Go's standard library).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论