Skip to content

Instantly share code, notes, and snippets.

@wongoo
Created August 1, 2019 03:19
Show Gist options
  • Save wongoo/2b974a9594627114bea3e53c794980cd to your computer and use it in GitHub Desktop.
Save wongoo/2b974a9594627114bea3e53c794980cd to your computer and use it in GitHub Desktop.
golang RSA utility, include encrypt/decrypt/signature
//author: http://github.com/wongoo
//date: 20190717
package rsautil
import (
"bytes"
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/base64"
"errors"
)
const (
rsaKeySize = 2048
)
func hash(data []byte) []byte {
s := sha1.Sum(data)
return s[:]
}
func GenerateKey() (*rsa.PrivateKey, *rsa.PublicKey, error) {
pri, err := rsa.GenerateKey(rand.Reader, rsaKeySize)
if err != nil {
return nil, nil, err
}
return pri, &pri.PublicKey, nil
}
func GenerateKeyBytes() (privateBytes, publicBytes []byte, err error) {
pri, pub, err := GenerateKey()
if err != nil {
return nil, nil, err
}
priBytes, err := x509.MarshalPKCS8PrivateKey(pri)
if err != nil {
return nil, nil, err
}
pubBytes := x509.MarshalPKCS1PublicKey(pub)
return priBytes, pubBytes, nil
}
func GenerateKey64() (pri64, pub64 string, err error) {
pri, pub, err := GenerateKeyBytes()
if err != nil {
return "", "", nil
}
return base64.StdEncoding.EncodeToString(pri),
base64.StdEncoding.EncodeToString(pub),
nil
}
func PublicKeyFrom(key []byte) (*rsa.PublicKey, error) {
pubInterface, err := x509.ParsePKIXPublicKey(key)
if err != nil {
return nil, err
}
pub, ok := pubInterface.(*rsa.PublicKey)
if !ok {
return nil, errors.New("invalid public key")
}
return pub, nil
}
func PublicKeyFrom64(key string) (*rsa.PublicKey, error) {
b, err := base64.StdEncoding.DecodeString(key)
if err != nil {
return nil, err
}
return PublicKeyFrom(b)
}
func PrivateKeyFrom(key []byte) (*rsa.PrivateKey, error) {
pri, err := x509.ParsePKCS8PrivateKey(key)
if err != nil {
return nil, err
}
p, ok := pri.(*rsa.PrivateKey)
if !ok {
return nil, errors.New("invalid private key")
}
return p, nil
}
func PrivateKeyFrom64(key string) (*rsa.PrivateKey, error) {
b, err := base64.StdEncoding.DecodeString(key)
if err != nil {
return nil, err
}
return PrivateKeyFrom(b)
}
func PublicEncrypt(key *rsa.PublicKey, data []byte) ([]byte, error) {
return rsa.EncryptPKCS1v15(rand.Reader, key, data)
}
func PublicSign(key *rsa.PublicKey, data []byte) ([]byte, error) {
return PublicEncrypt(key, hash(data))
}
func PublicVerify(key *rsa.PublicKey, sign, data []byte) error {
return rsa.VerifyPKCS1v15(key, crypto.SHA1, hash(data), sign)
}
func PrivateDecrypt(key *rsa.PrivateKey, data []byte) ([]byte, error) {
return rsa.DecryptPKCS1v15(rand.Reader, key, data)
}
func PrivateSign(key *rsa.PrivateKey, data []byte) ([]byte, error) {
return rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA1, hash(data))
}
func PrivateVerify(key *rsa.PrivateKey, sign, data []byte) error {
h, err := PrivateDecrypt(key, sign)
if err != nil {
return err
}
if !bytes.Equal(h, hash(data)) {
return rsa.ErrVerification
}
return nil
}
@nexus166
Copy link

SHA1? Are you in some parallel dimension two decades behind?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment