cryptoHook

2025/5/12 16:35:05

  1. // ==UserScript==
  2. // @name cryptoHook
  3. // @namespace qchook
  4. // @match *://*/*
  5. // @grant none
  6. // @version 1.0
  7. // @author cthousand
  8. // @license MIT
  9. // @description 2025/5/12 16:35:05
  10. // ==/UserScript==
  11.  
  12. // Hook 加密方法
  13. !function () {
  14. // 保存原始的解密方法
  15. const originalEncrypt = window.crypto.subtle.encrypt;
  16. window.crypto.subtle.encrypt = async function (algorithm, key, data) {
  17. console.log("检测到加密调用");
  18. console.log("Algorithm:", algorithm);
  19.  
  20. // 根据算法名称区分加密类型
  21. console.log("加密算法:", algorithm.name);
  22.  
  23. // 如果是 AES 加密,打印更多详细信息
  24. if (algorithm.name.startsWith("AES")) {
  25. console.log("AES 加密详细信息:");
  26. debugger
  27. // 打印初始化向量(IV,16进制)
  28. if (algorithm.iv) {
  29. console.log("AES 初始化向量(IV,16进制):", arrayBufferToHex(algorithm.iv));
  30. }
  31.  
  32. // 打印加密的明文(UTF-8)
  33. console.log("AES 加密的明文(UTF-8):", new TextDecoder().decode(data));
  34.  
  35. // 调用原始的加密方法
  36. const encryptedData = await originalEncrypt.apply(this, arguments);
  37.  
  38. // 打印加密的密文(Base64)
  39. console.log("AES 加密的密文(Base64):", arrayBufferToBase64(encryptedData));
  40.  
  41. return encryptedData;
  42. }
  43.  
  44. // 调用原始的加密方法
  45. return originalEncrypt.apply(this, arguments);
  46. };
  47.  
  48. // 保存原始的解密方法
  49. const originalDecrypt = window.crypto.subtle.decrypt;
  50. // Hook 解密方法
  51. window.crypto.subtle.decrypt = async function (algorithm, key, data) {
  52. console.log("检测到解密调用");
  53. console.log("Algorithm:", algorithm);
  54.  
  55. // 根据算法名称区分解密类型
  56. console.log("解密算法:", algorithm.name);
  57.  
  58. // 如果是 AES 解密,打印更多详细信息
  59. if (algorithm.name.startsWith("AES")) {
  60. console.log("AES 解密详细信息:");
  61. // 打印初始化向量(IV,16进制)
  62. if (algorithm.iv) {
  63. console.log("AES 初始化向量(IV,16进制):", arrayBufferToHex(algorithm.iv));
  64. }
  65.  
  66. // 打印加密的密文(Base64)
  67. console.log("AES 加密的密文(Base64):", arrayBufferToBase64(data));
  68.  
  69. // 调用原始的解密方法
  70. try {
  71. const decryptedData = await originalDecrypt.apply(this, arguments);
  72.  
  73. // 打印解密的明文(UTF-8)
  74. console.log("AES 解密的明文(UTF-8):", new TextDecoder().decode(decryptedData));
  75.  
  76. return decryptedData;
  77. } catch (error) {
  78. console.error("解密失败:", error);
  79. throw error;
  80. }
  81. }
  82.  
  83. // 调用原始的解密方法
  84. return originalDecrypt.apply(this, arguments);
  85. };
  86.  
  87. // 保存原始的 generateKey 方法
  88. const originalGenerateKey = window.crypto.subtle.generateKey;
  89. // Hook generateKey 方法
  90. window.crypto.subtle.generateKey = async function (algorithm, extractable, keyUsages) {
  91. console.log("检测到生成密钥调用");
  92. console.log("Algorithm:", algorithm);
  93. console.log("Extractable:", extractable);
  94. console.log("Key Usages:", keyUsages);
  95.  
  96. // 调用原始的 generateKey 方法
  97. const key = await originalGenerateKey(algorithm, extractable, keyUsages);
  98.  
  99. // 如果生成的是密钥对(如 RSA 或 ECC),打印公钥和私钥信息
  100. if (algorithm.name.startsWith("RSA") || algorithm.name.startsWith("EC")) {
  101. console.log("生成的密钥对:");
  102. console.log("公钥:", key.publicKey);
  103. console.log("私钥:", key.privateKey);
  104.  
  105. // 导出公钥(如果需要)
  106. if (key.publicKey.extractable) {
  107. const exportedPublicKey = await crypto.subtle.exportKey("spki", key.publicKey);
  108. console.log("公钥(Base64):", arrayBufferToBase64(exportedPublicKey));
  109. } else {
  110. console.warn("公钥不可导出");
  111. }
  112. } else {
  113. console.log("生成的密钥:", key);
  114.  
  115. // 导出密钥(如果需要)
  116. if (key.extractable) {
  117. const exportedKey = await crypto.subtle.exportKey("raw", key);
  118. console.log("密钥(16进制):", arrayBufferToHex(exportedKey));
  119. } else {
  120. console.warn("密钥不可导出");
  121. }
  122. }
  123.  
  124. return key;
  125. };
  126.  
  127. // 辅助函数:将 ArrayBuffer 转换为 16 进制字符串
  128. function arrayBufferToHex(buffer) {
  129. const uint8Array = new Uint8Array(buffer);
  130. return uint8Array.reduce((hexString, byte) => {
  131. return hexString + byte.toString(16).padStart(2, '0');
  132. }, '');
  133. }
  134.  
  135. // 辅助函数:将 ArrayBuffer 转换为 Base64 字符串
  136. function arrayBufferToBase64(buffer) {
  137. const uint8Array = new Uint8Array(buffer);
  138. return btoa(String.fromCharCode.apply(null, uint8Array));
  139. }
  140. }()
  141.