undefined:x509.MarshalPKCS1PublicKey在调用* rsa.PublicKey

时间:2018-02-21 09:12:34

标签: go

我无法访问PublicKey

*rsa.PrivateKey字段

每当我在下面的代码中致电x509.MarshalPKCS1PublicKey(keyBytes.PublicKey)时,我会得到:

[tony@localhost app]$ go run gencsr.go
# command-line-arguments
./gencsr.go:37:90: undefined: x509.MarshalPKCS1PublicKey

正如您所看到的,我已添加x509个包,我可以访问keyBytes.PublicKey并看到它的类型为PublicKey

来源:
crypto/x509
crypto/rsa

package main

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

var oidEmailAddress = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}

func main() {

    email := ""
    subj := pkix.Name{
        CommonName:         "example.com",
        Country:            []string{"US"},
        Province:           []string{"New York"},
        Locality:           []string{"Albany"},
        Organization:       []string{"My Company Ltd"},
        OrganizationalUnit: []string{"IT"},
    }
    bits := 4096

    key, csr := genCSR(subj, email, bits)
    fmt.Printf(key)
    fmt.Printf(csr)

}

func genCSR(subj pkix.Name, email string, bits int) (pemKey, csr string) {

    keyBytes, _ := rsa.GenerateKey(rand.Reader, bits)
    pemPubKey := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: x509.MarshalPKCS1PublicKey(keyBytes.PublicKey)}))
    pemKey = string(pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(keyBytes)}))
    fmt.Printf(pemPubKey)

    rawSubj := subj.ToRDNSequence()
    if len(email) > 0 {
        rawSubj = append(rawSubj, []pkix.AttributeTypeAndValue{
            {Type: oidEmailAddress, Value: email},
        })
    }

    asn1Subj, _ := asn1.Marshal(rawSubj)
    template := x509.CertificateRequest{
        RawSubject:         asn1Subj,
        SignatureAlgorithm: x509.SHA256WithRSA,
    }

    csrBytes, _ := x509.CreateCertificateRequest(rand.Reader, &template, keyBytes)
    csr = string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrBytes}))

    return pemKey, csr
}

2 个答案:

答案 0 :(得分:2)

x509.MarshalPKCS1PublicKey是new in Go 1.10。您可能正在运行旧版本。

如果您无法升级:the function is very simple,您只需将其复制到自己的包中即可:

// pkcs1PublicKey reflects the ASN.1 structure of a PKCS#1 public key.
type pkcs1PublicKey struct {
    N *big.Int
    E int
}

// MarshalPKCS1PublicKey converts an RSA public key to PKCS#1, ASN.1 DER form.
func MarshalPKCS1PublicKey(key *rsa.PublicKey) []byte {
    derBytes, _ := asn1.Marshal(pkcs1PublicKey{
            N: key.N,
            E: key.E,
    })
    return derBytes
}

答案 1 :(得分:0)

RSA公钥可以通过以下方式生成:

package main

import (
    "bytes"

    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "encoding/pem"
    "fmt"
    "golang.org/x/crypto/ssh"
)

func main(){
    key, b, err := generatePrivateKey()
    if err != nil{
        fmt.Println(err)
        return
    }

    fmt.Println(string(b))

    public2, err := generateSSHPublicKey(key)
    if err != nil{
        fmt.Println(err)
        return
    }
    fmt.Println(string(public2))
}

func generatePrivateKey() (*rsa.PrivateKey, []byte, error) {
    // keyBytes, err := rsa.GenerateKey(rand.Reader, 2048)
    keyBytes, err := rsa.GenerateKey(rand.Reader, 4096)
    if err != nil {
        return nil, nil, err
    }

    certBytes := new(bytes.Buffer)

    err = pem.Encode(certBytes, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(keyBytes)})
    if err != nil{
        return nil, nil, err
    }

    return keyBytes, certBytes.Bytes(), nil
}

func generateSSHPublicKey(key *rsa.PrivateKey) ([]byte, error){

    public, err := ssh.NewPublicKey(&key.PublicKey) // *rsaPublicKey
    if err != nil{
        return nil, err
    }

    certBytes := new(bytes.Buffer)

    err = pem.Encode(certBytes, &pem.Block{Type: "PUBLIC KEY", Bytes: public.Marshal()})
    if err != nil{
        return nil, err
    }

    return certBytes.Bytes(), nil
}