Kaynağa Gözat

feat: 新增前端解密项目

cuiyalong 1 yıl önce
ebeveyn
işleme
b5fa017be9

+ 137 - 0
apps/decrypt-js/.gitignore

@@ -0,0 +1,137 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+.pnpm-debug.log*
+
+# Diagnostic reports (https://nodejs.org/api/report.html)
+report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+*.lcov
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+jspm_packages/
+
+# Snowpack dependency directory (https://snowpack.dev/)
+web_modules/
+
+# TypeScript cache
+*.tsbuildinfo
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional stylelint cache
+.stylelintcache
+
+# Microbundle cache
+.rpt2_cache/
+.rts2_cache_cjs/
+.rts2_cache_es/
+.rts2_cache_umd/
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variable files
+.env
+.env.development.local
+.env.test.local
+.env.production.local
+.env.local
+
+# parcel-bundler cache (https://parceljs.org/)
+.cache
+.parcel-cache
+
+# Next.js build output
+.next
+out
+
+# Nuxt.js build / generate output
+.nuxt
+dist
+
+# Gatsby files
+.cache/
+# Comment in the public line in if your project uses Gatsby and not Next.js
+# https://nextjs.org/blog/next-9-1#public-directory-support
+# public
+
+# vuepress build output
+.vuepress/dist
+
+# vuepress v2.x temp and cache directory
+.temp
+.cache
+
+# Docusaurus cache and generated files
+.docusaurus
+
+# Serverless directories
+.serverless/
+
+# FuseBox cache
+.fusebox/
+
+# DynamoDB Local files
+.dynamodb/
+
+# TernJS port file
+.tern-port
+
+# Stores VSCode versions used for testing VSCode extensions
+.vscode-test
+
+# yarn v2
+.yarn/cache
+.yarn/unplugged
+.yarn/build-state.yml
+.yarn/install-state.gz
+.pnp.*
+/test-results/
+/playwright-report/
+/blob-report/
+/playwright/.cache/
+
+
+.idea

+ 2 - 0
apps/decrypt-js/README.md

@@ -0,0 +1,2 @@
+# 前端解密页面
+

+ 17 - 0
apps/decrypt-js/index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title></title>
+</head>
+<body>
+  <script src='https://cdn-common.jianyu360.com/cdn/lib/jsencrypt/3.3.2/jsencrypt.min.js'></script>
+  <script type="module" src="/src/main.js"></script>
+  <script
+    src="https://jysentry.jydev.jianyu360.cn/js-sdk-loader/2f4bb88c2cc54b81855bb5e3c85f953f.min.js"
+    defer
+    crossorigin="anonymous"
+  ></script>
+</body>
+</html>

+ 15 - 0
apps/decrypt-js/package.json

@@ -0,0 +1,15 @@
+{
+  "name": "decrypt-js",
+  "private": true,
+  "version": "1.0.0",
+  "scripts": {
+    "dev": "vite build --watch",
+    "build": "vite build",
+    "preview": "vite preview"
+  },
+  "devDependencies": {
+    "@babel/core": "^7.12.16",
+    "@vitejs/plugin-legacy": "^4.0.4",
+    "rollup-obfuscator": "^4.1.1"
+  }
+}

+ 16 - 0
apps/decrypt-js/rsa/rsa_private_key.pem

