吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1103|回复: 6
收起左侧

[求助] 移动云盘sign签名算法

  [复制链接]
asd124689 发表于 2023-8-6 17:46
"2023-08-06 17:22:21,XGfeKeQB4dkgNSF3,585044BBD05BEC21B25A2437199BDC92"
"2023-08-06 17:22:22,vEp3QJkwsI25bpmX,2B2DF0CF68ACA8727B81C534D42BABC2"
"2023-08-06 17:22:24,aZ3gvANn3fspWIP0,BD26FBA18AA5C977450221546C4D6B8A"
"2023-08-06 17:15:56,uZBWnqE9jajzoSx2,0C20C7C7C5C4BC980747FA1AC95C7A38"
"2023-08-06 17:15:58,0gdlmSX1ufnLcQ6A,B74E92AB954F80403ED5BD2148FF51A6"
"2023-08-06 16:42:58,6WSgQjMBk3j6RLv0,2D5A894A6B8FF2B3FA819EBF3AD15328"
"2023-08-06 16:45:50,nMsFqP03lRBYhjEv,0CFEC975281BADDD32FF924AACE36734"

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| asd124689 发表于 2023-8-6 17:48
这是几次请求头的值,请问大佬们如何使用python计算这个签名,签名应该是请求时间戳格式化,中间一段随机字符串 后面md5?
 楼主| asd124689 发表于 2023-8-6 21:12

package _139

import (
        "encoding/base64"
        "errors"
        "fmt"
        "net/http"
        "net/url"
        "sort"
        "strconv"
        "strings"
        "time"

        "github.com/alist-org/alist/v3/drivers/base"
        "github.com/alist-org/alist/v3/internal/model"
        "github.com/alist-org/alist/v3/pkg/utils"
        "github.com/alist-org/alist/v3/pkg/utils/random"
        "github.com/go-resty/resty/v2"
        jsoniter "github.com/json-iterator/go"
        log "github.com/sirupsen/logrus"
)

// do others that not defined in Driver interface
func (d *Yun139) isFamily() bool {
        return d.Type == "family"
}

func encodeURIComponent(str string) string {
        r := url.QueryEscape(str)
        r = strings.Replace(r, "+", "%20", -1)
        r = strings.Replace(r, "%21", "!", -1)
        r = strings.Replace(r, "%27", "'", -1)
        r = strings.Replace(r, "%28", "(", -1)
        r = strings.Replace(r, "%29", ")", -1)
        r = strings.Replace(r, "%2A", "*", -1)
        return r
}

func calSign(body, ts, randStr string) string {
        body = encodeURIComponent(body)
        strs := strings.Split(body, "")
        sort.Strings(strs)
        body = strings.Join(strs, "")
        body = base64.StdEncoding.EncodeToString([]byte(body))
        res := utils.GetMD5EncodeStr(body) + utils.GetMD5EncodeStr(ts+":"+randStr)
        res = strings.ToUpper(utils.GetMD5EncodeStr(res))
        return res
}

func getTime(t string) time.Time {
        stamp, _ := time.ParseInLocation("20060102150405", t, time.Local)
        return stamp
}

func (d *Yun139) request(pathname string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
        url := "https://yun.139.com" + pathname
        req := base.RestyClient.R()
        randStr := random.String(16)
        ts := time.Now().Format("2006-01-02 15:04:05")
        if callback != nil {
                callback(req)
        }
        body, err := utils.Json.Marshal(req.Body)
        if err != nil {
                return nil, err
        }
        sign := calSign(string(body), ts, randStr)
        svcType := "1"
        if d.isFamily() {
                svcType = "2"
        }
        req.SetHeaders(map[string]string{
                "Accept":         "application/json, text/plain, */*",
                "CMS-DEVICE":     "default",
                "Authorization":  "Basic " + d.Authorization,
                "mcloud-channel": "1000101",
                "mcloud-client":  "10701",
                //"mcloud-route": "001",
                "mcloud-sign": fmt.Sprintf("%s,%s,%s", ts, randStr, sign),
                //"mcloud-skey":"",
                "mcloud-version":      "6.6.0",
                "Origin":              "https://yun.139.com",
                "Referer":             "https://yun.139.com/w/",
                "x-DeviceInfo":        "||9|6.6.0|chrome|95.0.4638.69|uwIy75obnsRPIwlJSd7D9GhUvFwG96ce||macos 10.15.2||zh-CN|||",
                "x-huawei-channelSrc": "10000034",
                "x-inner-ntwk":        "2",
                "x-m4c-caller":        "PC",
                "x-m4c-src":           "10002",
                "x-SvcType":           svcType,
        })

        var e BaseResp
        req.SetResult(&e)
        res, err := req.Execute(method, url)
        log.Debugln(res.String())
        if !e.Success {
                return nil, errors.New(e.Message)
        }
        if resp != nil {
                err = utils.Json.Unmarshal(res.Body(), resp)
                if err != nil {
                        return nil, err
                }
        }
        return res.Body(), nil
}
func (d *Yun139) post(pathname string, data interface{}, resp interface{}) ([]byte, error) {
        return d.request(pathname, http.MethodPost, func(req *resty.Request) {
                req.SetBody(data)
        }, resp)
}

