Documentation ¶
Overview ¶
Package pkcs8 implements functions to parse and convert private keys in PKCS#8 format with ShangMi(SM) support, as defined in RFC5208 and RFC5958.
Index ¶
- Variables
- func ConvertPrivateKeyToPKCS8(priv any, v ...[]byte) ([]byte, error)
- func MarshalPrivateKey(priv any, password []byte, encrypter pkcs.PBESEncrypter) ([]byte, error)
- func ParsePKCS8PrivateKey(der []byte, v ...[]byte) (any, error)
- func ParsePKCS8PrivateKeyECDSA(der []byte, v ...[]byte) (*ecdsa.PrivateKey, error)
- func ParsePKCS8PrivateKeyRSA(der []byte, v ...[]byte) (*rsa.PrivateKey, error)
- func ParsePKCS8PrivateKeySM2(der []byte, v ...[]byte) (*sm2.PrivateKey, error)
- func ParsePrivateKey(der []byte, password []byte) (any, pkcs.KDFParameters, error)
- func ParseSM9EncryptMasterPrivateKey(der []byte, v ...[]byte) (*sm9.EncryptMasterPrivateKey, error)
- func ParseSM9EncryptPrivateKey(der []byte, v ...[]byte) (*sm9.EncryptPrivateKey, error)
- func ParseSM9SignMasterPrivateKey(der []byte, v ...[]byte) (*sm9.SignMasterPrivateKey, error)
- func ParseSM9SignPrivateKey(der []byte, v ...[]byte) (*sm9.SignPrivateKey, error)
- type Opts
- type PBKDF2Opts
- type ScryptOpts
Examples ¶
- MarshalPrivateKey
- MarshalPrivateKey (WithoutPassword)
- MarshalPrivateKey (WithoutPasswordSM9MasterSignKey)
- ParsePKCS8PrivateKey
- ParsePKCS8PrivateKey (WithoutPassword)
- ParsePKCS8PrivateKeySM2
- ParsePKCS8PrivateKeySM2 (RemovePassword)
- ParsePKCS8PrivateKeySM2 (WithoutPassword)
- ParsePrivateKey
- ParsePrivateKey (WithoutPassword)
- ParseSM9SignMasterPrivateKey (WithoutPassword)
Constants ¶
This section is empty.
Variables ¶
var ( ErrUnsupportedPBES = errors.New("pkcs8: only part of PBES1/PBES2 supported") ErrUnexpectedKeyType = errors.New("pkcs8: unexpected key type") )
var DefaultOpts = pkcs.DefaultOpts
var SHA1 = pkcs.SHA1
var SHA224 = pkcs.SHA224
var SHA256 = pkcs.SHA256
var SHA384 = pkcs.SHA384
var SHA512 = pkcs.SHA512
var SHA512_224 = pkcs.SHA512_224
var SHA512_256 = pkcs.SHA512_256
var SM3 = pkcs.SM3
Functions ¶
func ConvertPrivateKeyToPKCS8 ¶
ConvertPrivateKeyToPKCS8 converts the private key into PKCS#8 format. To encrypt the private key, the password of []byte type should be provided as the second parameter.
func MarshalPrivateKey ¶
MarshalPrivateKey encodes a private key into DER-encoded PKCS#8 with the given options. Password can be nil.
Example ¶
package main import ( "encoding/hex" "encoding/pem" "fmt" "math/big" "os" "github.com/emmansun/gmsm/pkcs" "github.com/emmansun/gmsm/pkcs8" "github.com/emmansun/gmsm/sm2" ) func main() { // real private key should be from secret storage, or generate directly privKey, _ := hex.DecodeString("6c5a0a0b2eed3cbec3e4f1252bfe0e28c504a1c6bf1999eebb0af9ef0f8e6c85") d := new(big.Int).SetBytes(privKey) testkey := new(sm2.PrivateKey) testkey.Curve = sm2.P256() testkey.D = d testkey.PublicKey.X, testkey.PublicKey.Y = testkey.ScalarBaseMult(testkey.D.Bytes()) password := []byte("Password1") opts := &pkcs8.Opts{ Cipher: pkcs.SM4CBC, KDFOpts: pkcs8.PBKDF2Opts{ SaltSize: 16, IterationCount: 16, HMACHash: pkcs8.SM3, }, } // generate der bytes der, err := pkcs8.MarshalPrivateKey(testkey, password, opts) if err != nil { fmt.Fprintf(os.Stderr, "Error from MarshalPrivateKey: %s\n", err) return } // encode der bytes to pem block := &pem.Block{Bytes: der, Type: "ENCRYPTED PRIVATE KEY"} pemContent := string(pem.EncodeToMemory(block)) fmt.Printf("%v\n", pemContent) }
Output:
Example (WithoutPassword) ¶
package main import ( "encoding/hex" "encoding/pem" "fmt" "math/big" "os" "github.com/emmansun/gmsm/pkcs8" "github.com/emmansun/gmsm/sm2" ) func main() { // real private key should be from secret storage, or generate directly privKey, _ := hex.DecodeString("6c5a0a0b2eed3cbec3e4f1252bfe0e28c504a1c6bf1999eebb0af9ef0f8e6c85") d := new(big.Int).SetBytes(privKey) testkey := new(sm2.PrivateKey) testkey.Curve = sm2.P256() testkey.D = d testkey.PublicKey.X, testkey.PublicKey.Y = testkey.ScalarBaseMult(testkey.D.Bytes()) // generate der bytes der, err := pkcs8.MarshalPrivateKey(testkey, nil, nil) if err != nil { fmt.Fprintf(os.Stderr, "Error from MarshalPrivateKey: %s\n", err) return } // encode der bytes to pem block := &pem.Block{Bytes: der, Type: "PRIVATE KEY"} pemContent := string(pem.EncodeToMemory(block)) fmt.Printf("%v\n", pemContent) }
Output:
Example (WithoutPasswordSM9MasterSignKey) ¶
package main import ( "encoding/hex" "encoding/pem" "fmt" "math/big" "os" "github.com/emmansun/gmsm/pkcs8" "github.com/emmansun/gmsm/sm9" "golang.org/x/crypto/cryptobyte" ) func main() { // real private key should be from secret storage, or generate directly kb, _ := hex.DecodeString("0130E78459D78545CB54C587E02CF480CE0B66340F319F348A1D5B1F2DC5F4") var b cryptobyte.Builder b.AddASN1BigInt(new(big.Int).SetBytes(kb)) kb, _ = b.Bytes() testkey := new(sm9.SignMasterPrivateKey) err := testkey.UnmarshalASN1(kb) if err != nil { panic(err) } // generate der bytes der, err := pkcs8.MarshalPrivateKey(testkey, nil, nil) if err != nil { fmt.Fprintf(os.Stderr, "Error from MarshalPrivateKey: %s\n", err) return } // encode der bytes to pem block := &pem.Block{Bytes: der, Type: "SM9 SIGN PRIVATE KEY"} pemContent := string(pem.EncodeToMemory(block)) fmt.Printf("%v\n", pemContent) }
Output:
func ParsePKCS8PrivateKey ¶
ParsePKCS8PrivateKey parses encrypted/unencrypted private keys in PKCS#8 format. To parse encrypted private keys, a password of []byte type should be provided to the function as the second parameter.
Example ¶
package main import ( "encoding/pem" "fmt" "os" "github.com/emmansun/gmsm/pkcs8" ) func main() { const privateKeyPem = ` -----BEGIN ENCRYPTED PRIVATE KEY----- MIH2MGEGCSqGSIb3DQEFDTBUMDQGCSqGSIb3DQEFDDAnBBDa6ckWJNP3QBD7MIF8 4nVqAgEQAgEQMA0GCSqBHM9VAYMRAgUAMBwGCCqBHM9VAWgCBBDMUgr+5Y/XN2g9 mPGiISzGBIGQytwK98/ET4WrS0H7AsUri6FTqztrzAvgzFl3+s9AsaYtUlzE3EzE x6RWxo8kpKO2yj0a/Jh9WZCD4XAcoZ9aMopiWlOdpXJr/iQlMGdirCYIoF37lHMc jZHNffmk4ii7NxCfjrzpiFq4clYsNMXeSEnq1tuOEur4kYcjHYSIFc9bPG656a60 +SIJsJuPFi0f -----END ENCRYPTED PRIVATE KEY-----` password := []byte("Password1") block, _ := pem.Decode([]byte(privateKeyPem)) if block == nil { fmt.Fprintf(os.Stderr, "Failed to parse PEM block\n") return } pk, err := pkcs8.ParsePKCS8PrivateKey(block.Bytes, password) if err != nil { fmt.Fprintf(os.Stderr, "Error from ParsePKCS8PrivateKey: %s\n", err) return } if pk != nil { fmt.Println("ok") } else { fmt.Println("fail") } }
Output: ok
Example (WithoutPassword) ¶
package main import ( "encoding/pem" "fmt" "os" "github.com/emmansun/gmsm/pkcs8" ) func main() { const privateKeyPem = ` -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgbFoKCy7tPL7D5PEl K/4OKMUEoca/GZnuuwr57w+ObIWhRANCAASDVuZCpA69GNKbo1MvvZ87vujwJ8P2 85pbovhwNp+ZiJgfXv5V0cXN9sDvKwcIR6FPf99CcqjfCcRC8wWK+Uuh -----END PRIVATE KEY-----` block, _ := pem.Decode([]byte(privateKeyPem)) if block == nil { fmt.Fprintf(os.Stderr, "Failed to parse PEM block\n") return } pk, err := pkcs8.ParsePKCS8PrivateKey(block.Bytes) if err != nil { fmt.Fprintf(os.Stderr, "Error from ParsePKCS8PrivateKey: %s\n", err) return } if pk != nil { fmt.Println("ok") } else { fmt.Println("fail") } }
Output: ok
func ParsePKCS8PrivateKeyECDSA ¶
func ParsePKCS8PrivateKeyECDSA(der []byte, v ...[]byte) (*ecdsa.PrivateKey, error)
ParsePKCS8PrivateKeyECDSA parses encrypted/unencrypted private keys in PKCS#8 format. To parse encrypted private keys, a password of []byte type should be provided to the function as the second parameter.
func ParsePKCS8PrivateKeyRSA ¶
func ParsePKCS8PrivateKeyRSA(der []byte, v ...[]byte) (*rsa.PrivateKey, error)
ParsePKCS8PrivateKeyRSA parses encrypted/unencrypted private keys in PKCS#8 format. To parse encrypted private keys, a password of []byte type should be provided to the function as the second parameter.
func ParsePKCS8PrivateKeySM2 ¶
func ParsePKCS8PrivateKeySM2(der []byte, v ...[]byte) (*sm2.PrivateKey, error)
ParsePKCS8PrivateKeySM2 parses encrypted/unencrypted SM2 private key in PKCS#8 format. To parse encrypted private keys, a password of []byte type should be provided to the function as the second parameter.
Example ¶
package main import ( "encoding/pem" "fmt" "os" "github.com/emmansun/gmsm/pkcs8" ) func main() { const privateKeyPem = ` -----BEGIN ENCRYPTED PRIVATE KEY----- MIH2MGEGCSqGSIb3DQEFDTBUMDQGCSqGSIb3DQEFDDAnBBDa6ckWJNP3QBD7MIF8 4nVqAgEQAgEQMA0GCSqBHM9VAYMRAgUAMBwGCCqBHM9VAWgCBBDMUgr+5Y/XN2g9 mPGiISzGBIGQytwK98/ET4WrS0H7AsUri6FTqztrzAvgzFl3+s9AsaYtUlzE3EzE x6RWxo8kpKO2yj0a/Jh9WZCD4XAcoZ9aMopiWlOdpXJr/iQlMGdirCYIoF37lHMc jZHNffmk4ii7NxCfjrzpiFq4clYsNMXeSEnq1tuOEur4kYcjHYSIFc9bPG656a60 +SIJsJuPFi0f -----END ENCRYPTED PRIVATE KEY-----` password := []byte("Password1") block, _ := pem.Decode([]byte(privateKeyPem)) if block == nil { fmt.Fprintf(os.Stderr, "Failed to parse PEM block\n") return } pk, err := pkcs8.ParsePKCS8PrivateKeySM2(block.Bytes, password) if err != nil { fmt.Fprintf(os.Stderr, "Error from ParsePKCS8PrivateKeySM2: %s\n", err) return } if pk != nil { fmt.Println("ok") } else { fmt.Println("fail") } }
Output: ok
Example (RemovePassword) ¶
package main import ( "encoding/pem" "fmt" "os" "github.com/emmansun/gmsm/pkcs8" "github.com/emmansun/gmsm/smx509" ) func main() { const privateKeyPem = ` -----BEGIN ENCRYPTED PRIVATE KEY----- MIH2MGEGCSqGSIb3DQEFDTBUMDQGCSqGSIb3DQEFDDAnBBDa6ckWJNP3QBD7MIF8 4nVqAgEQAgEQMA0GCSqBHM9VAYMRAgUAMBwGCCqBHM9VAWgCBBDMUgr+5Y/XN2g9 mPGiISzGBIGQytwK98/ET4WrS0H7AsUri6FTqztrzAvgzFl3+s9AsaYtUlzE3EzE x6RWxo8kpKO2yj0a/Jh9WZCD4XAcoZ9aMopiWlOdpXJr/iQlMGdirCYIoF37lHMc jZHNffmk4ii7NxCfjrzpiFq4clYsNMXeSEnq1tuOEur4kYcjHYSIFc9bPG656a60 +SIJsJuPFi0f -----END ENCRYPTED PRIVATE KEY-----` password := []byte("Password1") block, _ := pem.Decode([]byte(privateKeyPem)) if block == nil { fmt.Fprintf(os.Stderr, "Failed to parse PEM block\n") return } pk, err := pkcs8.ParsePKCS8PrivateKeySM2(block.Bytes, password) if err != nil { fmt.Fprintf(os.Stderr, "Error from ParsePKCS8PrivateKeySM2: %s\n", err) return } der, err := smx509.MarshalPKCS8PrivateKey(pk) if err != nil { fmt.Fprintf(os.Stderr, "Error from MarshalPKCS8PrivateKey: %s\n", err) return } block = &pem.Block{Bytes: der, Type: "PRIVATE KEY"} pemContent := string(pem.EncodeToMemory(block)) fmt.Printf("%v\n", pemContent) }
Output: -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgbFoKCy7tPL7D5PEl K/4OKMUEoca/GZnuuwr57w+ObIWhRANCAASDVuZCpA69GNKbo1MvvZ87vujwJ8P2 85pbovhwNp+ZiJgfXv5V0cXN9sDvKwcIR6FPf99CcqjfCcRC8wWK+Uuh -----END PRIVATE KEY-----
Example (WithoutPassword) ¶
package main import ( "encoding/pem" "fmt" "os" "github.com/emmansun/gmsm/pkcs8" ) func main() { const privateKeyPem = ` -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgbFoKCy7tPL7D5PEl K/4OKMUEoca/GZnuuwr57w+ObIWhRANCAASDVuZCpA69GNKbo1MvvZ87vujwJ8P2 85pbovhwNp+ZiJgfXv5V0cXN9sDvKwcIR6FPf99CcqjfCcRC8wWK+Uuh -----END PRIVATE KEY-----` block, _ := pem.Decode([]byte(privateKeyPem)) if block == nil { fmt.Fprintf(os.Stderr, "Failed to parse PEM block\n") return } pk, err := pkcs8.ParsePKCS8PrivateKeySM2(block.Bytes) if err != nil { fmt.Fprintf(os.Stderr, "Error from ParsePKCS8PrivateKeySM2: %s\n", err) return } if pk != nil { fmt.Println("ok") } else { fmt.Println("fail") } }
Output: ok
func ParsePrivateKey ¶
ParsePrivateKey parses a DER-encoded PKCS#8 private key. Password can be nil. This is equivalent to ParsePKCS8PrivateKey.
Example ¶
package main import ( "encoding/pem" "fmt" "os" "github.com/emmansun/gmsm/pkcs8" ) func main() { const privateKeyPem = ` -----BEGIN ENCRYPTED PRIVATE KEY----- MIH2MGEGCSqGSIb3DQEFDTBUMDQGCSqGSIb3DQEFDDAnBBDa6ckWJNP3QBD7MIF8 4nVqAgEQAgEQMA0GCSqBHM9VAYMRAgUAMBwGCCqBHM9VAWgCBBDMUgr+5Y/XN2g9 mPGiISzGBIGQytwK98/ET4WrS0H7AsUri6FTqztrzAvgzFl3+s9AsaYtUlzE3EzE x6RWxo8kpKO2yj0a/Jh9WZCD4XAcoZ9aMopiWlOdpXJr/iQlMGdirCYIoF37lHMc jZHNffmk4ii7NxCfjrzpiFq4clYsNMXeSEnq1tuOEur4kYcjHYSIFc9bPG656a60 +SIJsJuPFi0f -----END ENCRYPTED PRIVATE KEY-----` password := []byte("Password1") block, _ := pem.Decode([]byte(privateKeyPem)) if block == nil { fmt.Fprintf(os.Stderr, "Failed to parse PEM block\n") return } pk, params, err := pkcs8.ParsePrivateKey(block.Bytes, password) if err != nil { fmt.Fprintf(os.Stderr, "Error from ParsePrivateKey: %s\n", err) return } if params != nil && pk != nil { fmt.Println("ok") } else { fmt.Println("fail") } }
Output: ok
Example (WithoutPassword) ¶
package main import ( "encoding/pem" "fmt" "os" "github.com/emmansun/gmsm/pkcs8" ) func main() { const privateKeyPem = ` -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgbFoKCy7tPL7D5PEl K/4OKMUEoca/GZnuuwr57w+ObIWhRANCAASDVuZCpA69GNKbo1MvvZ87vujwJ8P2 85pbovhwNp+ZiJgfXv5V0cXN9sDvKwcIR6FPf99CcqjfCcRC8wWK+Uuh -----END PRIVATE KEY-----` block, _ := pem.Decode([]byte(privateKeyPem)) if block == nil { fmt.Fprintf(os.Stderr, "Failed to parse PEM block\n") return } pk, params, err := pkcs8.ParsePrivateKey(block.Bytes, nil) if err != nil { fmt.Fprintf(os.Stderr, "Error from ParsePrivateKey: %s\n", err) return } if params == nil && pk != nil { fmt.Println("ok") } else { fmt.Println("fail") } }
Output: ok
func ParseSM9EncryptMasterPrivateKey ¶ added in v0.15.0
func ParseSM9EncryptMasterPrivateKey(der []byte, v ...[]byte) (*sm9.EncryptMasterPrivateKey, error)
ParseSM9EncryptMasterPrivateKey parses encrypted/unencrypted SM9 encrypt master private key in PKCS#8 format. To parse encrypted private keys, a password of []byte type should be provided to the function as the second parameter.
func ParseSM9EncryptPrivateKey ¶ added in v0.15.0
func ParseSM9EncryptPrivateKey(der []byte, v ...[]byte) (*sm9.EncryptPrivateKey, error)
ParseSM9EncryptPrivateKey parses encrypted/unencrypted SM9 encrypt private key in PKCS#8 format. To parse encrypted private keys, a password of []byte type should be provided to the function as the second parameter.
func ParseSM9SignMasterPrivateKey ¶ added in v0.15.0
func ParseSM9SignMasterPrivateKey(der []byte, v ...[]byte) (*sm9.SignMasterPrivateKey, error)
ParseSM9SignMasterPrivateKey parses encrypted/unencrypted SM9 sign master private key in PKCS#8 format. To parse encrypted private keys, a password of []byte type should be provided to the function as the second parameter.
Example (WithoutPassword) ¶
package main import ( "encoding/pem" "fmt" "os" "github.com/emmansun/gmsm/pkcs8" ) func main() { const privateKeyPem = ` -----BEGIN SM9 SIGN PRIVATE KEY----- MIHGAgEAMBUGCCqBHM9VAYIuBgkqgRzPVQGCLgEEgakwgaYCHwEw54RZ14VFy1TF h+As9IDOC2Y0DzGfNIodWx8txfQDgYIABJ9kCAswhPcz5Ir/S0G1ZQEc4HEcXjks +wqxtnkblMQIKduhFhUtH3hs6EPtJKO1c0FNIXc4apLdjxTWVpbqXjJphQk4q+oB ErVzKfRH46DLrT4v2xp38zXonhQI0O8cJUHgClPdpTLaGnzgJ7ekb3QQBuhfXN/w cw51wF+04yFt -----END SM9 SIGN PRIVATE KEY-----` block, _ := pem.Decode([]byte(privateKeyPem)) if block == nil { fmt.Fprintf(os.Stderr, "Failed to parse PEM block\n") return } pk, err := pkcs8.ParseSM9SignMasterPrivateKey(block.Bytes) if err != nil { fmt.Fprintf(os.Stderr, "Error from ParseSM9SignMasterPrivateKey: %s\n", err) return } if pk != nil { fmt.Println("ok") } else { fmt.Println("fail") } }
Output: ok
func ParseSM9SignPrivateKey ¶ added in v0.15.0
func ParseSM9SignPrivateKey(der []byte, v ...[]byte) (*sm9.SignPrivateKey, error)
ParseSM9SignPrivateKey parses encrypted/unencrypted SM9 sign private key in PKCS#8 format. To parse encrypted private keys, a password of []byte type should be provided to the function as the second parameter.
Types ¶
type PBKDF2Opts ¶
type PBKDF2Opts = pkcs.PBKDF2Opts
type ScryptOpts ¶
type ScryptOpts = pkcs.ScryptOpts