@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOhM0pNOfGeiBr+t
+nunphCHReY3RiS4Fuc2nD3cbjKNdLezeViGmsZwHsb2SVUb6rpPHyX0+3xjXYn//
+n39/Q8uPjWRA332TtN8MDEkSR2HMbn8ufRRt2TnlfsFDFTgBywSP7cwd0CiEdvBX
+5w8Jifc9VbedwbeplBWyDeLLqjRjAgMBAAECgYB4es+EAuLWxNwHMb8Hxkr3VzNZ
+8GDbc7DIDmsg9TLdz4fwH+hAD7pyGDOBBJIh/AXrM2U3BhKjSaIWjLdmYtT/kzg8
+BxQDr9YoO7u2jvTcEE+/6p2YugYX/ngpinawFJqyM+N7Or8yRABaw6Aq8VuKtv6p
+980Y2BBVVYn+/KorYQJBAP+9lu8iolzKRzJrFt/rosdWkOpNg5ujcSCwbxhYnYC0
+UY85sPLsMvnLgegkpO8jocSAt586BmcsA+Q9o97qVCkCQQDoiSVegtOvG3U0mNlN
+rCVpPEL22s9Kkwps3ZCdTl3VtUtNiyfhE8rbw/qOGti3VxMCRhpKi9hTIgeq13UG
+67WrAkEA/WQ1c5XGd9f4eU1AKffInmf4SB8rgn+L7I7EVMQgstB3a0kHOXqs+3IX
+shL01PliJFhBF+QfSgSDipdEke9uGQJBAOcw46xxmhDw1bizdulYi+Fy/oj7xzi3
+tJfEObGMZpLBKtsvzThkOz4APS3n1yuBMO8Dz8PqAeu1W7YpfLqiwv0CQF68N244
+dFebDSoZLl1hbCExpbtC7SDBpYxlIVNVqwN7ymr+Z0rIcAMVv5Ldp/bJEWaXJs9C
+0sPCBpjDnyK9Z04=
+-----END PRIVATE KEY-----

+ 6 - 0
apps/decrypt-js/rsa/rsa_public_key.pem

@@ -0,0 +1,6 @@
+-----BEGIN PUBLIC KEY-----
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDoTNKTTnxnoga/rZ7p6YQh0XmN
+0YkuBbnNpw93G4yjXS3s3lYhprGcB7G9klVG+q6Tx8l9Pt8Y12J//59/f0PLj41k
+QN99k7TfDAxJEkdhzG5/Ln0Ubdk55X7BQxU4AcsEj+3MHdAohHbwV+cPCYn3PVW3
+ncG3qZQVsg3iy6o0YwIDAQAB
+-----END PUBLIC KEY-----

+ 8 - 0
apps/decrypt-js/src/decrypt-pre1.js

@@ -0,0 +1,8 @@
+;(function(){
+  window.__pkContent = `MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOhM0pNOfGeiBr+t
+    nunphCHReY3RiS4Fuc2nD3cbjKNdLezeViGmsZwHsb2SVUb6rpPHyX0+3xjXYn//
+    n39/Q8uPjWRA332TtN8MDEkSR2HMbn8ufRRt2TnlfsFDFTgBywSP7cwd0CiEdvBX
+    5w8Jifc9VbedwbeplBWyDeLLqjRjAgMBAAECgYB4es+EAuLWxNwHMb8Hxkr3VzNZ
+    8GDbc7DIDmsg9TLdz4fwH+hAD7pyGDOBBJIh/AXrM2U3BhKjSaIWjLdmYtT/kzg8
+    BxQDr9YoO7u2jvTcEE+/6p2YugYX/ngpinawFJqyM+N7Or8yRABaw6Aq8VuKtv6p`
+})()

+ 10 - 0
apps/decrypt-js/src/decrypt-pre2.js

@@ -0,0 +1,10 @@
+;(function(){
+  window.__pkContent += `980Y2BBVVYn+/KorYQJBAP+9lu8iolzKRzJrFt/rosdWkOpNg5ujcSCwbxhYnYC0
+    UY85sPLsMvnLgegkpO8jocSAt586BmcsA+Q9o97qVCkCQQDoiSVegtOvG3U0mNlN
+    rCVpPEL22s9Kkwps3ZCdTl3VtUtNiyfhE8rbw/qOGti3VxMCRhpKi9hTIgeq13UG
+    67WrAkEA/WQ1c5XGd9f4eU1AKffInmf4SB8rgn+L7I7EVMQgstB3a0kHOXqs+3IX
+    shL01PliJFhBF+QfSgSDipdEke9uGQJBAOcw46xxmhDw1bizdulYi+Fy/oj7xzi3
+    tJfEObGMZpLBKtsvzThkOz4APS3n1yuBMO8Dz8PqAeu1W7YpfLqiwv0CQF68N244
+    dFebDSoZLl1hbCExpbtC7SDBpYxlIVNVqwN7ymr+Z0rIcAMVv5Ldp/bJEWaXJs9C
+    0sPCBpjDnyK9Z04=`
+})()

