authorizer/server/crypto/rsa.go

142 lines
3.6 KiB
Go
Raw Permalink Normal View History

2022-02-26 04:14:55 +00:00
package crypto
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
2022-02-26 04:14:55 +00:00
"crypto/x509"
"encoding/base64"
2022-02-26 04:14:55 +00:00
"encoding/pem"
"errors"
)
// NewRSAKey to generate new RSA Key if env is not set
// returns key instance, private key string, public key string, jwk string, error
func NewRSAKey(algo, keyID string) (*rsa.PrivateKey, string, string, string, error) {
2022-02-26 04:14:55 +00:00
key, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, "", "", "", err
2022-02-26 04:14:55 +00:00
}
privateKey, publicKey, err := AsRSAStr(key, &key.PublicKey)
if err != nil {
return nil, "", "", "", err
2022-02-26 04:14:55 +00:00
}
jwkPublicKey, err := GetPubJWK(algo, keyID, &key.PublicKey)
if err != nil {
return nil, "", "", "", err
}
return key, privateKey, publicKey, string(jwkPublicKey), err
2022-02-26 04:14:55 +00:00
}
// IsRSA checks if given string is valid RSA algo
func IsRSA(algo string) bool {
switch algo {
case "RS256", "RS384", "RS512":
return true
default:
return false
}
}
// ExportRsaPrivateKeyAsPemStr to get RSA private key as 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)
}
// ExportRsaPublicKeyAsPemStr to get RSA public key as pem string
func ExportRsaPublicKeyAsPemStr(pubkey *rsa.PublicKey) string {
pubkeyBytes := x509.MarshalPKCS1PublicKey(pubkey)
2022-02-26 04:14:55 +00:00
pubkeyPem := pem.EncodeToMemory(
&pem.Block{
Type: "RSA PUBLIC KEY",
Bytes: pubkeyBytes,
},
)
return string(pubkeyPem)
2022-02-26 04:14:55 +00:00
}
// ParseRsaPrivateKeyFromPemStr to parse 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
}
// ParseRsaPublicKeyFromPemStr to parse RSA public key from 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.ParsePKCS1PublicKey(block.Bytes)
2022-02-26 04:14:55 +00:00
if err != nil {
return nil, err
}
return pub, nil
2022-02-26 04:14:55 +00:00
}
// AsRSAStr returns private, public key string or error
func AsRSAStr(privateKey *rsa.PrivateKey, publickKey *rsa.PublicKey) (string, string, error) {
// Export the keys to pem string
privPem := ExportRsaPrivateKeyAsPemStr(privateKey)
pubPem := ExportRsaPublicKeyAsPemStr(publickKey)
2022-02-26 04:14:55 +00:00
// Import the keys from pem string
privParsed, err := ParseRsaPrivateKeyFromPemStr(privPem)
if err != nil {
return "", "", err
}
pubParsed, err := ParseRsaPublicKeyFromPemStr(pubPem)
if err != nil {
return "", "", err
}
// Export the newly imported keys
privParsedPem := ExportRsaPrivateKeyAsPemStr(privParsed)
pubParsedPem := ExportRsaPublicKeyAsPemStr(pubParsed)
2022-02-26 04:14:55 +00:00
return privParsedPem, pubParsedPem, nil
}
func EncryptRSA(message string, key rsa.PublicKey) (string, error) {
label := []byte("OAEP Encrypted")
rng := rand.Reader
ciphertext, err := rsa.EncryptOAEP(sha256.New(), rng, &key, []byte(message), label)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(ciphertext), nil
}
func DecryptRSA(cipherText string, privateKey rsa.PrivateKey) (string, error) {
ct, _ := base64.StdEncoding.DecodeString(cipherText)
label := []byte("OAEP Encrypted")
rng := rand.Reader
plaintext, err := rsa.DecryptOAEP(sha256.New(), rng, &privateKey, ct, label)
if err != nil {
return "", err
}
return string(plaintext), nil
}