LoginSignup
8
7

More than 3 years have passed since last update.

GolangでPKI入門 - 1

Last updated at Posted at 2019-09-20

1. この記事の対象のひと

  • GolangでRSA秘密鍵・公開鍵(PEM・DER形式)を作りたい人
  • GolangでSubjectPublicKeyInfo(PEM・DER形式)を作りたい人
  • GolangでPrivateKeyInfo(PEM・DER形式)を作りたい人

2. GolangでRSA秘密鍵作成

以下エラー処理は省略しますので悪しからず

2048bitのRSA秘密鍵作成

    //PKCS#1 format RSA PrivateKey [RFC8017]
    rsaPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048)

DER形式で保存する

    derRsaPrivateKey := x509.MarshalPKCS1PrivateKey(rsaPrivateKey)
    f, err := os.Create("derFormatRsaPrivate.key")
    _, err = f.Write(derRsaPrivateKey)
    err = f.Close()

保存したDER形式のRSA秘密鍵をOpenSSLコマンドで確認する

openssl rsa -text -inform der -in derFormatRsaPrivate.key

PEM形式で保存する

    f, err = os.Create("pemFormatRsaPrivate.key")
    err = pem.Encode(f, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: derRsaPrivateKey})
    err = f.Close()

保存したPEM形式のRSA秘密鍵をOpenSSLコマンドで確認する

openssl rsa -text -in pemFormatRsaPrivate.key

3. GolangでRSA公開鍵作成

2048bitのRSA公開鍵の作成

    //PKCS#1 format RSA PublicKey [RFC8017]
    var rsaPublicKey crypto.PublicKey
    rsaPublicKey = rsaPrivateKey.Public()

DER形式で保存する

    var derRsaPublicKey []byte
    if rsaPublicKeyPointer, ok := rsaPublicKey.(*rsa.PublicKey); ok {
        derRsaPublicKey = x509.MarshalPKCS1PublicKey(rsaPublicKeyPointer)
    }
    f, err = os.Create("derFormatRsaPublic.key")
    _, err = f.Write(derRsaPublicKey)
    err = f.Close()

保存したDER形式のRSA公開鍵をOpenSSLコマンドで確認する

openssl rsa -text -RSAPublicKey_in -inform der -in derFormatRsaPublic.key

PEM形式で保存する

    f, err = os.Create("pemFormatRsaPublic.key")
    err = pem.Encode(f, &pem.Block{Type: "RSA PUBLIC KEY", Bytes: derRsaPublicKey})
    err = f.Close()

保存したPEM形式のRSA公開鍵をOpenSSLコマンドで確認する

openssl rsa -text -RSAPublicKey_in -in pemFormatRsaPublic.key

4. GolangでSubjectPublicKeyInfo作成

あんまり需要はないきがしますが...

SubjectPublicKeyInfo作成

    //[RFC5280]
    publicKeyInfo, err := x509.MarshalPKIXPublicKey(rsaPublicKey)

DER形式で保存する

    //拡張子は適当
    f, err = os.Create("subjectPublicKeyInfo.der")
    _, err = f.Write(publicKeyInfo)
    err = f.Close()

PEM形式で保存する

    //拡張子は適当
    f, err = os.Create("subjectPublicKeyInfo.pem")
    err = pem.Encode(f, &pem.Block{Type: "PUBLIC KEY", Bytes: publicKeyInfo})
    err = f.Close()

保存したPEM形式のSubjectPublicKeyInfoをOpenSSLコマンドで確認する

RFC 5280に定義されたSubjectPublicKeyInfoの構造

   SubjectPublicKeyInfo  ::=  SEQUENCE  {
        algorithm            AlgorithmIdentifier,
        subjectPublicKey     BIT STRING  }

   AlgorithmIdentifier  ::=  SEQUENCE  {
        algorithm               OBJECT IDENTIFIER,
        parameters              ANY DEFINED BY algorithm OPTIONAL  }

OpenSSLのasn1parseで中身を表示

openssl asn1parse -in subjectPublicKeyInfo.pem
    0:d=0  hl=4 l= 290 cons: SEQUENCE
    4:d=1  hl=2 l=  13 cons: SEQUENCE
    6:d=2  hl=2 l=   9 prim: OBJECT            :rsaEncryption
   17:d=2  hl=2 l=   0 prim: NULL
   19:d=1  hl=4 l= 271 prim: BIT STRING

5. GolangでPrivateKeyInfo作成

PrivateKeyInfo作成

    //PKCS#8 format RSA PrivateKey [RFC5208]
    privateKeyInfo, err := x509.MarshalPKCS8PrivateKey(rsaPrivateKey)

DER形式で保存する

    //拡張子は適当
    f, err = os.Create("privateKeyInfo.der")
    _, err = f.Write(privateKeyInfo)
    err = f.Close()

PEM形式で保存する

    //拡張子は適当
    f, err = os.Create("privateKeyInfo.pem")
    err = pem.Encode(f, &pem.Block{Type: "PRIVATE KEY", Bytes: privateKeyInfo})
    err = f.Close()

保存したPEM形式のPrivateKeyInfoをOpenSSLコマンドで確認する

RFC 5208に定義されたPrivateKeyInfoの構造

   PrivateKeyInfo ::= SEQUENCE {
        version                   Version,
        privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
        privateKey                PrivateKey,
        attributes           [0]  IMPLICIT Attributes OPTIONAL }
   Version ::= INTEGER
   PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
   PrivateKey ::= OCTET STRING
   Attributes ::= SET OF Attribute

OpenSSLのasn1parseで中身を表示

$ openssl asn1parse -in privateKeyInfo.pem
    0:d=0  hl=4 l=1212 cons: SEQUENCE
    4:d=1  hl=2 l=   1 prim: INTEGER           :00
    7:d=1  hl=2 l=  13 cons: SEQUENCE
    9:d=2  hl=2 l=   9 prim: OBJECT            :rsaEncryption
   20:d=2  hl=2 l=   0 prim: NULL
   22:d=1  hl=4 l=1190 prim: OCTET STRING      [HEX DUMP]:308204A202 ~以下略~

6. コード

コードはこちら
https://github.com/tardevnull/gopkicookbook1

8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7