mirror of
https://gogs.blitter.com/RLabs/xs
synced 2024-08-14 10:26:42 +00:00
87 lines
2 KiB
Go
87 lines
2 KiB
Go
|
package sm4
|
||
|
|
||
|
import (
|
||
|
"crypto/rand"
|
||
|
"crypto/x509"
|
||
|
"encoding/pem"
|
||
|
"errors"
|
||
|
"io/ioutil"
|
||
|
)
|
||
|
|
||
|
// ReadKeyFromPem will return SM4Key from PEM format data.
|
||
|
func ReadKeyFromPem(data []byte, pwd []byte) (SM4Key, error) {
|
||
|
block, _ := pem.Decode(data)
|
||
|
if block == nil {
|
||
|
return nil, errors.New("SM4: pem decode failed")
|
||
|
}
|
||
|
if x509.IsEncryptedPEMBlock(block) {
|
||
|
if block.Type != "SM4 ENCRYPTED KEY" {
|
||
|
return nil, errors.New("SM4: unknown type")
|
||
|
}
|
||
|
if pwd == nil {
|
||
|
return nil, errors.New("SM4: need passwd")
|
||
|
}
|
||
|
data, err := x509.DecryptPEMBlock(block, pwd)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return data, nil
|
||
|
}
|
||
|
if block.Type != "SM4 KEY" {
|
||
|
return nil, errors.New("SM4: unknown type")
|
||
|
}
|
||
|
return block.Bytes, nil
|
||
|
}
|
||
|
|
||
|
// ReadKeyFromPemFile will return SM4Key from filename that saved PEM format data.
|
||
|
func ReadKeyFromPemFile(FileName string, pwd []byte) (SM4Key, error) {
|
||
|
data, err := ioutil.ReadFile(FileName)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return ReadKeyFromPem(data, pwd)
|
||
|
}
|
||
|
|
||
|
// WriteKeyToPem will convert SM4Key to PEM format data and return it.
|
||
|
func WriteKeyToPem(key SM4Key, pwd []byte) ([]byte, error) {
|
||
|
if pwd != nil {
|
||
|
block, err := x509.EncryptPEMBlock(rand.Reader,
|
||
|
"SM4 ENCRYPTED KEY", key, pwd, x509.PEMCipherAES256) //Use AES256 algorithms to encrypt SM4KEY
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return pem.EncodeToMemory(block), nil
|
||
|
} else {
|
||
|
block := &pem.Block{
|
||
|
Type: "SM4 KEY",
|
||
|
Bytes: key,
|
||
|
}
|
||
|
return pem.EncodeToMemory(block), nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// WriteKeyToPemFile will convert SM4Key to PEM format data, then write it
|
||
|
// into the input filename.
|
||
|
func WriteKeyToPemFile(FileName string, key SM4Key, pwd []byte) error {
|
||
|
var block *pem.Block
|
||
|
var err error
|
||
|
if pwd != nil {
|
||
|
block, err = x509.EncryptPEMBlock(rand.Reader,
|
||
|
"SM4 ENCRYPTED KEY", key, pwd, x509.PEMCipherAES256)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
} else {
|
||
|
block = &pem.Block{
|
||
|
Type: "SM4 KEY",
|
||
|
Bytes: key,
|
||
|
}
|
||
|
}
|
||
|
pemBytes := pem.EncodeToMemory(block)
|
||
|
err = ioutil.WriteFile(FileName, pemBytes, 0666)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|