123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- package encrypter
- import (
- "crypto/rand"
- "crypto/rsa"
- "crypto/sha256"
- "crypto/x509"
- "encoding/base64"
- "fmt"
- "reflect"
- "strings"
- msgpack "gopkg.in/vmihailenco/msgpack.v2"
- )
- // PrivateKey type
- type PrivateKey rsa.PrivateKey
- // PublicKey type
- type PublicKey rsa.PublicKey
- const (
- keySize = 2048
- decryptBlockSize = 256
- encryptBlockSize = 190
- )
- // NewPrivateKey func
- func NewPrivateKey() *PrivateKey {
- pk, err := rsa.GenerateKey(rand.Reader, keySize)
- if err != nil {
- panic(fmt.Errorf("Error create rsa.PrivateKey %v", err))
- }
- return (*PrivateKey)(pk)
- }
- // ParsePrivateKey func
- func ParsePrivateKey(raw []byte) *PrivateKey {
- k, err := x509.ParsePKCS1PrivateKey(raw)
- if err != nil {
- panic(fmt.Errorf("Error parse privateKey %v", err))
- }
- return (*PrivateKey)(k)
- }
- // ParsePrivateKeyString func
- func ParsePrivateKeyString(str string) (*PrivateKey, error) {
- raw, err := base64.RawURLEncoding.DecodeString(str)
- if err != nil {
- slog.Debugf("Error key decode %v", err)
- return nil, err
- }
- k, err := x509.ParsePKCS1PrivateKey(raw)
- if err != nil {
- slog.Debugf("Error parse key %v", err)
- return nil, err
- }
- return (*PrivateKey)(k), nil
- }
- // ParsePublicKey func
- func ParsePublicKey(raw []byte) *PublicKey {
- k, err := x509.ParsePKIXPublicKey(raw)
- if err != nil {
- panic(fmt.Errorf("Error parse privateKey %v", err))
- }
- if p, ok := k.(*rsa.PublicKey); ok {
- return (*PublicKey)(p)
- }
- panic(fmt.Errorf("Invalid type %s", reflect.TypeOf(k).String()))
- }
- // ParsePublicKeyString func
- func ParsePublicKeyString(str string) (*PublicKey, error) {
- raw, err := base64.RawURLEncoding.DecodeString(str)
- if err != nil {
- slog.Debugf("Error key decode %v", err)
- return nil, err
- }
- k, err := x509.ParsePKIXPublicKey(raw)
- if err != nil {
- slog.Debugf("Error parse key %v", err)
- return nil, err
- }
- if p, ok := k.(*rsa.PublicKey); ok {
- return (*PublicKey)(p), nil
- }
- err = fmt.Errorf("Invalid type %s", reflect.TypeOf(k).String())
- slog.Debugf("Error %v", err)
- return nil, err
- }
- var _ msgpack.CustomEncoder = (*PrivateKey)(nil)
- var _ msgpack.CustomDecoder = (*PrivateKey)(nil)
- // EncodeMsgpack func
- func (s *PrivateKey) EncodeMsgpack(enc *msgpack.Encoder) error {
- return enc.Encode(s.Raw())
- }
- // DecodeMsgpack func
- func (s *PrivateKey) DecodeMsgpack(dec *msgpack.Decoder) error {
- var raw []byte
- err := dec.Decode(&raw)
- if err != nil {
- slog.Warnf("PrivateKey.DecodeMsgpack decode str %v", err)
- return err
- }
- sk, err := x509.ParsePKCS1PrivateKey(raw)
- if err != nil {
- slog.Warnf("PrivateKey.DecodeMsgpack parse pkcs key %v", err)
- return err
- }
- s.PublicKey = sk.PublicKey
- s.D = sk.D
- s.Primes = sk.Primes
- s.Precomputed = sk.Precomputed
- return nil
- }
- // Decrypt func
- func (s *PrivateKey) Decrypt(crypt []byte) (plain []byte, err error) {
- for {
- if len(crypt) <= decryptBlockSize {
- bb, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, (*rsa.PrivateKey)(s), crypt, nil)
- if err != nil {
- return nil, err
- }
- return append(plain, bb...), err
- }
- bb, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, (*rsa.PrivateKey)(s), crypt[:decryptBlockSize], nil)
- if err != nil {
- return nil, err
- }
- plain = append(plain, bb...)
- crypt = crypt[decryptBlockSize:]
- }
- }
- // MarshalJSON func
- func (s *PrivateKey) MarshalJSON() ([]byte, error) {
- return []byte("\"" + base64.RawURLEncoding.EncodeToString(s.Raw()) + "\""), nil
- }
- // UnmarshalJSON func
- func (s *PrivateKey) UnmarshalJSON(b []byte) error {
- if b[0] != '"' && b[len(b)-1] != '"' {
- return fmt.Errorf("Invalid key")
- }
- skey := strings.Replace(string(b[1:len(b)-1]), "\\n", "", -1)
- bb, err := base64.RawURLEncoding.DecodeString(skey)
- if err != nil {
- return fmt.Errorf("Error parse privateKey %v [%s]", err, skey)
- }
- k, err := x509.ParsePKCS1PrivateKey(bb)
- if err != nil {
- return fmt.Errorf("Error parse privateKey %v [%s]", err, string(bb))
- }
- s.D = k.D
- s.E = k.E
- s.N = k.N
- s.Primes = k.Primes
- return ((*rsa.PrivateKey)(s)).Validate()
- }
- func (s *PrivateKey) String() string {
- bb := x509.MarshalPKCS1PrivateKey((*rsa.PrivateKey)(s))
- return base64.RawURLEncoding.EncodeToString(bb)
- }
- // Public func
- func (s *PrivateKey) Public() *PublicKey {
- rp := (*rsa.PrivateKey)(s).PublicKey
- return (*PublicKey)(&rp)
- }
- // EncryptKey func
- func (s *PrivateKey) EncryptKey(key *PublicKey) EncryptedPrivateKey {
- bb, err := key.Encrypt(s.Raw())
- if err != nil {
- panic(err)
- }
- return (EncryptedPrivateKey)(bb)
- }
- // Raw func
- func (s *PrivateKey) Raw() []byte {
- return x509.MarshalPKCS1PrivateKey((*rsa.PrivateKey)(s))
- }
- // Equal func
- func (s *PrivateKey) Equal(key *PrivateKey) bool {
- if key == nil {
- return s == nil
- }
- k1 := (*rsa.PrivateKey)(s)
- k2 := (*rsa.PrivateKey)(key)
- return k1.E == k2.E && k1.D.Cmp(k2.D) == 0 && k1.N.Cmp(k2.N) == 0
- }
- var _ msgpack.CustomEncoder = (*PublicKey)(nil)
- var _ msgpack.CustomDecoder = (*PublicKey)(nil)
- // EncodeMsgpack func
- func (s *PublicKey) EncodeMsgpack(enc *msgpack.Encoder) error {
- return enc.Encode(s.Raw())
- }
- // DecodeMsgpack func
- func (s *PublicKey) DecodeMsgpack(dec *msgpack.Decoder) error {
- var raw []byte
- err := dec.Decode(&raw)
- if err != nil {
- return err
- }
- sko, err := x509.ParsePKIXPublicKey(raw)
- if err != nil {
- return err
- }
- if sk, ok := sko.(*rsa.PublicKey); ok {
- s.N = sk.N
- s.E = sk.E
- return nil
- }
- return fmt.Errorf("Unkown type %s", reflect.TypeOf(sko))
- }
- // Encrypt func
- func (s *PublicKey) Encrypt(data []byte) (crypt []byte, err error) {
- for {
- if len(data) <= encryptBlockSize {
- bb, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, (*rsa.PublicKey)(s), data, nil)
- if err != nil {
- return nil, err
- }
- return append(crypt, bb...), err
- }
- bb, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, (*rsa.PublicKey)(s), data[:encryptBlockSize], nil)
- if err != nil {
- return nil, err
- }
- crypt = append(crypt, bb...)
- data = data[encryptBlockSize:]
- }
- }
- // MarshalJSON func
- func (s *PublicKey) MarshalJSON() ([]byte, error) {
- return []byte("\"" + base64.RawURLEncoding.EncodeToString(s.Raw()) + "\""), nil
- }
- // UnmarshalJSON func
- func (s *PublicKey) UnmarshalJSON(b []byte) error {
- if b[0] != '"' && b[len(b)-1] != '"' {
- return fmt.Errorf("Invalid key")
- }
- skey := strings.Replace(string(b[1:len(b)-1]), "\\n", "", -1)
- bb, err := base64.RawURLEncoding.DecodeString(skey)
- if err != nil {
- return fmt.Errorf("Error parse privateKey %v [%s]", err, skey)
- }
- k, err := x509.ParsePKIXPublicKey(bb)
- if err != nil {
- return fmt.Errorf("Error parse privateKey %v [%s]", err, string(bb))
- }
- if pk, ok := k.(*rsa.PublicKey); ok {
- s.E = pk.E
- s.N = pk.N
- return nil
- }
- return fmt.Errorf("Invalid type %s", reflect.TypeOf(k))
- }
- func (s *PublicKey) String() string {
- return base64.RawURLEncoding.EncodeToString(s.Raw())
- }
- // Raw func
- func (s *PublicKey) Raw() []byte {
- bb, err := x509.MarshalPKIXPublicKey((*rsa.PublicKey)(s))
- if err != nil {
- panic(err)
- }
- return bb
- }
- // Equal func
- func (s *PublicKey) Equal(key *PublicKey) bool {
- if key == nil {
- return s == nil
- }
- k1 := (*rsa.PublicKey)(s)
- k2 := (*rsa.PublicKey)(key)
- return k1.E == k2.E && k1.N.Cmp(k2.N) == 0
- }
|