+ 95 - 0
apps/decrypt-js/src/main.js

@@ -0,0 +1,95 @@
+import './decrypt-pre1.js'
+import './decrypt-pre2.js'
+
+const config = {
+    plainKey: '', // rsa解密后的key
+    privateKey: `-----BEGIN PRIVATE KEY-----
+        ${window.__pkContent || ''}
+        -----END PRIVATE KEY-----`,
+    // privateKey: `-----BEGIN PRIVATE KEY-----
+    //     MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOhM0pNOfGeiBr+t
+    //     nunphCHReY3RiS4Fuc2nD3cbjKNdLezeViGmsZwHsb2SVUb6rpPHyX0+3xjXYn//
+    //     n39/Q8uPjWRA332TtN8MDEkSR2HMbn8ufRRt2TnlfsFDFTgBywSP7cwd0CiEdvBX
+    //     5w8Jifc9VbedwbeplBWyDeLLqjRjAgMBAAECgYB4es+EAuLWxNwHMb8Hxkr3VzNZ
+    //     8GDbc7DIDmsg9TLdz4fwH+hAD7pyGDOBBJIh/AXrM2U3BhKjSaIWjLdmYtT/kzg8
+    //     BxQDr9YoO7u2jvTcEE+/6p2YugYX/ngpinawFJqyM+N7Or8yRABaw6Aq8VuKtv6p
+    //     980Y2BBVVYn+/KorYQJBAP+9lu8iolzKRzJrFt/rosdWkOpNg5ujcSCwbxhYnYC0
+    //     UY85sPLsMvnLgegkpO8jocSAt586BmcsA+Q9o97qVCkCQQDoiSVegtOvG3U0mNlN
+    //     rCVpPEL22s9Kkwps3ZCdTl3VtUtNiyfhE8rbw/qOGti3VxMCRhpKi9hTIgeq13UG
+    //     67WrAkEA/WQ1c5XGd9f4eU1AKffInmf4SB8rgn+L7I7EVMQgstB3a0kHOXqs+3IX
+    //     shL01PliJFhBF+QfSgSDipdEke9uGQJBAOcw46xxmhDw1bizdulYi+Fy/oj7xzi3
+    //     tJfEObGMZpLBKtsvzThkOz4APS3n1yuBMO8Dz8PqAeu1W7YpfLqiwv0CQF68N244
+    //     dFebDSoZLl1hbCExpbtC7SDBpYxlIVNVqwN7ymr+Z0rIcAMVv5Ldp/bJEWaXJs9C
+    //     0sPCBpjDnyK9Z04=
+    //     -----END PRIVATE KEY-----`
+}
+
+const decryptTools = {
+    // rsa解密
+    rsaDecrypt: function (cipherText, privateKey) {
+        // 解密
+        var decrypt = new JSEncrypt()//创建解密对象实例
+        decrypt.setPrivateKey(privateKey)//设置秘钥
+        var uncrypted = decrypt.decrypt(cipherText)//解密之前拿公钥加密的内容
+        return uncrypted
+    },
+    // AES解密
+    async AESDecrypt(content, base64Key) {
+        const key = new TextEncoder().encode(base64Key)
+        const encryptedBase64 = content;
+        const encryptedData = Uint8Array.from(window.atob(encryptedBase64), c => c.charCodeAt(0));
+
+        const decryptData = async () => {
+            const iv = encryptedData.slice(0, 16);
+            const ciphertext = encryptedData.slice(16);
+
+            const aesKey = await crypto.subtle.importKey("raw", key, {name: "AES-CTR"}, false, ["encrypt", "decrypt"]);
+
+            const decryptedData = await crypto.subtle.decrypt({name: "AES-CTR", counter: iv, length: 128}, aesKey, ciphertext);
+            const decryptedText = new TextDecoder().decode(decryptedData);
+
+            return {
+                value: decryptedText
+            }
+        };
+
+        const result = await decryptData()
+        return result
+    }
+}
+
+const message = {
+    sendPostMessage: function(e, result) {
+        const win = e.source
+        var payload = {
+            ...result,
+            type: 'after-decrypt'
+        }
+        window.parent.postMessage(payload, payload.fromOrigin)
+    }
+}
+
+window.addEventListener('message', async (e) => {
+    if (e.data.type !== 'decrypt') {
+        return
+    }
+    if (window === e.source) {
+        return
+    }
+
+    var base64Key = e.data.base64Key
+    var cipherText = e.data.cipherText
+    // 1. 先解密base64Key
+    var plainKey = decryptTools.rsaDecrypt(base64Key, config.privateKey)
+    config.plainKey = plainKey
+    // 2. 再用key解密cipherText
+    var plainText = await decryptTools.AESDecrypt(cipherText, plainKey)
+
+    const result = {
+        ...e.data,
+        plainKey: plainKey,
+        plainText: plainText.value,
+    }
+    message.sendPostMessage(e, result)
+})
+

