2012-11-25 12 views

答えて

39

キーをマーシャリングするには、何らかの形式が必要です。ゴー標準ライブラリでサポートされている1つのフォーマットは、ここで見つけることができます:http://golang.org/pkg/crypto/x509/#MarshalPKCS1PrivateKey

func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte 

逆関数はhttp://golang.org/pkg/crypto/x509/#ParsePKCS1PrivateKeyです。

func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err error) 

しかし、PEMファイルにマーシャリングキーをエンコードするために比較的標準的です。

pemdata := pem.EncodeToMemory(
    &pem.Block{ 
     Type: "RSA PRIVATE KEY", 
     Bytes: x509.MarshalPKCS1PrivateKey(key), 
    }, 
) 

hereの完全な例があります。

+1

公共の部分ですか? –

15

あなたの質問の公開鍵部分が答えて、私はちょうど同じ問題に遭遇し、それを解決していなかったので、ここにある:

MarshalPKIXPublicKey

への引数の前で&
Priv := rsa.GenerateKey(rand.Reader, 4096) 

PubASN1, err := x509.MarshalPKIXPublicKey(&Priv.PublicKey) 
if err != nil { 
    // do something about it 
} 

pubBytes = pem.EncodeToMemory(&pem.Block{ 
    Type: "RSA PUBLIC KEY", 
    Bytes: PubASN1, 
}) 

ioutil.WriteFile("key.pub", PubBytes, 0644) 

関連読み:

  • MarshalPKIXPublicKey(パブインタフェース{})([]バイト、エラー)godoc
  • EncodeToMemory(b *のブロック)[]バイトgodoc
  • ブロックgodoc

PS:MarshalPKIXPublicKeyもajust、ECDSAキーを受け付けpemヘッダーを適切に設定します。

6

パブリックキーとプライベートキーの両方のインポートとエクスポートを示すコードスニペットです。これは、他の回答に基づいていますスーパーヘルプだけでなく、コピーパスタの公式ドキュメントからです。

package main 

import (
    "crypto/rand" 
    "crypto/rsa" 
    "crypto/x509" 
    "encoding/pem" 
    "errors" 
    "fmt" 
) 

func GenerateRsaKeyPair() (*rsa.PrivateKey, *rsa.PublicKey) { 
    privkey, _ := rsa.GenerateKey(rand.Reader, 4096) 
    return privkey, &privkey.PublicKey 
} 

func ExportRsaPrivateKeyAsPemStr(privkey *rsa.PrivateKey) string { 
    privkey_bytes := x509.MarshalPKCS1PrivateKey(privkey) 
    privkey_pem := pem.EncodeToMemory(
      &pem.Block{ 
        Type: "RSA PRIVATE KEY", 
        Bytes: privkey_bytes, 
      }, 
    ) 
    return string(privkey_pem) 
} 

func ParseRsaPrivateKeyFromPemStr(privPEM string) (*rsa.PrivateKey, error) { 
    block, _ := pem.Decode([]byte(privPEM)) 
    if block == nil { 
      return nil, errors.New("failed to parse PEM block containing the key") 
    } 

    priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) 
    if err != nil { 
      return nil, err 
    } 

    return priv, nil 
} 

func ExportRsaPublicKeyAsPemStr(pubkey *rsa.PublicKey) (string, error) { 
    pubkey_bytes, err := x509.MarshalPKIXPublicKey(pubkey) 
    if err != nil { 
      return "", err 
    } 
    pubkey_pem := pem.EncodeToMemory(
      &pem.Block{ 
        Type: "RSA PUBLIC KEY", 
        Bytes: pubkey_bytes, 
      }, 
    ) 

    return string(pubkey_pem), nil 
} 

func ParseRsaPublicKeyFromPemStr(pubPEM string) (*rsa.PublicKey, error) { 
    block, _ := pem.Decode([]byte(pubPEM)) 
    if block == nil { 
      return nil, errors.New("failed to parse PEM block containing the key") 
    } 

    pub, err := x509.ParsePKIXPublicKey(block.Bytes) 
    if err != nil { 
      return nil, err 
    } 

    switch pub := pub.(type) { 
    case *rsa.PublicKey: 
      return pub, nil 
    default: 
      break // fall through 
    } 
    return nil, errors.New("Key type is not RSA") 
} 

func main() { 

    // Create the keys 
    priv, pub := GenerateRsaKeyPair() 

    // Export the keys to pem string 
    priv_pem := ExportRsaPrivateKeyAsPemStr(priv) 
    pub_pem, _ := ExportRsaPublicKeyAsPemStr(pub) 

    // Import the keys from pem string 
    priv_parsed, _ := ParseRsaPrivateKeyFromPemStr(priv_pem) 
    pub_parsed, _ := ParseRsaPublicKeyFromPemStr(pub_pem) 

    // Export the newly imported keys 
    priv_parsed_pem := ExportRsaPrivateKeyAsPemStr(priv_parsed) 
    pub_parsed_pem, _ := ExportRsaPublicKeyAsPemStr(pub_parsed) 

    fmt.Println(priv_parsed_pem) 
    fmt.Println(pub_parsed_pem) 

    // Check that the exported/imported keys match the original keys 
    if priv_pem != priv_parsed_pem || pub_pem != pub_parsed_pem { 
      fmt.Println("Failure: Export and Import did not result in same Keys") 
    } else { 
      fmt.Println("Success") 
    } 
} 
+0

最後に検証が少し問題:条件は '||'でなく '&&' – Max

関連する問題