数字证书和golang的研究

  • Post author:
  • Post category:golang




数字证书和golang的研究

在go语言提供的系统包中包含了大量和数字证书有关的方法。在这些方法中就有私钥生成的方法、私钥解析的方法、证书请求生成的方法、证书生成的方法等等。通过这些方法应该能够实现和openssl命令类似的功能。

仿照openssl生成证书的流程(从私钥的生成—>证书请求的生成—>证书的生成)用go语言进行模拟。



私钥的生成

在go的x509包下有go定义的证书的结构,该结构如下:

        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 []pkix.Extension
        ExtraExtensions []pkix.Extension
        UnhandledCriticalExtensions []asn1.ObjectIdentifier
        ExtKeyUsage        []ExtKeyUsage           // Sequence of extended key usages.
        UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package.
        BasicConstraintsValid bool // if true then the next two fields are valid.
        IsCA                  bool
        MaxPathLen            int
        MaxPathLenZero bool

        SubjectKeyId   []byte
        AuthorityKeyId []byte
        OCSPServer            []string
        IssuingCertificateURL []string

        // Subject Alternate Name values
        DNSNames       []string
        EmailAddresses []string
        IPAddresses    []net.IP
        PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical.
        PermittedDNSDomains         []string
        CRLDistributionPoints []string
        PolicyIdentifiers []asn1.ObjectIdentifier

在该结构中有

PublicKeyAlgorithm

字段,该字段用来表示生成公钥的算法。该字段的变量中可使用的字段如下:

const (
        UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota
        RSA
        DSA
        ECDSA
)

一共定义了4中情况。除去Unknown的情况。剩下的三种的实现分别在

crypto/rsa



crypto/dsa



crypto/ecdsa

这三个包中定义了实现。



RSA

使用RSA方法生成公私钥的方式非常简单。在

crypto/rsa

包中直接提供了生成方法。

func GenerateKey(random io.Reader, bits int) (*PrivateKey, error)
  • 1

该方法生成一个rsa的私钥。查找整个包所提供的方法并没有什么方法能够生成公钥。但在包中有公钥的结构说明。查看私钥的结构:

type PrivateKey struct {
        PublicKey            // public part.
        D         *big.Int   // private exponent
        Primes    []*big.Int // prime factors of N, has >= 2 elements.
        Precomputed PrecomputedValues
}

赫然发现,公钥包含在私钥的结构中。换句话说,只要生成的私钥,公钥就同时拥有了(ECDSA和DSA的公钥也是如此)。



ECDSA

使用ECDSA生成公私钥的方式和RSA的方式非常类似:



版权声明:本文为ffzhihua原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。