Golang使用json post编码/解码base64并不起作用

时间:2017-05-12 17:00:16

标签: json encryption go base64 aes

我在golang中构建一个客户端和一个服务器都使用这个函数来加密/解密

func encrypt(text []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    b := base64.StdEncoding.EncodeToString(text)
    ciphertext := make([]byte, aes.BlockSize+len(b))
    iv := ciphertext[:aes.BlockSize]
    if _, err := io.ReadFull(rand.Reader, iv); err != nil {
        return nil, err
    }
    cfb := cipher.NewCFBEncrypter(block, iv)
    cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
    return ciphertext, nil
}

func decrypt(text []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    if len(text) < aes.BlockSize {
        return nil, errors.New("ciphertext too short")
    }
    iv := text[:aes.BlockSize]
    text = text[aes.BlockSize:]
    cfb := cipher.NewCFBDecrypter(block, iv)
    cfb.XORKeyStream(text, text)
    data, err := base64.StdEncoding.DecodeString(string(text))
    if err != nil {
        return nil, err
    }
    return data, nil
}

所以我做了一个正常的帖子请求

url := "https://"+configuration.Server+configuration.Port+"/get"

// TODO maybe bugs rest here
ciphertext, err := encrypt([]byte(*getUrl))
if err != nil {
    fmt.Println("Error: " + err.Error())
}
fmt.Println(string(ciphertext))

values := map[string]interface{}{"url": *getUrl, "urlCrypted": ciphertext}
jsonValue, _ := json.Marshal(values)
jsonStr := bytes.NewBuffer(jsonValue)

req, err := http.NewRequest("POST", url, jsonStr)

,服务器代码如下

requestContent := getRequestContentFromRequest(req)
url := requestContent["url"].(string)

undecryptedUrl := requestContent["urlCrypted"].(string)
decryptedurl, err := decrypt([]byte(undecryptedUrl))
if err != nil {
    fmt.Println("Error: " + err.Error())
}
fmt.Println(decryptedurl)

其中getRequestContentFromRequest如下

func getRequestContentFromRequest(req *http.Request)                 
    map[string]interface{} {
    buf := new(bytes.Buffer)
    buf.ReadFrom(req.Body)
    data := buf.Bytes()
    var requestContent map[string]interface{}
    err := json.Unmarshal(data, &requestContent)
    if err != nil {
        fmt.Println(err)
    }
    return requestContent
}

现在问题。 如果我在客户端加密我的字符串并在之后直接解密,一切都很好。

但是,当我将加密的字符串发送到服务器并尝试使用与客户端中相同的函数对其进行解密时,解密函数会抛出错误。

Error: illegal base64 data at input byte 0

我认为问题是JSON的解组。

感谢您的帮助。

P.S。

回购是

github.com/BelphegorPrime/goSafeClient和github.com/BelphegorPrime/goSafe

更新

示例JSON

{"url":"facebook2.com","urlCrypted":"/}\ufffd\ufffd\ufffdgP\ufffdN뼞\ufffd\u0016\ufffd)\ufffd\ufffd\ufffdy\u001c\u000f\ufffd\ufffd\ufffdep\ufffd\rY\ufffd\ufffd$\ufffd\ufffd"}

UPDATE2

我做了一个游乐场here

1 个答案:

答案 0 :(得分:0)

问题是您在base64中编码两次。第一次在encrypt函数中,第二次在JSON编组期间。字节切片由encoding/json编组器自动转换为base64字符串。

解决方案是在调用decrypt之前解码base64字符串。

the Go PlayGround

上的示例

修改

工作解决方案here