golang读取证书中的SubjectAlternativeNames(扩展字段)

2 篇文章 0 订阅

简述

任务:在实际开发中需要使用golang读取证书中SubjectAlternativeNames字段的内容。标准证书是由ASN1编码生成的,Java可以使用java.security.cert包中的X509Certificate类中getSubjectAlternativeNames()方法来提取这个扩展字段的内容。golang官方库中提供了X509这个包来实现asn1编码,其所对应的证书字段为:


// A Certificate represents an X.509 certificate.

type Certificate struct {

	Raw                     []byte // Complete ASN.1 DER content (certificate, signature algorithm and signature).

	RawTBSCertificate       []byte // Certificate part of raw ASN.1 DER content.

	RawSubjectPublicKeyInfo []byte // DER encoded SubjectPublicKeyInfo.

	RawSubject              []byte // DER encoded Subject

	RawIssuer               []byte // DER encoded Issuer



	Signature          []byte

	SignatureAlgorithm SignatureAlgorithm



	PublicKeyAlgorithm PublicKeyAlgorithm

	PublicKey          interface{}



	Version             int

	SerialNumber        *big.Int

	Issuer              pkix.Name

	Subject             pkix.Name

	NotBefore, NotAfter time.Time // Validity bounds.

	KeyUsage            KeyUsage



	// Extensions contains raw X.509 extensions. When parsing certificates,

	// this can be used to extract non-critical extensions that are not

	// parsed by this package. When marshaling certificates, the Extensions

	// field is ignored, see ExtraExtensions.

	Extensions []pkix.Extension



	// ExtraExtensions contains extensions to be copied, raw, into any

	// marshaled certificates. Values override any extensions that would

	// otherwise be produced based on the other fields. The ExtraExtensions

	// field is not populated when parsing certificates, see Extensions.

	ExtraExtensions []pkix.Extension



	// UnhandledCriticalExtensions contains a list of extension IDs that

	// were not (fully) processed when parsing. Verify will fail if this

	// slice is non-empty, unless verification is delegated to an OS

	// library which understands all the critical extensions.

	//

	// Users can access these extensions using Extensions and can remove

	// elements from this slice if they believe that they have been

	// handled.

	UnhandledCriticalExtensions []asn1.ObjectIdentifier



	ExtKeyUsage        []ExtKeyUsage           // Sequence of extended key usages.

	UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package.



	// BasicConstraintsValid indicates whether IsCA, MaxPathLen,

	// and MaxPathLenZero are valid.

	BasicConstraintsValid bool

	IsCA                  bool



	// MaxPathLen and MaxPathLenZero indicate the presence and

	// value of the BasicConstraints' "pathLenConstraint".

	//

	// When parsing a certificate, a positive non-zero MaxPathLen

	// means that the field was specified, -1 means it was unset,

	// and MaxPathLenZero being true mean that the field was

	// explicitly set to zero. The case of MaxPathLen==0 with MaxPathLenZero==false

	// should be treated equivalent to -1 (unset).

	//

	// When generating a certificate, an unset pathLenConstraint

	// can be requested with either MaxPathLen == -1 or using the

	// zero value for both MaxPathLen and MaxPathLenZero.

	MaxPathLen int

	// MaxPathLenZero indicates that BasicConstraintsValid==true

	// and MaxPathLen==0 should be interpreted as an actual

	// maximum path length of zero. Otherwise, that combination is

	// interpreted as MaxPathLen not being set.

	MaxPathLenZero bool



	SubjectKeyId   []byte

	AuthorityKeyId []byte



	// RFC 5280, 4.2.2.1 (Authority Information Access)

	OCSPServer            []string

	IssuingCertificateURL []string



	// Subject Alternate Name values. (Note that these values may not be valid

	// if invalid values were contained within a parsed certificate. For

	// example, an element of DNSNames may not be a valid DNS domain name.)

	DNSNames       []string

	EmailAddresses []string

	IPAddresses    []net.IP

	URIs           []*url.URL



	// Name constraints

	PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical.

	PermittedDNSDomains         []string

	ExcludedDNSDomains          []string

	PermittedIPRanges           []*net.IPNet

	ExcludedIPRanges            []*net.IPNet

	PermittedEmailAddresses     []string

	ExcludedEmailAddresses      []string

	PermittedURIDomains         []string

	ExcludedURIDomains          []string



	// CRL Distribution Points

	CRLDistributionPoints []string



	PolicyIdentifiers []asn1.ObjectIdentifier

}

通过查阅相关的文档,我发现golang中的Extensions即x509证书中的扩展项,如果要读取证书中这个字段的内容,只需要直接使用如下的代码:


certDERBlock, _ := pem.Decode(cert)//cert为byte数组,证书字节流

x509Cert, _ := x509.ParseCertificate(certDERBlock.Bytes)

strTemp := x509Cert.Extensions //取得了扩展字段

此时,回到最初的问题,我们需要从Java中对应的代码中取得SubjectAlternativeNames,在Java中debug定位发现,存入扩展字段中的需要提取的目的字段为:


[5]: ObjectId: 2.5.29.17 Criticality=false

SubjectAlternativeName [

  IPAddress: 10.33.102.9

  URIName: http://SecurityMgmtMicroService.SecurityMgmtService.huawei.com

]

从这里可以看出,该字段对应的asn1.ObjectIdentifier为2.5.29.17(注意:一个ObjectIdentifier表示一个 ASN.1 对象标识符。),因此可以采用如下的方式发现这个字段


for _, value := range strTemp

if strings.Compare(value.Id.String() , "2.5.29.17") == 0{

}

提取了这个字段之后,该如何解析这个字段的内容呢?

此时需要使用ASN1反序列化解析,要与生成证书中ASN1序列化的方式一一对应。针对我面临的问题,使用如下的方式反序列化:


		for _, value := range strTemp {

			if strings.Compare(value.Id.String(), "2.5.29.17") == 0 {

				var val []asn1.RawValue

				_, err1 := asn1.Unmarshal(value.Value, &val)

				if err1 != nil {

					log.Print(err1)

				}

				for _, asnVal := range val {

					strA := string(asnVal.Bytes)

					if strings.Contains(strA, "http://") {

						nameUrl := strA[len("http://"):]

						nameArr := strings.Split(nameUrl, ".")

						microServiceName = nameArr[0]

						serviceName = nameArr[1]

						break

					} else{

						microServiceName = ""

						serviceName = ""

					}

				}

			}

		}

总结

证书如果按照X509标准来生成,go中提供了ASN1库来序列化和反序列化证书中的字段内容。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值