小花狸監控之加密

壹頁書發表於2015-03-28
小花狸監控
採用對稱加密演算法AES
明文首先經過Base64編碼,然後用空格填充到指定位數,使用AES加密,最後將加密的資料再用Base64編碼

$GOPATH/probe/module/AES.go

package module

import (
    "crypto/aes"
    "crypto/cipher"
    "crypto/rand"
    "encoding/base64"
    "encoding/hex"
    "errors"
    "fmt"
    "io"
    "strings"
    "sync"
)

const (
    //aesTable是金鑰
    aesTable    = "abcdefghijklmnopkrstuvwsyz333333"
    base64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
)

var (
    block       cipher.Block
    mutex       sync.Mutex
    base64Coder = base64.NewEncoding(base64Table)
)

func EncryptString(src string) string {
    datastr := base64Coder.EncodeToString([]byte(src))
    for len(datastr)%aes.BlockSize != 0 {
        datastr = datastr + " "
    }
    data, _ := Encrypt([]byte(datastr))
    result := base64Coder.EncodeToString(data)
    return result
}

// AES加密
func Encrypt(src []byte) ([]byte, error) {
    // 驗證輸入引數
    // 必須為aes.Blocksize的倍數
    if len(src)%aes.BlockSize != 0 {
        return nil, errors.New("crypto/cipher: input not full blocks")
    }

    encryptText := make([]byte, aes.BlockSize+len(src))

    iv := encryptText[:aes.BlockSize]
    if _, err := io.ReadFull(rand.Reader, iv); err != nil {
        return nil, err
    }

    mode := cipher.NewCBCEncrypter(block, iv)

    mode.CryptBlocks(encryptText[aes.BlockSize:], src)

    return encryptText, nil
}

func DecryptString(src string) string {
    var result []byte
    data, _ := base64Coder.DecodeString(src)
    data, _ = Decrypt(data)
    datastr := strings.Trim(string(data), " ")
    result, _ = base64Coder.DecodeString(datastr)
    return string(result)
}

// AES解密
func Decrypt(src []byte) ([]byte, error) {
    // hex
    decryptText, err := hex.DecodeString(fmt.Sprintf("%x", string(src)))
    if err != nil {
        return nil, err
    }

    // 長度不能小於aes.Blocksize
    if len(decryptText) < aes.BlockSize {
        return nil, errors.New("crypto/cipher: ciphertext too short")
    }

    iv := decryptText[:aes.BlockSize]
    decryptText = decryptText[aes.BlockSize:]

    // 驗證輸入引數
    // 必須為aes.Blocksize的倍數
    if len(decryptText)%aes.BlockSize != 0 {
        return nil, errors.New("crypto/cipher: ciphertext is not a multiple of the block size")
    }

    mode := cipher.NewCBCDecrypter(block, iv)

    mode.CryptBlocks(decryptText, decryptText)

    return decryptText, nil
}

func init() {
    mutex.Lock()
    defer mutex.Unlock()

    if block != nil {
        return
    }

    cblock, err := aes.NewCipher([]byte(aesTable))
    if err != nil {
        panic("aes.NewCipher: " + err.Error())
    }

    block = cblock
}

呼叫程式
$GOPATH/main.go

package main                                             
     
import (                                                                                     
        "fmt"                                                                                
        "probe/module"                                                                       
)                                                                                            
                                                                                             
func main() {                                                                                
        data := "zbcdfe"                                                                     
        fmt.Println("明文:", data)                                                           
        s := module.EncryptString(data)                                                      
        fmt.Println("密文:", s)                                                              
        fmt.Println("解密:", module.DecryptString(s))                                        
}                                                                                            
~  
結果:


參考:
http://www.oschina.net/code/snippet_197499_25891


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1477252/,如需轉載,請註明出處,否則將追究法律責任。

相關文章