x-ca-key,x-ca-nonce,x-ca-signature与x-ca-signature-headers探索

2024-05-24 11:18:22 浏览数 (2)

x-ca-key,x-ca-nonce,x-ca-signature与x-ca-signature-headers探索

请求的curl如下

代码语言:javascript复制
curl 'https://bizapi.csdn.net/blog-console-api/v3/editor/getArticle?id=xxxxxxxxx&model_type=' 
  -H 'accept: */*' 
  -H 'accept-language: zh-CN,zh;q=0.9,en;q=0.8' 
  -H 'cookie: ' 
  -H 'origin: https://editor.csdn.net' 
  -H 'referer: https://editor.csdn.net/' 
  -H 'sec-ch-ua: "Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"' 
  -H 'sec-ch-ua-mobile: ?0' 
  -H 'sec-ch-ua-platform: "Windows"' 
  -H 'sec-fetch-dest: empty' 
  -H 'sec-fetch-mode: cors' 
  -H 'sec-fetch-site: same-site' 
  -H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36' 
  -H 'x-ca-key: 203803574' 
  -H 'x-ca-nonce: d73db41b-e7bd-493b-8fe3-3a6995a422b3' 
  -H 'x-ca-signature: rfYFgB84YDneWj2onHHmtJWeKUTsKC3EKsIurbvvR7E=' 
  -H 'x-ca-signature-headers: x-ca-key,x-ca-nonce'

核心js文件

app.chunk.de89d64e.js

