main.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. package crypto
  2. import (
  3. "bytes"
  4. "crypto/aes"
  5. "crypto/cipher"
  6. "crypto/md5"
  7. "crypto/rand"
  8. "crypto/rsa"
  9. "crypto/x509"
  10. "encoding/base64"
  11. "encoding/hex"
  12. "encoding/pem"
  13. "fmt"
  14. "strconv"
  15. "time"
  16. "github.com/pkg/errors"
  17. )
  18. // const .
  19. const (
  20. BlockSizeMIN = 16 // AES-128
  21. BlockSizeMID = 24 // AES-192
  22. BlockSizeMAX = 32 // AES-256
  23. )
  24. // Main mainsite cryptor
  25. type Main struct {
  26. publicKey, privateKey []byte
  27. }
  28. // NewMain is.
  29. func NewMain(pub, priv string) (e *Main) {
  30. return &Main{
  31. publicKey: []byte(pub),
  32. privateKey: []byte(priv),
  33. }
  34. }
  35. // IMGEncrypt rsa + AES-128
  36. func (e *Main) IMGEncrypt(raw []byte) (data []byte, err error) {
  37. if len(raw) == 0 {
  38. return
  39. }
  40. var (
  41. hash = md5.New()
  42. randToken []byte
  43. rsaData, aesData []byte
  44. aesBase64 []byte
  45. rsaBase64Str string
  46. buf bytes.Buffer
  47. )
  48. if _, err = hash.Write([]byte(strconv.FormatInt(time.Now().UnixNano(), 10))); err != nil {
  49. err = errors.WithStack(err)
  50. return
  51. }
  52. randToken = []byte(hex.EncodeToString(hash.Sum(nil)))
  53. if rsaData, err = e.RsaEncrypt(randToken); err != nil {
  54. err = errors.WithStack(err)
  55. return
  56. }
  57. if aesData, err = e.AESEncrypt(randToken, raw, BlockSizeMIN); err != nil {
  58. err = errors.WithStack(err)
  59. return
  60. }
  61. rsaBase64Str = base64.StdEncoding.EncodeToString(rsaData)
  62. aesBase64 = make([]byte, base64.StdEncoding.EncodedLen(len(aesData)))
  63. base64.StdEncoding.Encode(aesBase64, aesData)
  64. fmt.Fprintf(&buf, "%04x", len(rsaBase64Str))
  65. buf.Write([]byte(rsaBase64Str))
  66. buf.Write(aesBase64)
  67. data = buf.Bytes()
  68. return
  69. }
  70. // IMGDecrypt rsa + AES-128
  71. func (e *Main) IMGDecrypt(raw []byte) (data []byte, err error) {
  72. if len(raw) == 0 {
  73. return
  74. }
  75. var (
  76. rsaLen int64
  77. rsaRandToken []byte
  78. randToken []byte
  79. aesBase64 []byte
  80. aesData []byte
  81. base64DecodedSize int
  82. )
  83. if rsaLen, err = strconv.ParseInt(string(raw[:4]), 16, 64); err != nil {
  84. err = errors.WithStack(err)
  85. return
  86. }
  87. if rsaRandToken, err = base64.StdEncoding.DecodeString(string(raw[4 : 4+rsaLen])); err != nil {
  88. err = errors.WithStack(err)
  89. return
  90. }
  91. if randToken, err = e.RsaDecrypt(rsaRandToken); err != nil {
  92. err = errors.WithStack(err)
  93. return
  94. }
  95. aesBase64 = raw[4+rsaLen:]
  96. aesData = make([]byte, base64.StdEncoding.DecodedLen(len(aesBase64)))
  97. if base64DecodedSize, err = base64.StdEncoding.Decode(aesData, aesBase64); err != nil {
  98. err = errors.WithStack(err)
  99. return
  100. }
  101. if data, err = e.AESDecrypt(randToken, aesData[:base64DecodedSize], BlockSizeMIN); err != nil {
  102. err = errors.WithStack(err)
  103. return
  104. }
  105. return
  106. }
  107. // RsaEncrypt rsa encrypt.
  108. func (e *Main) RsaEncrypt(text []byte) (data []byte, err error) {
  109. var (
  110. block *pem.Block
  111. )
  112. block, _ = pem.Decode(e.publicKey)
  113. if block == nil {
  114. return nil, errors.New("public key error")
  115. }
  116. var (
  117. pubInterface interface{}
  118. pub *rsa.PublicKey
  119. )
  120. if pubInterface, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
  121. err = errors.WithStack(err)
  122. return nil, err
  123. }
  124. pub = pubInterface.(*rsa.PublicKey)
  125. if data, err = rsa.EncryptPKCS1v15(rand.Reader, pub, text); err != nil {
  126. err = errors.WithStack(err)
  127. return
  128. }
  129. return
  130. }
  131. // RsaDecrypt rsa decrypt.
  132. func (e *Main) RsaDecrypt(text []byte) (data []byte, err error) {
  133. var (
  134. block *pem.Block
  135. )
  136. block, _ = pem.Decode(e.privateKey)
  137. if block == nil {
  138. return nil, errors.New("private key error")
  139. }
  140. var (
  141. privateKey *rsa.PrivateKey
  142. )
  143. if privateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
  144. err = errors.WithStack(err)
  145. return
  146. }
  147. if data, err = rsa.DecryptPKCS1v15(rand.Reader, privateKey, text); err != nil {
  148. err = errors.WithStack(err)
  149. return
  150. }
  151. return
  152. }
  153. // AESEncrypt AES-128, AES-192, or AES-256 encrypt.
  154. // mod 16, 24, or 32 bytes
  155. func (e *Main) AESEncrypt(key, text []byte, mod int) (data []byte, err error) {
  156. var (
  157. block cipher.Block
  158. )
  159. if block, err = aes.NewCipher(key[:mod]); err != nil {
  160. err = errors.WithStack(err)
  161. return
  162. }
  163. msg := pkPadding(text, block.BlockSize())
  164. ciphertext := make([]byte, len(msg))
  165. cbc := cipher.NewCBCEncrypter(block, key[mod:])
  166. cbc.CryptBlocks(ciphertext, []byte(msg))
  167. return ciphertext, nil
  168. }
  169. // AESDecrypt AES-128, AES-192, or AES-256 decrypt.
  170. // mod 16, 24, or 32 bytes
  171. func (e *Main) AESDecrypt(key, text []byte, mod int) (data []byte, err error) {
  172. var (
  173. block cipher.Block
  174. )
  175. if block, err = aes.NewCipher(key[:mod]); err != nil {
  176. err = errors.WithStack(err)
  177. return
  178. }
  179. blockModel := cipher.NewCBCDecrypter(block, key[mod:])
  180. ciphertext := make([]byte, len(text))
  181. blockModel.CryptBlocks(ciphertext, text)
  182. ciphertext = pkUnPadding(ciphertext)
  183. return ciphertext, nil
  184. }
  185. func pkPadding(src []byte, blockSize int) []byte {
  186. padding := blockSize - len(src)%blockSize
  187. padtext := bytes.Repeat([]byte{byte(0)}, padding)
  188. return append(src, padtext...)
  189. }
  190. func pkUnPadding(src []byte) []byte {
  191. length := len(src)
  192. unpadding := int(src[length-1])
  193. return src[:(length - unpadding)]
  194. }