XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/bilibili-API-collect

给Wbi签名算法的Demo添加C#实现 (#719)

Co-authored-by: 社会易姐QwQ <45892418+SocialSisterYi@users.noreply.github.com>

63deb66
kurisu_u <73207840+lanyeeee@users.noreply.github.com>
提交于

代码差异

1 个文件 +86 -46
Modified docs/misc/sign/wbi.md +86 -46
@@ -115,7 +115,7 @@
115 115
116 116 ## Wbi签名算法实现Demo
117 117
118 该 Demo 提供 [Python](#Python)、[JavaScript](#JavaScript)、[Golang](#Golang) 语言
118 该 Demo 提供 [Python](#Python)、[JavaScript](#JavaScript)、[Golang](#Golang)、[C#](#CSharp) 语言
119 119
120 120 ### Python
121 121
@@ -422,60 +422,100 @@ func main() {
422 422 fmt.Println(string(body))
423 423 }
424 424 ```
425 ### Java
426 425
427 需要 `hutool` 依赖
426 ### CSharp
428 427
429 ```java
430 package com.example.demo;
428 无需依赖外部库
431 429
432 import cn.hutool.crypto.SecureUtil;
430 ```cs
431 using System.Security.Cryptography;
432 using System.Text;
433 using System.Text.Json.Nodes;
433 434
434 import java.util.*;
435 class Program
436 {
437 private static HttpClient _httpClient = new();
435 438
436 public class WbiTest {
437 private static final int[] mixinKeyEncTab = new int[]{
438 46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
439 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40,
440 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11,
441 36, 20, 34, 44, 52
439 private static readonly int[] MixinKeyEncTab =
440 {
441 46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49, 33, 9, 42, 19, 29, 28, 14, 39,
442 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63,
443 57, 62, 11, 36, 20, 34, 44, 52
442 444 };
443 445
444 public static String getMixinKey(String imgKey, String subKey) {
445 String s = imgKey + subKey;
446 StringBuilder key = new StringBuilder();
447 for (int i = 0; i < 32; i++) {
448 key.append(s.charAt(mixinKeyEncTab[i]));
449 }
450 return key.toString();
446 //对 imgKey 和 subKey 进行字符顺序打乱编码
447 private static string GetMixinKey(string orig)
448 {
449 return MixinKeyEncTab.Aggregate("", (s, i) => s + orig[i])[..32];
450 }
451
452 private static Dictionary<string, string> EncWbi(Dictionary<string, string> parameters, string imgKey,
453 string subKey)
454 {
455 string mixinKey = GetMixinKey(imgKey + subKey);
456 string currTime = DateTimeOffset.Now.ToUnixTimeSeconds().ToString();
457 //添加 wts 字段
458 parameters["wts"] = currTime;
459 // 按照 key 重排参数
460 parameters = parameters.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
461 //过滤 value 中的 "!'()*" 字符
462 parameters = parameters.ToDictionary(
463 kvp => kvp.Key,
464 kvp => new string(kvp.Value.Where(chr => !"!'()*".Contains(chr)).ToArray())
465 );
466 // 序列化参数
467 string query = new FormUrlEncodedContent(parameters).ReadAsStringAsync().Result;
468 //计算 w_rid
469 using MD5 md5 = MD5.Create();
470 byte[] hashBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(query + mixinKey));
471 string wbiSign = BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
472 parameters["w_rid"] = wbiSign;
473
474 return parameters;
475 }
476
477 // 获取最新的 img_key 和 sub_key
478 private static async Task<(string, string)> GetWbiKeys()
479 {
480 HttpResponseMessage responseMessage = await _httpClient.SendAsync(new HttpRequestMessage
481 {
482 Method = HttpMethod.Get,
483 RequestUri = new Uri("https://api.bilibili.com/x/web-interface/nav"),
484 });
485
486 JsonNode response = JsonNode.Parse(await responseMessage.Content.ReadAsStringAsync())!;
487
488 string imgUrl = (string)response["data"]!["wbi_img"]!["img_url"]!;
489 imgUrl = imgUrl.Split("/")[^1].Split(".")[0];
490
491 string subUrl = (string)response["data"]!["wbi_img"]!["sub_url"]!;
492 subUrl = subUrl.Split("/")[^1].Split(".")[0];
493 return (imgUrl, subUrl);
451 494 }
452 495
453 public static void main(String[] args) {
454 String imgKey = "653657f524a547ac981ded72ea172057";
455 String subKey = "6e4909c702f846728e64f6007736a338";
456 String mixinKey = getMixinKey(imgKey, subKey);
457 System.out.println(mixinKey);
458 //72136226c6a73669787ee4fd02a74c27
459 //{
460 // foo: '114',
461 // bar: '514',
462 // zab: 1919810
463 //}
464 LinkedHashMap<String, Object> map = new LinkedHashMap<>();
465 map.put("foo", "114");
466 map.put("bar", "514");
467 map.put("zab", 1919810);
468 map.put("wts", System.currentTimeMillis() / 1000);
469 StringJoiner param = new StringJoiner("&");
470 //排序 + 拼接字符串
471 map.entrySet().stream()
472 .sorted(Map.Entry.comparingByKey())
473 .forEach(entry -> param.add(entry.getKey() + "=" + entry.getValue().toString()));
474 String s = param + mixinKey;
475 String wbiSign = SecureUtil.md5(s);
476 System.out.println(wbiSign);
477 String finalParam = param + "&w_rid=" + wbiSign;
478 System.out.println(finalParam);
496 public static async Task Main()
497 {
498 var (imgKey, subKey) = await GetWbiKeys();
499
500 Dictionary<string, string> signedParams = EncWbi(
501 parameters: new Dictionary<string, string>
502 {
503 { "foo", "114" },
504 { "bar", "514" },
505 { "baz", "1919810" }
506 },
507 imgKey: imgKey,
508 subKey: subKey
509 );
510
511 string query = await new FormUrlEncodedContent(signedParams).ReadAsStringAsync();
512
513 Console.WriteLine(query);
479 514 }
480 515 }
516 ```
517 输出内容为进行 Wbi 签名的后参数的 url query 形式
518
519 ```
520 bar=514&baz=1919810&foo=114&wts=1687541921&w_rid=26e82b1b9b3a11dbb1807a9228a40d3b
481 521 ```