github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/cry/rsa.go (about)

     1  package cry
     2  
     3  import (
     4  	"crypto/rand"
     5  	"crypto/rsa"
     6  	"crypto/sha512"
     7  	"crypto/x509"
     8  	"encoding/pem"
     9  	"errors"
    10  )
    11  
    12  // from https://gist.github.com/miguelmota/3ea9286bd1d3c2a985b67cac4ba2130a
    13  // and https://gist.github.com/sohamkamani/08377222d5e3e6bc130827f83b0c073e
    14  // and https://asecuritysite.com/encryption/gorsa
    15  
    16  // GenerateKeyPair generates a new key pair.
    17  func GenerateKeyPair(bits int) (*rsa.PrivateKey, *rsa.PublicKey) {
    18  	key, _ := rsa.GenerateKey(rand.Reader, bits)
    19  	return key, &key.PublicKey
    20  }
    21  
    22  // ExportPrivateKey exports private key to bytes.
    23  func ExportPrivateKey(key *rsa.PrivateKey) []byte {
    24  	return pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})
    25  }
    26  
    27  // ParsePrivateKey parses private key bytes to *rsa.PrivateKey.
    28  func ParsePrivateKey(key []byte) (*rsa.PrivateKey, error) {
    29  	block, _ := pem.Decode(key)
    30  	if block == nil {
    31  		return nil, errors.New("failed to parse PEM block containing the key")
    32  	}
    33  
    34  	return x509.ParsePKCS1PrivateKey(block.Bytes)
    35  }
    36  
    37  // ExportPublicKey exports public key to bytes.
    38  func ExportPublicKey(pub *rsa.PublicKey) []byte {
    39  	pubBytes, _ := x509.MarshalPKIXPublicKey(pub)
    40  	return pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: pubBytes})
    41  }
    42  
    43  // ParsePublicKey parses public key bytes to *rsa.PublicKey.
    44  func ParsePublicKey(key []byte) (*rsa.PublicKey, error) {
    45  	block, _ := pem.Decode(key)
    46  	if block == nil {
    47  		return nil, errors.New("failed to parse PEM block containing the key")
    48  	}
    49  
    50  	pub, err := x509.ParsePKIXPublicKey(block.Bytes)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  
    55  	if p, ok := pub.(*rsa.PublicKey); ok {
    56  		return p, nil
    57  	}
    58  
    59  	return nil, errors.New("key type is not RSA")
    60  }
    61  
    62  // EncryptWithPublicKey encrypts data with public key.
    63  func EncryptWithPublicKey(msg []byte, pub *rsa.PublicKey) ([]byte, error) {
    64  	return rsa.EncryptOAEP(sha512.New(), rand.Reader, pub, msg, nil)
    65  }
    66  
    67  // DecryptWithPrivateKey decrypts data with private key.
    68  func DecryptWithPrivateKey(ciphertext []byte, priv *rsa.PrivateKey) ([]byte, error) {
    69  	return rsa.DecryptOAEP(sha512.New(), rand.Reader, priv, ciphertext, nil)
    70  }