+ 70 - 0
apps/decrypt-js/vite.config.js

@@ -0,0 +1,70 @@
+import { resolve } from 'path'
+import { defineConfig } from 'vite'
+import legacyPlugin from '@vitejs/plugin-legacy'
+import { obfuscator } from 'rollup-obfuscator'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+  build: {
+    minify: true,
+    target: 'es2015',
+    assetsDir: './',
+    outDir: '../../dist/decrypt-js',
+    emptyOutDir: true,
+    rollupOptions: {
+      input: {
+        main: resolve(__dirname, 'index.html'),
+        // decrypt: resolve(__dirname, 'decrypt-js/decrypt-js.html'),
+      },
+      output: {
+        manualChunks: {
+          'decrypt-pre1': [
+            'src/decrypt-pre1.js'
+          ],
+          'decrypt-pre2': [
+            'src/decrypt-pre2.js'
+          ]
+        }
+      },
+      plugins: [
+        // 代码混淆
+        // https://juejin.cn/post/7216915438297677882
+        // https://juejin.cn/post/7292692843415109641 有更详细的配置
+        obfuscator({
+          compact: true,
+          controlFlowFlattening: true,
+          controlFlowFlatteningThreshold: 1,
+          deadCodeInjection: true,
+          deadCodeInjectionThreshold: 1,
+          debugProtection: true,
+          debugProtectionInterval: 0,
+          disableConsoleOutput: true,
+          identifierNamesGenerator: 'hexadecimal',
+          log: false,
+          renameGlobals: false,
+          rotateStringArray: true,
+          selfDefending: true,
+          shuffleStringArray: true,
+          splitStrings: true,
+          splitStringsChunkLength: 10,
+          stringArray: true,
+          stringArrayEncoding: ['rc4'],
+          stringArrayThreshold: 1,
+          transformObjectKeys: true,
+          unicodeEscapeSequence: false,
+        }),
+      ]
+    },
+  },
+  plugins: [
+    // https://juejin.cn/post/7358306245349605402
+    legacyPlugin({
+      // 如果不设置targets,默认值为'last 2 versions and not dead, > 0.3%, Firefox ESR'
+      // 需要兼容的目标列表,可以设置多个
+      targets: ['chrome 52'],  
+    }),
+  ]
+})
+
+
+

+ 2 - 0
package.json

@@ -15,6 +15,8 @@
     "preinstall": "npx only-allow pnpm",
     "dev:doc": "pnpm --filter docs run dev",
     "build:doc": "pnpm --filter docs run build",
+    "dev:decrypt": "pnpm --filter decrypt-js run dev",
+    "build:decrypt": "pnpm --filter decrypt-js run build",
     "dev:mobile": "pnpm --filter jy-mobile run dev",
     "build:mobile": "pnpm --filter jy-mobile run build",
     "dev:work": "pnpm --filter work-bench run serve",

Dosya farkı çok büyük olduğundan ihmal edildi
+ 91 - 762
pnpm-lock.yaml


Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor