123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- package jyutil
- import (
- "bytes"
- "crypto/rand"
- "crypto/rsa"
- "crypto/x509"
- "encoding/json"
- "encoding/pem"
- "log"
- "sync"
- "time"
- util "app.yhyue.com/moapp/jybase/common"
- . "app.yhyue.com/moapp/jybase/date"
- "app.yhyue.com/moapp/jybase/redis"
- "github.com/robfig/cron/v3"
- )
- //
- type RsaStruct struct {
- Sign string
- PrivateKey *rsa.PrivateKey
- PublicKey *rsa.PublicKey
- RsaConfig *RsaConfig
- }
- type RsaConfig struct {
- RsaSignflag string
- PrivateKeyStr string
- PublicKeyStr string
- }
- type MyWrite struct {
- Byte *bytes.Buffer
- }
- func (m MyWrite) Write(p []byte) (n int, err error) {
- n, err = m.Byte.Write(p)
- return
- }
- func getNewRsaConfig() *RsaConfig {
- //私钥-----
- privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
- if err != nil {
- log.Println(err)
- }
- X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey)
- privateBlock := pem.Block{Type: "RSA Private Key", Bytes: X509PrivateKey}
- privateWrite := MyWrite{Byte: bytes.NewBuffer([]byte(""))}
- pem.Encode(privateWrite, &privateBlock)
- privateKeyByte := privateWrite.Byte.Bytes()
- //公钥----
- publicKey := privateKey.PublicKey
- X509PublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
- if err != nil {
- log.Println(err)
- }
- publicBlock := pem.Block{Type: "RSA Public Key", Bytes: X509PublicKey}
- publicWrite := MyWrite{Byte: bytes.NewBuffer([]byte(""))}
- pem.Encode(publicWrite, &publicBlock)
- publicKeyByte := publicWrite.Byte.Bytes()
- return &RsaConfig{
- RsaSignflag: time.Now().Format(Date_Full_Layout),
- PrivateKeyStr: string(privateKeyByte),
- PublicKeyStr: string(publicKeyByte),
- }
- }
- func initRsa(config *RsaConfig) *RsaStruct {
- //初始化私钥
- private_block, _ := pem.Decode([]byte(config.PrivateKeyStr))
- private, err := x509.ParsePKCS1PrivateKey(private_block.Bytes)
- if err != nil {
- log.Println(err)
- }
- //初始化公钥
- public_block, _ := pem.Decode([]byte(config.PublicKeyStr))
- publicKeyInterface, err := x509.ParsePKIXPublicKey(public_block.Bytes)
- if err != nil {
- log.Println(err)
- }
- public := publicKeyInterface.(*rsa.PublicKey)
- return &RsaStruct{
- Sign: config.RsaSignflag,
- RsaConfig: config,
- PrivateKey: private,
- PublicKey: public,
- }
- }
- //加密
- func (r *RsaStruct) Encrypt(str string) string {
- enStrByte, err := rsa.EncryptPKCS1v15(rand.Reader, r.PublicKey, []byte(str))
- if err != nil {
- log.Printf("%s加密失败%v", str, err)
- }
- return string(enStrByte)
- }
- //解密
- func (r *RsaStruct) Decrypt(enStr string) string {
- deStrByte, err := rsa.DecryptPKCS1v15(rand.Reader, r.PrivateKey, []byte(enStr))
- if err != nil {
- log.Printf("%s解密失败%v", enStr, err)
- }
- return string(deStrByte)
- }
- type EncryptionStruct struct {
- RsaStruct_Now *RsaStruct
- MapRsa map[string]*RsaStruct
- EncryptionConf *EncryptionConf
- Lock *sync.Mutex
- }
- type EncryptionConf struct {
- Now string
- MapRsaConf map[string]*RsaConfig
- }
- //首次启动加载秘钥
- func InitEncryptionStruct(Sysconfig map[string]interface{}) *EncryptionStruct {
- encryStruct := EncryptionStruct{EncryptionConf: &EncryptionConf{}, Lock: &sync.Mutex{}}
- // log.Println("xxxxxx", redis.GetInt("other", "jynode_"+nodemgr.NodeName))
- // isMaster := util.If(redis.GetInt("other", "jynode_"+nodemgr.NodeName) == 1, true, false).(bool)
- go func() {
- cn := cron.New()
- str := util.ObjToString(Sysconfig["sessionEnctryFlushCorn"])
- cn.AddFunc(str, func() {
- encryStruct.Flush(Sysconfig)
- })
- cn.Start()
- }()
- //for {
- redis_obj := util.ObjToString(redis.Get("session", "sessionEncryption"))
- if redis_obj != "" {
- encryconf := EncryptionConf{}
- err := json.Unmarshal([]byte(redis_obj), &encryconf)
- if err != nil {
- log.Println("InitEncryptionStruct Unmarshal redis err", err)
- } else {
- encryStruct.EncryptionConf = &encryconf
- encryStruct.initAllRsa()
- log.Println("从redis中加载EncryptionStruct")
- return &encryStruct
- }
- }
- log.Println("主结点首次创建EncryptionStruct")
- newRsaConf := getNewRsaConfig()
- encryStruct.EncryptionConf.Now = newRsaConf.RsaSignflag
- encryStruct.EncryptionConf.MapRsaConf = map[string]*RsaConfig{newRsaConf.RsaSignflag: newRsaConf}
- encryStruct.initAllRsa()
- go func() {
- //存入redis
- byteArr, err := json.Marshal(encryStruct.EncryptionConf)
- log.Println(string(byteArr))
- if err != nil {
- log.Printf("InitEncryptionStruct save %s redis err %:v\n", byteArr, err)
- return
- }
- redis.Put("session", "sessionEncryption", string(byteArr), -1)
- }()
- return &encryStruct
- }
- func (e *EncryptionStruct) initAllRsa() {
- e.Lock.Lock()
- defer e.Lock.Unlock()
- e.MapRsa = map[string]*RsaStruct{}
- for k, v := range e.EncryptionConf.MapRsaConf {
- thisRsa := initRsa(v)
- e.MapRsa[k] = thisRsa
- if k == e.EncryptionConf.Now {
- e.RsaStruct_Now = thisRsa
- }
- }
- }
- //定时更新秘钥
- func (e *EncryptionStruct) Flush(Sysconfig map[string]interface{}) {
- NodeName := util.ObjToString(Sysconfig["nodeName"])
- isMaster := util.If(redis.GetInt("other", "jynode_"+NodeName) == 1, true, false).(bool)
- if !isMaster {
- //从节点从redis中更新秘钥
- for {
- redis_obj := util.ObjToString(redis.Get("session", "sessionEncryption"))
- if redis_obj != "" {
- encryconf := EncryptionConf{}
- err := json.Unmarshal([]byte(redis_obj), &encryconf)
- if e.RsaStruct_Now.Sign == encryconf.Now {
- log.Println("从节点定时更新EncryptionStruct失败,一分钟后重试", e.RsaStruct_Now.Sign)
- time.Sleep(time.Minute)
- if redis.GetInt("other", "jynode_"+NodeName) == 1 {
- break
- } else {
- continue
- }
- }
- if err != nil {
- log.Println("InitEncryptionStruct Unmarshal redis err", err)
- } else {
- e.EncryptionConf = &encryconf
- e.initAllRsa()
- log.Println("从节点定时更新EncryptionStruct")
- return
- }
- }
- }
- } else {
- e.Lock.Lock()
- //主结点生成秘钥 存入redis
- log.Printf("主结点更新EncryptionStruct before %+v", e.MapRsa)
- last := e.RsaStruct_Now
- newRsa := initRsa(getNewRsaConfig())
- //更新map
- e.MapRsa = map[string]*RsaStruct{newRsa.Sign: newRsa, last.Sign: last}
- //更新默认加密
- e.RsaStruct_Now = newRsa
- log.Printf("after %+v", e.MapRsa)
- e.Lock.Unlock()
- //更新redis
- func() {
- e.EncryptionConf.Now = e.RsaStruct_Now.Sign
- e.EncryptionConf.MapRsaConf = map[string]*RsaConfig{newRsa.Sign: newRsa.RsaConfig, last.Sign: last.RsaConfig}
- byteArr, err := json.Marshal(e.EncryptionConf)
- log.Println("主结点更新sessionEncryption", string(byteArr))
- if err != nil {
- log.Printf("InitEncryptionStruct save %s redis err %:v\n", byteArr, err)
- return
- }
- redis.Put("session", "sessionEncryption", string(byteArr), -1)
- }()
- }
- }
|