diff --git a/src/cmd/frps/control.go b/src/cmd/frps/control.go index ec60078..15620ff 100644 --- a/src/cmd/frps/control.go +++ b/src/cmd/frps/control.go @@ -229,6 +229,7 @@ func doLogin(req *msg.ControlReq, c *conn.Conn) (ret int64, info string) { } else if req.PrivilegeKey != privilegeKey { info = fmt.Sprintf("ProxyName [%s], privilege mode authorization failed", req.ProxyName) log.Warn(info) + log.Debug("PrivilegeKey [%s] and get [%s]", privilegeKey, req.PrivilegeKey) return } } else { @@ -241,6 +242,7 @@ func doLogin(req *msg.ControlReq, c *conn.Conn) (ret int64, info string) { } else if req.AuthKey != authKey { info = fmt.Sprintf("ProxyName [%s], authorization failed", req.ProxyName) log.Warn(info) + log.Debug("AuthKey [%s] and get [%s]", authKey, req.AuthKey) return } } diff --git a/src/utils/pcrypto/pcrypto.go b/src/utils/pcrypto/pcrypto.go index 8f5e873..65b7fbd 100644 --- a/src/utils/pcrypto/pcrypto.go +++ b/src/utils/pcrypto/pcrypto.go @@ -20,9 +20,10 @@ import ( "crypto/aes" "crypto/cipher" "crypto/md5" + "crypto/rand" "encoding/hex" - "errors" "fmt" + "io" "io/ioutil" ) @@ -33,35 +34,47 @@ type Pcrypto struct { func (pc *Pcrypto) Init(key []byte) error { var err error - pc.pkey = pKCS7Padding(key, aes.BlockSize) + pc.pkey = pkKeyPadding(key) pc.paes, err = aes.NewCipher(pc.pkey) return err } func (pc *Pcrypto) Encrypt(src []byte) ([]byte, error) { // aes - src = pKCS7Padding(src, aes.BlockSize) - blockMode := cipher.NewCBCEncrypter(pc.paes, pc.pkey) - crypted := make([]byte, len(src)) - blockMode.CryptBlocks(crypted, src) - return crypted, nil + src = pKCS5Padding(src, aes.BlockSize) + ciphertext := make([]byte, aes.BlockSize+len(src)) + + // The IV needs to be unique, but not secure. Therefore it's common to + // include it at the beginning of the ciphertext. + iv := ciphertext[:aes.BlockSize] + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + return nil, err + } + blockMode := cipher.NewCBCEncrypter(pc.paes, iv) + blockMode.CryptBlocks(ciphertext[aes.BlockSize:], src) + return ciphertext, nil } func (pc *Pcrypto) Decrypt(str []byte) ([]byte, error) { // aes - decryptText, err := hex.DecodeString(fmt.Sprintf("%x", str)) + ciphertext, err := hex.DecodeString(fmt.Sprintf("%x", str)) if err != nil { return nil, err } - if len(decryptText)%aes.BlockSize != 0 { - return nil, errors.New("crypto/cipher: ciphertext is not a multiple of the block size") + if len(ciphertext) < aes.BlockSize { + return nil, fmt.Errorf("ciphertext too short") + } + iv := ciphertext[:aes.BlockSize] + ciphertext = ciphertext[aes.BlockSize:] + + if len(ciphertext)%aes.BlockSize != 0 { + return nil, fmt.Errorf("crypto/cipher: ciphertext is not a multiple of the block size") } - blockMode := cipher.NewCBCDecrypter(pc.paes, pc.pkey) - - blockMode.CryptBlocks(decryptText, decryptText) - return pKCS7UnPadding(decryptText), nil + blockMode := cipher.NewCBCDecrypter(pc.paes, iv) + blockMode.CryptBlocks(ciphertext, ciphertext) + return pKCS5UnPadding(ciphertext), nil } func (pc *Pcrypto) Compression(src []byte) ([]byte, error) { @@ -87,13 +100,32 @@ func (pc *Pcrypto) Decompression(src []byte) ([]byte, error) { return str, nil } -func pKCS7Padding(ciphertext []byte, blockSize int) []byte { +func pkKeyPadding(key []byte) []byte { + l := len(key) + if l == 16 || l == 24 || l == 32 { + return key + } + if l < 16 { + return append(key, bytes.Repeat([]byte{byte(0)}, 16-l)...) + } else if l < 24 { + return append(key, bytes.Repeat([]byte{byte(0)}, 24-l)...) + } else if l < 32 { + return append(key, bytes.Repeat([]byte{byte(0)}, 32-l)...) + } else { + md5Ctx := md5.New() + md5Ctx.Write(key) + md5Str := md5Ctx.Sum(nil) + return []byte(hex.EncodeToString(md5Str)) + } +} + +func pKCS5Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) } -func pKCS7UnPadding(origData []byte) []byte { +func pKCS5UnPadding(origData []byte) []byte { length := len(origData) unpadding := int(origData[length-1]) return origData[:(length - unpadding)] diff --git a/src/utils/pcrypto/pcrypto_test.go b/src/utils/pcrypto/pcrypto_test.go index 41a1755..cfe8923 100644 --- a/src/utils/pcrypto/pcrypto_test.go +++ b/src/utils/pcrypto/pcrypto_test.go @@ -24,7 +24,7 @@ var ( func init() { pp = &Pcrypto{} - pp.Init([]byte("Hana")) + pp.Init([]byte("12234567890123451223456789012345321:wq")) } func TestEncrypt(t *testing.T) { @@ -60,3 +60,18 @@ func TestCompression(t *testing.T) { t.Fatalf("test compression error, from [%s] to [%s]", testStr, string(res)) } } + +func BenchmarkEncrypt(b *testing.B) { + testStr := "Test Encrypt!" + for i := 0; i < b.N; i++ { + pp.Encrypt([]byte(testStr)) + } +} + +func BenchmarkDecrypt(b *testing.B) { + testStr := "Test Encrypt!" + res, _ := pp.Encrypt([]byte(testStr)) + for i := 0; i < b.N; i++ { + pp.Decrypt([]byte(res)) + } +}