github.com/godaddy-x/freego@v1.0.156/utils/crypto/gorsa.go (about)

     1  package crypto
     2  
     3  import (
     4  	"bytes"
     5  	"crypto"
     6  	"crypto/rand"
     7  	"crypto/rsa"
     8  	"crypto/sha256"
     9  	"crypto/x509"
    10  	"encoding/base64"
    11  	"encoding/pem"
    12  	"errors"
    13  	"os"
    14  )
    15  
    16  const bits = 2048
    17  
    18  type Cipher interface {
    19  	GetPrivateKey() (interface{}, string)
    20  	GetPublicKey() (interface{}, string)
    21  	Encrypt(msg []byte) (string, error)
    22  	Decrypt(msg string) (string, error)
    23  	Sign(msg []byte) ([]byte, error)
    24  	Verify(msg, sign []byte) error
    25  }
    26  
    27  type RsaObj struct {
    28  	privateKey       *rsa.PrivateKey
    29  	publicKey        *rsa.PublicKey
    30  	PrivateKeyBase64 string
    31  	PublicKeyBase64  string
    32  }
    33  
    34  func (self *RsaObj) CreateRsaFile(keyfile, pemfile string) error {
    35  	// 生成私钥文件
    36  	prikey, err := rsa.GenerateKey(rand.Reader, bits)
    37  	if err != nil {
    38  		return err
    39  	}
    40  	block := pem.Block{
    41  		Type:  "RSA PRIVATE KEY",
    42  		Bytes: x509.MarshalPKCS1PrivateKey(prikey),
    43  	}
    44  	file, err := os.Create(keyfile)
    45  	if err != nil {
    46  		return err
    47  	}
    48  	if err := pem.Encode(file, &block); err != nil {
    49  		return err
    50  	}
    51  	if err := file.Close(); err != nil {
    52  		return err
    53  	}
    54  	// 将publicKey转换为PKIX, ASN.1 DER格式
    55  	derPkix, err := x509.MarshalPKIXPublicKey(&prikey.PublicKey)
    56  	if err != nil {
    57  		return err
    58  	}
    59  	// 设置PEM编码结构
    60  	block1 := pem.Block{
    61  		Type:  "PUBLIC KEY",
    62  		Bytes: derPkix,
    63  	}
    64  	file, err = os.Create(pemfile)
    65  	if err != nil {
    66  		return err
    67  	}
    68  	if err := pem.Encode(file, &block1); err != nil {
    69  		return err
    70  	}
    71  	if err := file.Close(); err != nil {
    72  		return err
    73  	}
    74  	return nil
    75  }
    76  
    77  func (self *RsaObj) CreateRsaPemFile(pemfile string) error {
    78  	block1, _ := pem.Decode([]byte(self.PublicKeyBase64))
    79  	if block1 == nil {
    80  		return errors.New("RSA block invalid")
    81  	}
    82  	file, err := os.Create(pemfile)
    83  	if err != nil {
    84  		return err
    85  	}
    86  	if err := pem.Encode(file, block1); err != nil {
    87  		return err
    88  	}
    89  	if err := file.Close(); err != nil {
    90  		return err
    91  	}
    92  	return nil
    93  }
    94  
    95  func (self *RsaObj) CreateRsa2048() error {
    96  	return self.CreateRsaFileBase64()
    97  }
    98  
    99  func (self *RsaObj) CreateRsa1024() error {
   100  	return self.CreateRsaFileBase64(1024)
   101  }
   102  
   103  func (self *RsaObj) CreateRsaFileBase64(b ...int) error {
   104  	x := bits
   105  	if len(b) > 0 {
   106  		x = b[0]
   107  	}
   108  	// 生成私钥文件
   109  	prikey, err := rsa.GenerateKey(rand.Reader, x)
   110  	if err != nil {
   111  		return err
   112  	}
   113  	block := pem.Block{
   114  		Type:  "RSA PRIVATE KEY",
   115  		Bytes: x509.MarshalPKCS1PrivateKey(prikey),
   116  	}
   117  	privateKeyBase64 := base64.URLEncoding.EncodeToString(pem.EncodeToMemory(&block))
   118  	// 将publicKey转换为PKIX, ASN.1 DER格式
   119  	derPkix, err := x509.MarshalPKIXPublicKey(&prikey.PublicKey)
   120  	if err != nil {
   121  		return err
   122  	}
   123  	// 设置PEM编码结构
   124  	block1 := &pem.Block{
   125  		Type:  "PUBLIC KEY",
   126  		Bytes: derPkix,
   127  	}
   128  	self.privateKey = prikey
   129  	self.publicKey = &prikey.PublicKey
   130  	self.PublicKeyBase64 = string(pem.EncodeToMemory(block1))
   131  	self.PrivateKeyBase64 = privateKeyBase64
   132  	return nil
   133  }
   134  
   135  func (self *RsaObj) LoadRsaFile(filePath string) error {
   136  	file, err := os.Open(filePath)
   137  	if err != nil {
   138  		return err
   139  	}
   140  	stat, _ := file.Stat()
   141  	content := make([]byte, stat.Size())
   142  	if _, err := file.Read(content); err != nil {
   143  		return err
   144  	}
   145  	if err := file.Close(); err != nil {
   146  		return err
   147  	}
   148  	block, _ := pem.Decode(content)
   149  	if block == nil {
   150  		return errors.New("RSA block invalid")
   151  	}
   152  	prikey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
   153  	if err != nil {
   154  		return err
   155  	}
   156  	// 将publicKey转换为PKIX, ASN.1 DER格式
   157  	derPkix, err := x509.MarshalPKIXPublicKey(&prikey.PublicKey)
   158  	if err != nil {
   159  		return err
   160  	}
   161  	// 设置PEM编码结构
   162  	block1 := pem.Block{
   163  		Type:  "PUBLIC KEY",
   164  		Bytes: derPkix,
   165  	}
   166  	self.PublicKeyBase64 = string(pem.EncodeToMemory(&block1))
   167  	self.PrivateKeyBase64 = base64.URLEncoding.EncodeToString(pem.EncodeToMemory(block))
   168  	self.privateKey = prikey
   169  	self.publicKey = &prikey.PublicKey
   170  	return nil
   171  }
   172  
   173  func (self *RsaObj) LoadRsaKeyFileBase64(fileBase64 string) error {
   174  	dec, err := base64.URLEncoding.DecodeString(fileBase64)
   175  	if err != nil {
   176  		return err
   177  	}
   178  	block, _ := pem.Decode(dec)
   179  	if block == nil {
   180  		return errors.New("RSA block invalid")
   181  	}
   182  	prikey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
   183  	if err != nil {
   184  		return err
   185  	}
   186  	// 将publicKey转换为PKIX, ASN.1 DER格式
   187  	derPkix, err := x509.MarshalPKIXPublicKey(&prikey.PublicKey)
   188  	if err != nil {
   189  		return err
   190  	}
   191  	// 设置PEM编码结构
   192  	block1 := pem.Block{
   193  		Type:  "PUBLIC KEY",
   194  		Bytes: derPkix,
   195  	}
   196  	self.PublicKeyBase64 = string(pem.EncodeToMemory(&block1))
   197  	self.PrivateKeyBase64 = fileBase64
   198  	self.privateKey = prikey
   199  	self.publicKey = &prikey.PublicKey
   200  	return nil
   201  }
   202  
   203  func (self *RsaObj) LoadRsaPemFile(filePath string) error {
   204  	file, err := os.Open(filePath)
   205  	if err != nil {
   206  		return err
   207  	}
   208  	stat, _ := file.Stat()
   209  	content := make([]byte, stat.Size())
   210  	if _, err := file.Read(content); err != nil {
   211  		return err
   212  	}
   213  	if err := file.Close(); err != nil {
   214  		return err
   215  	}
   216  	block, _ := pem.Decode(content)
   217  	if block == nil {
   218  		return errors.New("RSA block invalid")
   219  	}
   220  	pki, err := x509.ParsePKIXPublicKey(block.Bytes)
   221  	if err != nil {
   222  		return err
   223  	}
   224  	pub, b := pki.(*rsa.PublicKey)
   225  	if !b {
   226  		return errors.New("RSA pub key invalid")
   227  	}
   228  	self.PublicKeyBase64 = string(pem.EncodeToMemory(block))
   229  	self.publicKey = pub
   230  	return nil
   231  }
   232  
   233  func (self *RsaObj) LoadRsaPemFileBase64(fileBase64 string) error {
   234  	block, _ := pem.Decode([]byte(fileBase64))
   235  	if block == nil {
   236  		return errors.New("RSA block invalid")
   237  	}
   238  	pki, err := x509.ParsePKIXPublicKey(block.Bytes)
   239  	if err != nil {
   240  		return err
   241  	}
   242  	pub, b := pki.(*rsa.PublicKey)
   243  	if !b {
   244  		return errors.New("RSA pub key invalid")
   245  	}
   246  	self.publicKey = pub
   247  	self.PublicKeyBase64 = fileBase64
   248  	return nil
   249  }
   250  
   251  func split(buf []byte, lim int) [][]byte {
   252  	var chunk []byte
   253  	chunks := make([][]byte, 0, len(buf)/lim+1)
   254  	for len(buf) >= lim {
   255  		chunk, buf = buf[:lim], buf[lim:]
   256  		chunks = append(chunks, chunk)
   257  	}
   258  	if len(buf) > 0 {
   259  		chunks = append(chunks, buf[:])
   260  	}
   261  	return chunks
   262  }
   263  
   264  // ******************************************************* RSA Implement *******************************************************
   265  
   266  func (self *RsaObj) GetPrivateKey() (interface{}, string) {
   267  	return self.privateKey, self.PrivateKeyBase64
   268  }
   269  
   270  func (self *RsaObj) GetPublicKey() (interface{}, string) {
   271  	return self.publicKey, self.PublicKeyBase64
   272  }
   273  
   274  func (self *RsaObj) Encrypt(msg []byte) (string, error) {
   275  	partLen := self.publicKey.N.BitLen()/8 - 11
   276  	chunks := split(msg, partLen)
   277  	buffer := bytes.NewBufferString("")
   278  	for _, chunk := range chunks {
   279  		bytes, err := rsa.EncryptPKCS1v15(rand.Reader, self.publicKey, chunk)
   280  		if err != nil {
   281  			return "", err
   282  		}
   283  		buffer.Write(bytes)
   284  	}
   285  	return base64.StdEncoding.EncodeToString(buffer.Bytes()), nil
   286  }
   287  
   288  func (self *RsaObj) Decrypt(msg string) (string, error) {
   289  	partLen := self.publicKey.N.BitLen() / 8
   290  	raw, err := base64.StdEncoding.DecodeString(msg)
   291  	if err != nil {
   292  		return "", errors.New("msg base64 decode failed")
   293  	}
   294  	chunks := split(raw, partLen)
   295  	buffer := bytes.NewBufferString("")
   296  	for _, chunk := range chunks {
   297  		decrypted, err := rsa.DecryptPKCS1v15(rand.Reader, self.privateKey, chunk)
   298  		if err != nil {
   299  			return "", err
   300  		}
   301  		buffer.Write(decrypted)
   302  	}
   303  	return buffer.String(), err
   304  }
   305  
   306  func (self *RsaObj) Sign(msg []byte) ([]byte, error) {
   307  	h := sha256.New()
   308  	h.Write(msg)
   309  	has := h.Sum(nil)
   310  	res, err := rsa.SignPKCS1v15(rand.Reader, self.privateKey, crypto.SHA256, has)
   311  	if err != nil {
   312  		return nil, err
   313  	}
   314  	return res, nil
   315  }
   316  
   317  func (self *RsaObj) Verify(msg, sign []byte) error {
   318  	if msg == nil || len(msg) == 0 {
   319  		return errors.New("RSA msg invalid")
   320  	}
   321  	if sign == nil || len(sign) == 0 {
   322  		return errors.New("RSA sign invalid")
   323  	}
   324  	has := sha256.Sum256(msg)
   325  	if err := rsa.VerifyPKCS1v15(self.publicKey, crypto.SHA256, has[:], sign); err != nil {
   326  		return err
   327  	}
   328  	return nil
   329  }