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

带有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

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