func (d *Yun139) getFiles(catalogID string) ([]model.Obj, error) {
        start := 0
        limit := 100
        files := make([]model.Obj, 0)
        for {
                data := base.Json{
                        "catalogID":       catalogID,
                        "sortDirection":   1,
                        "startNumber":     start + 1,
                        "endNumber":       start + limit,
                        "filterType":      0,
                        "catalogSortType": 0,
                        "contentSortType": 0,
                        "commonAccountInfo": base.Json{
                                "account":     d.Account,
                                "accountType": 1,
                        },
                }
                var resp GetDiskResp
                _, err := d.post("/orchestration/personalCloud/catalog/v1.0/getDisk", data, &resp)
                if err != nil {
                        return nil, err
                }
                for _, catalog := range resp.Data.GetDiskResult.CatalogList {
                        f := model.Object{
                                ID:       catalog.CatalogID,
                                Name:     catalog.CatalogName,
                                Size:     0,
                                Modified: getTime(catalog.UpdateTime),
                                IsFolder: true,
                        }
                        files = append(files, &f)
                }
                for _, content := range resp.Data.GetDiskResult.ContentList {
                        f := model.ObjThumb{
                                Object: model.Object{
                                        ID:       content.ContentID,
                                        Name:     content.ContentName,
                                        Size:     content.ContentSize,
                                        Modified: getTime(content.UpdateTime),
                                },
                                Thumbnail: model.Thumbnail{Thumbnail: content.ThumbnailURL},
                                //Thumbnail: content.BigthumbnailURL,
                        }
                        files = append(files, &f)
                }
                if start+limit >= resp.Data.GetDiskResult.NodeCount {
                        break
                }
                start += limit
        }
        return files, nil
}

func (d *Yun139) newJson(data map[string]interface{}) base.Json {
        common := map[string]interface{}{
                "catalogType": 3,
                "cloudID":     d.CloudID,
                "cloudType":   1,
                "commonAccountInfo": base.Json{
                        "account":     d.Account,
                        "accountType": 1,
                },
        }
        return utils.MergeMap(data, common)
}

func (d *Yun139) familyGetFiles(catalogID string) ([]model.Obj, error) {
        pageNum := 1
        files := make([]model.Obj, 0)
        for {
                data := d.newJson(base.Json{
                        "catalogID":       catalogID,
                        "contentSortType": 0,
                        "pageInfo": base.Json{
                                "pageNum":  pageNum,
                                "pageSize": 100,
                        },
                        "sortDirection": 1,
                })
                var resp QueryContentListResp
                _, err := d.post("/orchestration/familyCloud/content/v1.0/queryContentList", data, &resp)
                if err != nil {
                        return nil, err
                }
                for _, catalog := range resp.Data.CloudCatalogList {
                        f := model.Object{
                                ID:       catalog.CatalogID,
                                Name:     catalog.CatalogName,
                                Size:     0,
                                IsFolder: true,
                                Modified: getTime(catalog.LastUpdateTime),
                        }
                        files = append(files, &f)
                }
                for _, content := range resp.Data.CloudContentList {
                        f := model.ObjThumb{
                                Object: model.Object{
                                        ID:       content.ContentID,
                                        Name:     content.ContentName,
                                        Size:     content.ContentSize,
                                        Modified: getTime(content.LastUpdateTime),
                                },
                                Thumbnail: model.Thumbnail{Thumbnail: content.ThumbnailURL},
                                //Thumbnail: content.BigthumbnailURL,
                        }
                        files = append(files, &f)
                }
                if 100*pageNum > resp.Data.TotalCount {
                        break
                }
                pageNum++
        }
        return files, nil
}

func (d *Yun139) getLink(contentId string) (string, error) {
        data := base.Json{
                "appName":   "",
                "contentID": contentId,
                "commonAccountInfo": base.Json{
                        "account":     d.Account,
                        "accountType": 1,
                },
        }
        res, err := d.post("/orchestration/personalCloud/uploadAndDownload/v1.0/downloadRequest",
                data, nil)
        if err != nil {
                return "", err
        }
        return jsoniter.Get(res, "data", "downloadURL").ToString(), nil
}

func unicode(str string) string {
        textQuoted := strconv.QuoteToASCII(str)
        textUnquoted := textQuoted[1 : len(textQuoted)-1]
        return textUnquoted
}
这是大佬们的 go实现的,有哪个好心大佬给转成ptyhon.拜谢!
 楼主| asd124689 发表于 2023-8-6 21:13
randStr = '2BRz5f3tVK2ezr4D'
ts = '2023-08-06 19:41:17'

body = {
    "catalogID": "00019700101000000001",
    "sortDirection": 1,
    "startNumber": 1,
    "endNumber": 100,
    "filterType": 0,
    "catalogSortType": 0,
    "contentSortType": 0,
    "commonAccountInfo": {
        "account": "13355009078",
        "accountType": 1
    }
}

body = json.dumps(body)
sign = calSign(body, ts, randStr)  得到结果应该是 BE8B1D532B940760EE2DCD5F3AFD2029
孤灯独饮 发表于 2023-8-6 22:47
要不是别人拦着,我非给你口算出来
CYZ0704 发表于 2023-8-7 01:58
孤灯独饮 发表于 2023-8-6 22:47
要不是别人拦着,我非给你口算出来

哈哈哈,我没拦着啊!
CYZ0704 发表于 2023-8-7 01:59
大佬666,刚好在查这一块的内容,就看到你发了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-1-11 00:24

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表