douangoo48863 2017-05-12 17:00
浏览 271
已采纳

带有JSON帖子的Golang编码/解码base64不起作用

I build a client and a server in golang both are using this functions to encrypt/decrypt

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
}

so yeah I make a normal post request

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)

and the servercode is as following

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)

where getRequestContentFromRequest is as following

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
}

Now to the problem. If I encrypt my string in the client and decrypt it direct after that everything is fine.

But, when I send the encrypted string to the server and try to decrypt it with literrally the same function as in the client, the decrypt function throws an error.

Error: illegal base64 data at input byte 0

I think the Problem is the unmarshalling of the JSON.

Thanks for help.

P.S.

Repos are

github.com/BelphegorPrime/goSafeClient and github.com/BelphegorPrime/goSafe

UPDATE

Example JSON

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

UPDATE2

I made a playground here

  • 写回答

1条回答 默认 最新

  • douwulu2576 2017-05-14 20:27
    关注

    The problem is that you encode in base64 twice. The first time in the encrypt function and the second time during the JSON marshalling. byte slices are automatically converted into base64 strings by the encoding/json marshaller.

    The solution is to decode the base64 string before calling decrypt.

    Example on the Go PlayGround

    EDIT

    Working solution here

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

    报告相同问题?

    悬赏问题

    • ¥15 关于C语言使用线程队列实现多线程并发
    • ¥15 这个运行,错误在哪里呀,大家看看吧,教导我
    • ¥15 advanceinstaller对话框设置
    • ¥100 正常上网,内部网页无法打开
    • ¥15 组件库引入并使用在若依框架未展示
    • ¥149 关于#使用python 的Flash Echarts+ajax+mysql动态数据实现饼图#的问题,请各位专家解答!
    • ¥15 RichTextBox中追加文本时报错
    • ¥15 关于c语言的学习问题
    • ¥15 activity升级到flowable工作流act_ge_bytearray的草稿json数据复制到act_de_model 的model_editor_json的脚本
    • ¥15 cvi使用CreateThread创建线程时,出现存储空间不足无法处理此命令的错误