|
@@ -0,0 +1,111 @@
|
|
|
+package expose
|
|
|
+
|
|
|
+import (
|
|
|
+ "crypto/rand"
|
|
|
+ "crypto/rsa"
|
|
|
+ "crypto/sha512"
|
|
|
+ "crypto/x509"
|
|
|
+ "encoding/pem"
|
|
|
+ "errors"
|
|
|
+ "log"
|
|
|
+)
|
|
|
+
|
|
|
+// GenerateKeyPair generates a new key pair
|
|
|
+func GenerateKeyPair(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error) {
|
|
|
+ privkey, err := rsa.GenerateKey(rand.Reader, bits)
|
|
|
+ if err != nil {
|
|
|
+ return nil, nil, err
|
|
|
+ }
|
|
|
+ return privkey, &privkey.PublicKey, nil
|
|
|
+}
|
|
|
+
|
|
|
+// PrivateKeyToBytes private key to bytes
|
|
|
+func PrivateKeyToBytes(priv *rsa.PrivateKey) []byte {
|
|
|
+ privBytes := pem.EncodeToMemory(
|
|
|
+ &pem.Block{
|
|
|
+ Type: "RSA PRIVATE KEY",
|
|
|
+ Bytes: x509.MarshalPKCS1PrivateKey(priv),
|
|
|
+ },
|
|
|
+ )
|
|
|
+
|
|
|
+ return privBytes
|
|
|
+}
|
|
|
+
|
|
|
+// PublicKeyToBytes public key to bytes
|
|
|
+func PublicKeyToBytes(pub *rsa.PublicKey) ([]byte, error) {
|
|
|
+ pubASN1, err := x509.MarshalPKIXPublicKey(pub)
|
|
|
+ if err != nil {
|
|
|
+ return []byte(""), err
|
|
|
+ }
|
|
|
+
|
|
|
+ pubBytes := pem.EncodeToMemory(&pem.Block{
|
|
|
+ Type: "RSA PUBLIC KEY",
|
|
|
+ Bytes: pubASN1,
|
|
|
+ })
|
|
|
+
|
|
|
+ return pubBytes, nil
|
|
|
+}
|
|
|
+
|
|
|
+// BytesToPrivateKey bytes to private key
|
|
|
+func BytesToPrivateKey(priv []byte) (*rsa.PrivateKey, error) {
|
|
|
+ block, _ := pem.Decode(priv)
|
|
|
+ enc := x509.IsEncryptedPEMBlock(block)
|
|
|
+ b := block.Bytes
|
|
|
+ var err error
|
|
|
+ if enc {
|
|
|
+ log.Println("is encrypted pem block")
|
|
|
+ b, err = x509.DecryptPEMBlock(block, nil)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ }
|
|
|
+ key, err := x509.ParsePKCS1PrivateKey(b)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return key, nil
|
|
|
+}
|
|
|
+
|
|
|
+// BytesToPublicKey bytes to public key
|
|
|
+func BytesToPublicKey(pub []byte) (*rsa.PublicKey, error) {
|
|
|
+ block, _ := pem.Decode(pub)
|
|
|
+ enc := x509.IsEncryptedPEMBlock(block)
|
|
|
+ b := block.Bytes
|
|
|
+ var err error
|
|
|
+ if enc {
|
|
|
+ log.Println("is encrypted pem block")
|
|
|
+ b, err = x509.DecryptPEMBlock(block, nil)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ifc, err := x509.ParsePKIXPublicKey(b)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ key, ok := ifc.(*rsa.PublicKey)
|
|
|
+ if !ok {
|
|
|
+ return nil, errors.New("key not valid")
|
|
|
+ }
|
|
|
+ return key, nil
|
|
|
+}
|
|
|
+
|
|
|
+// EncryptWithPublicKey encrypts data with public key
|
|
|
+func EncryptWithPublicKey(msg []byte, pub *rsa.PublicKey) ([]byte, error) {
|
|
|
+ hash := sha512.New()
|
|
|
+ ciphertext, err := rsa.EncryptOAEP(hash, rand.Reader, pub, msg, nil)
|
|
|
+ if err != nil {
|
|
|
+ return []byte(""), err
|
|
|
+ }
|
|
|
+ return ciphertext, nil
|
|
|
+}
|
|
|
+
|
|
|
+// DecryptWithPrivateKey decrypts data with private key
|
|
|
+func DecryptWithPrivateKey(ciphertext []byte, priv *rsa.PrivateKey) ([]byte, error) {
|
|
|
+ hash := sha512.New()
|
|
|
+ plaintext, err := rsa.DecryptOAEP(hash, rand.Reader, priv, ciphertext, nil)
|
|
|
+ if err != nil {
|
|
|
+ return []byte(""), err
|
|
|
+ }
|
|
|
+ return plaintext, nil
|
|
|
+}
|