-
Notifications
You must be signed in to change notification settings - Fork 117
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
016f803
commit ab7f90b
Showing
6 changed files
with
236 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package util | ||
|
||
import ( | ||
"crypto/aes" | ||
"encoding/hex" | ||
"strings" | ||
) | ||
|
||
var salt = "656f6974656b" | ||
|
||
// select hex(aes_encrypt("123456", unhex("656f6974656b"))); => E310E892E56801CED9ED98AA177F18E6 | ||
func AesEncryptECB(origData string) string { | ||
if origData == "" { | ||
return origData | ||
} | ||
var encrypted []byte | ||
var o = []byte(origData) | ||
s, _ := hex.DecodeString(salt) | ||
cipher, _ := aes.NewCipher(generateKey(s)) | ||
length := (len(o) + aes.BlockSize) / aes.BlockSize | ||
plain := make([]byte, length*aes.BlockSize) | ||
copy(plain, o) | ||
pad := byte(len(plain) - len(o)) | ||
for i := len(o); i < len(plain); i++ { | ||
plain[i] = pad | ||
} | ||
encrypted = make([]byte, len(plain)) | ||
for bs, be := 0, cipher.BlockSize(); bs <= len(o); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() { | ||
cipher.Encrypt(encrypted[bs:be], plain[bs:be]) | ||
} | ||
return strings.ToUpper(hex.EncodeToString(encrypted)) | ||
} | ||
|
||
// select aes_decrypt(unhex("E310E892E56801CED9ED98AA177F18E6"), unhex("656f6974656b")); => 123456 | ||
func AesDecryptECB(encrypted string) string { | ||
if encrypted == "" { | ||
return encrypted | ||
} | ||
var decrypted []byte | ||
h, _ := hex.DecodeString(encrypted) | ||
s, _ := hex.DecodeString(salt) | ||
cipher, _ := aes.NewCipher(generateKey(s)) | ||
decrypted = make([]byte, len(h)) | ||
|
||
for bs, be := 0, cipher.BlockSize(); bs < len(h); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() { | ||
cipher.Decrypt(decrypted[bs:be], h[bs:be]) | ||
} | ||
|
||
bEnd := searchByteSliceIndex(decrypted, 32) | ||
return string(decrypted[:bEnd]) | ||
} | ||
func generateKey(key []byte) (genKey []byte) { | ||
genKey = make([]byte, 16) | ||
copy(genKey, key) | ||
for i := 16; i < len(key); { | ||
for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 { | ||
genKey[j] ^= key[i] | ||
} | ||
} | ||
return genKey | ||
} | ||
|
||
func searchByteSliceIndex(bSrc []byte, b byte) int { | ||
for i := 0; i < len(bSrc); i++ { | ||
if bSrc[i] < b { | ||
return i | ||
} | ||
} | ||
|
||
return len(bSrc) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
package util | ||
|
||
import ( | ||
"reflect" | ||
"strings" | ||
|
||
"github.com/pkg/errors" | ||
) | ||
|
||
const ( | ||
GosyptPrefixDefault = "ENC(" | ||
GosyptSuffxiDefault = ")" | ||
GosyptAlgorithm = "AESWITHHEXANDBASE64" | ||
) | ||
|
||
/* Golang Simple Encrypt, simulate jasypt */ | ||
type Gosypt struct { | ||
prefix string | ||
suffix string | ||
algorithm string | ||
} | ||
|
||
var Gsypt = &Gosypt{ | ||
prefix: GosyptPrefixDefault, | ||
suffix: GosyptSuffxiDefault, | ||
algorithm: GosyptAlgorithm, | ||
} | ||
|
||
func (gsypt *Gosypt) ensurePassword(password string) string { | ||
if !strings.HasPrefix(password, gsypt.prefix) || !strings.HasSuffix(password, gsypt.suffix) { | ||
return password | ||
} | ||
passwd := strings.TrimSuffix(strings.TrimPrefix(password, gsypt.prefix), gsypt.suffix) | ||
if gsypt.algorithm == GosyptAlgorithm { | ||
return AesDecryptECB(passwd) | ||
} | ||
return password | ||
} | ||
|
||
func (gsypt *Gosypt) SetAttribution(prefix, suffix, algorithm string) { | ||
gsypt.prefix = prefix | ||
gsypt.suffix = suffix | ||
gsypt.algorithm = algorithm | ||
} | ||
|
||
func (gsypt *Gosypt) Unmarshal(v interface{}) error { | ||
rt := reflect.TypeOf(v) | ||
rv := reflect.ValueOf(v) | ||
|
||
if rt.Kind() != reflect.Ptr { | ||
return errors.Wrap(nil, "invalid args, expect ptr") | ||
} | ||
|
||
for rt.Kind() == reflect.Ptr { | ||
rt = rt.Elem() | ||
rv = rv.Elem() | ||
} | ||
|
||
if rt.Kind() == reflect.Struct { | ||
v, err := gsypt.structHandle(rt, rv) | ||
if err != nil { | ||
return err | ||
} | ||
rv.Set(v) | ||
} else if rt.Kind() == reflect.Slice || rt.Kind() == reflect.Array { | ||
v, err := gsypt.sliceHandle(rt, rv) | ||
if err != nil { | ||
return err | ||
} | ||
rv.Set(v) | ||
} else if rt.Kind() == reflect.Map { | ||
v, err := gsypt.mapHandle(rt, rv) | ||
if err != nil { | ||
return err | ||
} | ||
rv.Set(v) | ||
} else if rt.Kind() == reflect.Interface { | ||
v, err := gsypt.interfaceHandle(rt, rv) | ||
if err != nil { | ||
return err | ||
} | ||
rv.Set(v) | ||
} else if rt.Kind() == reflect.String { | ||
rv.Set(gsypt.stringHandle(rv)) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (gsypt *Gosypt) sliceHandle(rt reflect.Type, rv reflect.Value) (reflect.Value, error) { | ||
for j := 0; j < rv.Len(); j++ { | ||
if rt.Elem().Kind() == reflect.String { | ||
rv.Index(j).Set(gsypt.stringHandle(rv.Index(j))) | ||
} else { | ||
if err := gsypt.Unmarshal(rv.Index(j).Addr().Interface()); err != nil { | ||
return rv, err | ||
} | ||
} | ||
} | ||
return rv, nil | ||
} | ||
|
||
func (gsypt *Gosypt) mapHandle(rt reflect.Type, rv reflect.Value) (reflect.Value, error) { | ||
for _, k := range rv.MapKeys() { | ||
key := k.Convert(rv.Type().Key()) | ||
if rt.Elem().Kind() == reflect.String { | ||
v := gsypt.ensurePassword(rv.MapIndex(key).String()) | ||
rv.SetMapIndex(key, reflect.ValueOf(v)) | ||
} else { | ||
v := rv.MapIndex(key).Interface() | ||
if err := gsypt.Unmarshal(&v); err != nil { | ||
return rv, err | ||
} | ||
rv.SetMapIndex(key, reflect.ValueOf(v)) | ||
} | ||
} | ||
return rv, nil | ||
} | ||
|
||
func (gsypt *Gosypt) interfaceHandle(rt reflect.Type, rv reflect.Value) (reflect.Value, error) { | ||
//todo | ||
return rv, nil | ||
} | ||
|
||
func (gsypt *Gosypt) structHandle(rt reflect.Type, rv reflect.Value) (reflect.Value, error) { | ||
for i := 0; i < rt.NumField(); i++ { | ||
rtf := rt.Field(i) | ||
rvf := rv.Field(i) | ||
|
||
rtt := rtf.Type | ||
for rtt.Kind() == reflect.Ptr { | ||
rtt = rtt.Elem() | ||
} | ||
|
||
if rtt.Kind() == reflect.String { | ||
rv.Field(i).Set(gsypt.stringHandle(rvf)) | ||
} else { | ||
if err := gsypt.Unmarshal(rvf.Addr().Interface()); err != nil { | ||
return rv, err | ||
} | ||
} | ||
} | ||
return rv, nil | ||
} | ||
|
||
func (gsypt *Gosypt) stringHandle(rv reflect.Value) reflect.Value { | ||
rv.SetString(gsypt.ensurePassword(rv.String())) | ||
return rv | ||
} |