Save and load crypto/rsa PrivateKey to and from the disk

前端 未结 4 1190
萌比男神i
萌比男神i 2021-01-30 10:13

I\'m using crypto/rsa, and trying to find a way to properly save and load a key. Is there a correct way to create a []byte from an rsa.P

4条回答
  •  天命终不由人
    2021-01-30 11:00

    Here's code snippet that shows the import and export of both public and private keys. It's based on the other answers which were super helpful, as well as copy-pasta from the official docs.

    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")
        }
    }
    

提交回复
热议问题