test_crypto.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. """
  2. 签名层单元测试
  3. ==============
  4. 验证 key_sort / hmac_sha1_hex / sign_params 与前端 JS 一致。
  5. 不需要联网,不需要 996 账号密码。
  6. """
  7. import sys
  8. import unittest
  9. from pathlib import Path
  10. # 让 tests 能 import 包
  11. sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
  12. from chuanshi_login.crypto import hmac_sha1_hex, key_sort, sign_params
  13. class TestKeySort(unittest.TestCase):
  14. def test_basic_alpha_sort(self):
  15. # 按字母序升序
  16. params = {"b": "2", "a": "1", "c": "3"}
  17. self.assertEqual(key_sort(params), "a=1&b=2&c=3")
  18. def test_matches_protocolInit(self):
  19. """复现前端 protocolInit 调 appParam 时的签名输入"""
  20. params = {
  21. "appid": 155342,
  22. "game_id": 214256,
  23. "vType": "csvKey",
  24. }
  25. result = key_sort(params)
  26. self.assertEqual(result, "appid=155342&game_id=214256&vType=csvKey")
  27. def test_login_payload(self):
  28. """复现前端 toLogin 调 v5w/login 时的参数顺序(不计算 sign)"""
  29. params = {
  30. "username": "abc",
  31. "password": "xxx",
  32. "game_id": 1,
  33. "vType": "csvKey",
  34. "appid": 1,
  35. "promote_id": 0,
  36. "_device_info": "...",
  37. }
  38. result = key_sort(params)
  39. # 验证包含每个字段
  40. for k in params:
  41. self.assertIn(f"{k}=", result)
  42. def test_empty_value(self):
  43. # None 视为空字符串
  44. self.assertEqual(key_sort({"a": None, "b": "x"}), "a=&b=x")
  45. class TestHmacSha1(unittest.TestCase):
  46. KEY = "k1ebbkxlojjdbnffnp3w2ykk3p625xnn"
  47. def test_known_vector(self):
  48. # 与 verify_poc.py 跑出来的结果对照
  49. msg = "appid=155342&game_id=214256&vType=csvKey"
  50. sig = hmac_sha1_hex(msg, self.KEY)
  51. self.assertEqual(sig, "1470dbc89058c62ac4c39bd30c5097b140017528")
  52. def test_stable(self):
  53. # 同一输入两次结果一致
  54. msg = "a=1&b=2"
  55. self.assertEqual(hmac_sha1_hex(msg, self.KEY), hmac_sha1_hex(msg, self.KEY))
  56. class TestSignParams(unittest.TestCase):
  57. KEY = "k1ebbkxlojjdbnffnp3w2ykk3p625xnn"
  58. def test_adds_sign(self):
  59. params = {"appid": 155342, "game_id": 214256, "vType": "csvKey"}
  60. signed = sign_params(params, self.KEY)
  61. self.assertIn("sign", signed)
  62. # 不修改入参
  63. self.assertNotIn("sign", params)
  64. def test_sign_known_value(self):
  65. params = {"appid": 155342, "game_id": 214256, "vType": "csvKey"}
  66. signed = sign_params(params, self.KEY)
  67. # sign = URL-encoded hex of hmac_sha1_hex(sorted_str, key)
  68. # 与 verify_poc.py 一致
  69. self.assertEqual(signed["sign"], "1470dbc89058c62ac4c39bd30c5097b140017528")
  70. if __name__ == "__main__":
  71. unittest.main(verbosity=2)