package ciphers import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "errors" "hash" ) var ( ErrPubKeyNotCorrect = errors.New("rsa public key is not correct") ) // GenerateKeyPair generates a new key pair func GenerateKeyPair(bits int) (*rsa.PrivateKey, error) { privkey, err := rsa.GenerateKey(rand.Reader, bits) if err != nil { return nil, err } return privkey, 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.PrivateKey) ([]byte, error) { pubASN1, err := x509.MarshalPKIXPublicKey(&pub.PublicKey) if err != nil { return nil, err } pubBytes := pem.EncodeToMemory(&pem.Block{ Type: "PUBLIC KEY", Bytes: pubASN1, }) return pubBytes, nil } func BytesRsaKeyToGo(priv, pub []byte) (*rsa.PrivateKey, error) { key, err := BytesToPrivateKey(priv) if err != nil { return nil, err } pubKey, err := BytesToPublicKey(pub) if err != nil { return nil, err } key.PublicKey = rsa.PublicKey{ N: pubKey.N, E: pubKey.E, } return key, nil } // func BytesPublicKeyToGo(pub []byte) (*rsa.PublicKey, error) { pubKey, err := BytesToPublicKey(pub) if err != nil { return nil, err } return &rsa.PublicKey{ N: pubKey.N, E: pubKey.E, }, 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, ErrPubKeyNotCorrect } return key, nil } // EncryptWithPublicKey OAEP encrypts data with public key func EncryptWithPublicKeyOAEP(hash hash.Hash, msg []byte, pub *rsa.PublicKey) ([]byte, error) { //hash := sha512.New() //hash := sha1.New() ciphertext, err := rsa.EncryptOAEP(hash, rand.Reader, pub, msg, nil) if err != nil { return nil, err } return ciphertext, nil } // DecryptWithPrivateKey OAEP decrypts data with private key func DecryptWithPrivateKeyOAEP(hash hash.Hash, ciphertext []byte, priv *rsa.PrivateKey) ([]byte, error) { //hash := sha512.New() //hash := sha1.New() plaintext, err := rsa.DecryptOAEP(hash, rand.Reader, priv, ciphertext, nil) if err != nil { return nil, err } return plaintext, nil }