代码语言:javascript复制
 _ = function(t) {
        var e = t.meth
          , n = t.url
          , r = t.appSecret
          , a = t.accept
          , o = t.date
          , l = t.contentType
          , d = t.params
          , m = t.headers
          , g = "";
        d || -1 === n.indexOf("?") ? d || (d = {}) : (d = v(n),
        n = n.split("?")[0]);
        g  = e   "n",
        g  = a   "n",
        g  = "n",
        g  = l   "n",
        g  = o   "n";
        var _ = h(m)// {x-ca-key: '203803574', x-ca-nonce: '924136a4-5eca-42ba-a675-34036764b896'}
          , b = c()(s()(_)).sort() //['x-ca-key', 'x-ca-nonce']
          , w = !0// treu
          , y = !1// false
          , x = void 0; //false
        try {
            // x-ca-key:203803574nx-ca-nonce:924136a4-5eca-42ba-a675-34036764b896n
            for (var k, C = i()(b); !(w = (k = C.next()).done); w = !0) {
                var L = k.value;
                g  = L   ":"   _[L]   "n"
            }
        } catch (t) {
            y = !0,
            x = t
        } finally {
            try {
                !w && C.return && C.return()
            } finally {
                if (y)
                    throw x
            }
        }
        var S = /^(?=^.{3,255}$)(http(s)?://)?(www.)?[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(.csdn.net)/
        //n 'https://bizapi.csdn.net/blog-console-api/v3/mdeditor/saveArticle'
        // T '/blog-console-api/v3/mdeditor/saveArticle'
          , T = n.replace(S, "");
        return g  = f(T, d),
            // g 'POSTn*/*nnapplication/jsonnnx-ca-key:203803574nx-ca-nonce:939abdaa-0bdd-4eba-a720-e8fc0b151621n/blog-console-api/v3/mdeditor/saveArticle'
        u()(g, r).toString(p.a)
    }

入参t

代码语言:javascript复制
{
    "meth": "POST",
    "url": "https://bizapi.csdn.net/blog-console-api/v3/mdeditor/saveArticle",
    "accept": "*/*",
    "date": "",
    "contentType": "application/json",
    "headers": {
        "Content-Type": "application/json",
        "Accept": "*/*",
        "X-Ca-Key": "203803574",
        "X-Ca-Nonce": "eff837eb-901e-403f-9ed3-d17d0227b16b"
    },
    "appSecret": "9znpamsyl2c7cdrr9sas0le9vbc3r6ba"
}

说明:

  1. X-Ca-Key为固定值
  2. X-Ca-Nonce是随机串,只要随机串相同,同一个请求(get请求参数也要相同)算出来的x-ca-signature就是一样的
  3. appSecret固定值,可以认为是加密秘钥
  4. g最终要加密的字符串,x-ca-signature就是g用appSecret加密的结果.
代码语言:javascript复制
'POSTn*/*nnapplication/jsonnnx-ca-key:203803574nx-ca-nonce:eff837eb-901e-403f-9ed3-d17d0227b16bn/blog-console-api/v3/mdeditor/saveArticle'

Java代码实现

自定义实体

代码语言:javascript复制
@Data
@Accessors(chain = true)
public class HmacSHA256Dto {
    public String method;
    public String accept;
    public String contentType="";
    public String date = "";
    public String url;
    public String appSecret = "9znpamsyl2c7cdrr9sas0le9vbc3r6ba";
    public Map<String,Object> params;
    public String xCaKey = "203803574";
    public String xCaNonce;
}

获取要加密的字符串

get请求需要对参数排序,排序规则可能不对,欢迎指导,微信:lxwjy88,或评论区留言

代码语言:javascript复制
@SneakyThrows
    public static String getMessage(HmacSHA256Dto hmacSHA256Dto) {
        URL url = new URL(hmacSHA256Dto.url);
        String path = url.getPath();
        StringBuffer sb = new StringBuffer();
        sb.append(hmacSHA256Dto.method   "n")
                .append(hmacSHA256Dto.accept   "nn")
                .append(hmacSHA256Dto.contentType   "n")
                .append(hmacSHA256Dto.date   "n")
                .append("x-ca-key:"   hmacSHA256Dto.xCaKey   "n")
                .append("x-ca-nonce:").append(hmacSHA256Dto.xCaNonce   "n")
                .append(path);
        Map<String, Object> params = hmacSHA256Dto.params;
        if (params != null) {
            // 需要对参数排序,可能是默认排序也可能是其他排序,暂时没有用多参数测试过,临时用key排序,不知道对不对?欢迎留言指导,也可加微信:lxwjy88一起探讨
            List<String> keys = new ArrayList<>(params.keySet());
            Collections.sort(keys);
            for (int i = 0; i < keys.size(); i  ) {
                String value = keys.get(i);
                if (StringUtils.hasText(value)) {
                    if (i == 0) {
                        sb.append("?").append(value).append("=").append(params.get(value));
                    } else {
                        sb.append("&").append(value).append("=").append(params.get(value));
                    }
                }
            }
        }
        return sb.toString();
    }

加密

代码语言:javascript复制
@SneakyThrows
public static String hmacSHA256(String secret, String message) {
    Mac hmacSha256 = Mac.getInstance("HmacSHA256");
    SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
    hmacSha256.init(secret_key);
    byte[] bytes = hmacSha256.doFinal(message.getBytes());
    String s = Base64.getEncoder().encodeToString(bytes);
    System.out.println(s);
    return s;
}

测试

代码语言:javascript复制
 public static void main(String[] args) {
        String appSecret = "9znpamsyl2c7cdrr9sas0le9vbc3r6ba";
        HmacSHA256Dto hmacSHA256Dto = new HmacSHA256Dto();
        hmacSHA256Dto.setMethod("POST").setAccept("*/*").setContentType("application/json").setXCaNonce("939abdaa-0bdd-4eba-a720-e8fc0b151621").setUrl("https://bizapi.csdn.net/blog-console-api/v3/mdeditor/saveArticlen");
        String message = getMessage(hmacSHA256Dto);
        hmacSHA256(appSecret, message);
    }
小技巧

至于x-ca-signature生成的对不对,可以用页面产生的X-Ca-Nonce作为随机串,看看自己计算出来的和页面生成的x-ca-signature一不一致,如果一致可以认为生成x-ca-signature的逻辑是对的

总结

  1. x-ca-key与x-ca-signature-headers可以认为是固定值
  2. x-ca-nonce随机串,应该只要满足位数和格式即可
  3. x-ca-signature加密串
  4. 核心是计算需要加密的字符串,然后对字符串加密,加密算法是hmacSHA256

0 人点赞