package gauth import ( "crypto/aes" "fmt" "strings" b64 "encoding/base64" "github.com/happierall/l" "github.com/metarare/metarare_api/helpers" ) func prepareForAES() (string, error) { vv := helpers.LoadEnvs() v := vv.GetString("jwt.aes_secret") if strings.Compare(v, "") != 0 { return v, nil } else { l.Error("There is no JWTKey ") return "", fmt.Errorf("Threr is no AES SECRET!!!") } } func encrpyt(plainText string) ([]byte, error) { k, err := prepareForAES() if err != nil { l.Error(err.Error()) return nil, err } if len(k) < len(plainText) { err := fmt.Errorf("Plain text is too long...(Max size %d)", len(k)) l.Errorf(err.Error()) return nil, err } if len(plainText) > 255 { err := fmt.Errorf("Plain data is too long MAX SIZE is 255") l.Errorf(err.Error()) return nil, err } tempData := []byte(k[:aes.BlockSize]) block, err := aes.NewCipher(tempData) if err != nil { l.Error(err) return nil, err } devidedText := make([]string, len(plainText)/aes.BlockSize+1) lastBlockSize := len(plainText) % aes.BlockSize for i := 0; i < len(devidedText)-1; i++ { devidedText[i] = plainText[i*aes.BlockSize : (i+1)*aes.BlockSize] } padding := make([]byte, aes.BlockSize-lastBlockSize) devidedText[len(devidedText)-1] = fmt.Sprintf("%s%s", plainText[aes.BlockSize*(len(devidedText)-1):len(plainText)], string(padding)) // NOTE It work good even if doesn't do initializing why? //devidedText[len(devidedText)-1 ] = append( devidedText[len(devidedText)-1 ], padding) prefix := make([]byte, 1) // 마지막 블럭의 사이즈 prefix[0] = byte(lastBlockSize) & 0xff //encData := string(prefix) encData := prefix //store := make([]byte, aes.BlockSize*len(devidedText)+1) store := make([]byte, aes.BlockSize) for i := range devidedText { block.Encrypt(store, []byte(devidedText[i])) //encData = encData + string(store) encData = append(encData, store...) // l.Log("block data : (%s) , totalString (%s)", store, encData) } //return fmt.Sprintf("%s", encData), nil return encData, nil } func E(text string) []byte { if v, err := encrpyt(text); err != nil { l.Error("invalid value") return nil } else { return v } } func Pack(raw string) string { encData := E(raw) b64EncData := b64.URLEncoding.EncodeToString(encData) return b64EncData } func decrpyt(encData string) ([]byte, error) { k, err := prepareForAES() if err != nil { return nil, err } if len(k) < len(encData) { err := fmt.Errorf("Plain text is too long...(Max size %d)", len(k)) l.Errorf(err.Error()) return nil, err } if len(encData) > 255 { err := fmt.Errorf("Plain data is too long MAX SIZE is 255") l.Errorf(err.Error()) return nil, err } if len(encData)%aes.BlockSize != 1 { // encData size have to fit [len(encData) =16 * n + 1] err := fmt.Errorf("encData size have to fit [len(encData) =16 * n + 1]") l.Errorf(err.Error()) return nil, err } block, err := aes.NewCipher([]byte(k[:aes.BlockSize])) if err != nil { l.Error(err) return nil, err } lastBlockSize := int([]byte(encData[:1])[0] & 0xff) leftEncData := []byte(encData[1:len(encData)]) /// new devidedTextLen := len(leftEncData) / aes.BlockSize if len(leftEncData)%aes.BlockSize != 0 { devidedTextLen++ } devidedText := make([][]byte, devidedTextLen) for i := range devidedText { devidedText[i] = leftEncData[aes.BlockSize*i : aes.BlockSize*(i+1)] } plainBinary := make([]byte, 0) store := make([]byte, aes.BlockSize) for i := 0; i < devidedTextLen; i++ { block.Decrypt(store, []byte(devidedText[i])) plainBinary = append(plainBinary, store...) } return plainBinary[:len(leftEncData)-(aes.BlockSize-lastBlockSize)], nil } func D(encData string) []byte { if v, err := decrpyt(encData); err != nil { l.Error("invalid value") return nil } else { return v } } func UnPack(b64EncData string) string { decoded64Data, _ := b64.URLEncoding.DecodeString(b64EncData) decData := D(string(decoded64Data)) return string(decData) }