golang实现百度智能小程序用户数据的解密

golang实现百度智能小程序用户数据的解密

Anderyly
2023-03-18 / 0 评论 / 35 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2024年02月27日,已超过280天没有更新,若内容或图片失效,请留言反馈。

golang实现百度智能小程序用户数据的解密

百度智能小程序官方文档

博主在网上gitee github找了很多 几乎没有看到适配golang的方法,以下方法可行

类库

/*
 * @author anderyly
 * @email admin@aaayun.cc
 * @link http://blog.aaayun.cc
 * @copyright Copyright (c) 2023
 *
 */

package baidu

import (
    "crypto/aes"
    "crypto/cipher"
    "encoding/base64"
    "encoding/json"
    "errors"
    "fmt"
    "regexp"
)

var _ AppletDataCrypt = (*appletDataCrypt)(nil)

type AppletDataCrypt interface {
    Decrypt(data string, iv string, isJSON bool) (interface{}, error) // 解密
}

type appletDataCrypt struct {
    AppID      string
    SessionKey string
}

var errorCode = map[string]int{
    "IllegalAppID":      -41000,
    "IllegalAesKey":     -41001,
    "IllegalIV":         -41002,
    "IllegalBuffer":     -41003,
    "DecodeBase64Error": -41004,
    "DecodeJsonError":   -41005,
}

type showError struct {
    errorCode int
    errorMsg  error
}

func NewAppletDataCrypt(appid, sessionKey string) AppletDataCrypt {
    return &appletDataCrypt{
        AppID:      appid,
        SessionKey: sessionKey,
    }
}

func (e showError) Error() string {
    return fmt.Sprintf("{code: %v, error: \"%v\"}", e.errorCode, e.errorMsg)
}

func (con *appletDataCrypt) Decrypt(data string, iv string, isJSON bool) (interface{}, error) {
    aesKey, err := base64.StdEncoding.DecodeString(con.SessionKey)
    if err != nil {
        return nil, showError{errorCode["DecodeBase64Error"], err}
    }

    if len(iv) != 24 {
        return nil, showError{errorCode["IllegalIV"], errors.New("iv length is error")}
    }
    aesIV, err := base64.StdEncoding.DecodeString(iv)
    if err != nil {
        return nil, showError{errorCode["DecodeBase64Error"], err}
    }

    aesCipherText, err := base64.StdEncoding.DecodeString(data)
    if err != nil {
        return nil, showError{errorCode["DecodeBase64Error"], err}
    }
    aesPlantText := make([]byte, len(aesCipherText))

    aesBlock, err := aes.NewCipher(aesKey)
    if err != nil {
        return nil, showError{errorCode["IllegalBuffer"], err}
    }

    mode := cipher.NewCBCDecrypter(aesBlock, aesIV)
    mode.CryptBlocks(aesPlantText, aesCipherText)
    aesPlantText = con.PKCS7UnPadding(aesPlantText)

    var decrypted map[string]interface{}

    re := regexp.MustCompile(`[^\{]*(\{.*\})[^\}]*`)
    aesPlantText = []byte(re.ReplaceAllString(string(aesPlantText), "$1"))

    err = json.Unmarshal(aesPlantText, &decrypted)
    if err != nil {
        return nil, showError{errorCode["DecodeJsonError"], err}
    }

    if isJSON == true {
        return string(aesPlantText), nil
    }

    return decrypted, nil
}

func (con *appletDataCrypt) PKCS7UnPadding(plantText []byte) []byte {
    length := len(plantText)
    if length > 0 {
        unPadding := int(plantText[length-1])
        return plantText[:(length - unPadding)]
    }
    return plantText
}

调用方法

// res为json需要自行json.Unmarshal这里不做演示
res, err := baidu.NewAppletDataCryp("appid", "sessionKey").Decrypt("加密的数据", "偏移量", true)
0

评论 (0)

取消