2021-05-05 05:06:05 +07:00
|
|
|
package utils
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/rand"
|
|
|
|
"crypto/rsa"
|
|
|
|
"crypto/x509"
|
|
|
|
"encoding/pem"
|
|
|
|
"errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
// GenerateRsaKeyPair generate an RSA key pair.
|
|
|
|
// bits can be 2048 or 4096.
|
|
|
|
func GenerateRsaKeyPair(bits int) (*rsa.PrivateKey, *rsa.PublicKey) {
|
|
|
|
privkey, _ := rsa.GenerateKey(rand.Reader, bits)
|
|
|
|
return privkey, &privkey.PublicKey
|
|
|
|
}
|
|
|
|
|
|
|
|
// ExportRsaPrivateKeyAsPemStr marshal a rsa private key into PEM string.
|
|
|
|
func ExportRsaPrivateKeyAsPemStr(privkey *rsa.PrivateKey) string {
|
|
|
|
privkeyBytes := x509.MarshalPKCS1PrivateKey(privkey)
|
|
|
|
privkeyPem := pem.EncodeToMemory(
|
|
|
|
&pem.Block{
|
|
|
|
Type: "RSA PRIVATE KEY",
|
|
|
|
Bytes: privkeyBytes,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
return string(privkeyPem)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ParseRsaPrivateKeyFromPemStr parse a RSA private key from PEM string.
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
// ExportRsaPublicKeyAsPemStr marshal a RSA public into a PEM string.
|
|
|
|
func ExportRsaPublicKeyAsPemStr(pubkey *rsa.PublicKey) (string, error) {
|
|
|
|
pubkeyBytes, err := x509.MarshalPKIXPublicKey(pubkey)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
pubkeyPem := pem.EncodeToMemory(
|
|
|
|
&pem.Block{
|
|
|
|
Type: "RSA PUBLIC KEY",
|
|
|
|
Bytes: pubkeyBytes,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
return string(pubkeyPem), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ParseRsaPublicKeyFromPemStr parse RSA public key from a PEM string.
|
|
|
|
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:
|
2022-01-31 12:25:15 +07:00
|
|
|
break // fall through.
|
2021-05-05 05:06:05 +07:00
|
|
|
}
|
|
|
|
|
2021-07-04 05:08:24 +07:00
|
|
|
return nil, errors.New("key type is not RSA")
|
2021-05-05 05:06:05 +07:00
|
|
|
}
|