Electron 中 license-keys 的完整集成方案

secure-electron-license-keys 是一個專門為 Electron 應用設計的 npm 包,用于實現離線許可證密鑰的創建、驗證和管理,幫助開發者保護應用程序,確保只有擁有合法許可證的用戶才能使用。以下是關于它的詳細介紹:

在 Electron 應用中集成 secure-electron-license-keys 包主要涉及密鑰對生成、許可證創建(服務端)和客戶端驗證三個核心步驟。以下是詳細的集成流程:

步驟 1:準備工作

  1. 安裝依賴
    在 Electron 項目中安裝包:

    npm install secure-electron-license-keys --save
    
  2. 項目結構建議
    建議按以下結構組織文件(區分服務端和客戶端代碼):

    your-electron-app/
    ├── server/                # 服務端(生成密鑰對和許可證)
    │   ├── private.pem        # 私鑰(保密,不隨客戶端打包)
    │   └── generate-license.js # 生成許可證的腳本
    ├── src/
    │   ├── public.pem         # 公鑰(客戶端使用,隨應用打包)
    │   ├── main.js            # Electron 主進程
    │   └── renderer/          # 渲染進程(許可證輸入界面)
    

步驟 2:生成 RSA 密鑰對(服務端/開發者操作)

密鑰對用于加密和解密許可證,私鑰僅保存在服務端,公鑰內置到客戶端。

創建 server/generate-keys.js 腳本:

const { generateKeyPair } = require("secure-electron-license-keys");
const path = require("path");// 生成密鑰對并保存到文件
generateKeyPair({privateKeyPath: path.join(__dirname, "private.pem"),  // 私鑰路徑(絕對路徑)publicKeyPath: path.join(__dirname, "../src/public.pem"),  // 公鑰路徑(客戶端使用)keySize: 2048  // 密鑰長度(推薦 2048 或 4096)
}).then(() => {console.log("密鑰對生成成功!");
}).catch(err => {console.error("生成失敗:", err);
});

運行腳本生成密鑰:

node server/generate-keys.js

生成后,將 public.pem 移動到客戶端代碼目錄(如 src/),private.pem 留在服務端并嚴格保密。

步驟 3:創建許可證(服務端/開發者操作)

當用戶購買后,服務端使用私鑰生成許可證,包含用戶信息、有效期等數據。

創建 server/generate-license.js 腳本:

const { createLicense } = require("secure-electron-license-keys");
const path = require("path");
const fs = require("fs");// 自定義許可證數據
const licenseData = {userId: "user123",         // 用戶唯一標識email: "user@example.com", // 用戶郵箱expires: "2025-12-31",     // 過期時間(格式:YYYY-MM-DD)appVersion: "1.0.0",       // 允許的應用版本features: ["export", "cloudSync"]  // 允許的功能
};// 生成許可證
createLicense({privateKeyPath: path.join(__dirname, "private.pem"),  // 私鑰路徑data: licenseData
}).then(licenseKey => {// 保存許可證(可發送給用戶或存儲到數據庫)fs.writeFileSync(path.join(__dirname, `license-${licenseData.userId}.key`),licenseKey);console.log("許可證生成成功:", licenseKey);
}).catch(err => {console.error("生成失敗:", err);
});

運行腳本生成許可證:

node server/generate-license.js

生成的許可證密鑰(如 license-user123.key)可通過郵件等方式發送給用戶。

步驟 4:客戶端集成(Electron 應用中)

客戶端需要實現:許可證輸入界面、驗證邏輯、本地保存和啟動時自動驗證。

4.1 主進程配置(main.js)

在主進程中初始化許可證管理器,并提供驗證接口給渲染進程:

const { app, BrowserWindow, ipcMain } = require("electron");
const { LicenseManager } = require("secure-electron-license-keys");
const path = require("path");// 初始化許可證管理器
const licenseManager = new LicenseManager({publicKeyPath: path.join(__dirname, "public.pem"),  // 公鑰路徑licensePath: path.join(app.getPath("userData"), "license.key")  // 本地保存路徑
});// 驗證許可證(供渲染進程調用)
ipcMain.handle("verify-license", async (event, licenseKey) => {try {const result = await licenseManager.verifyLicense(licenseKey);if (result.valid) {// 驗證成功,保存許可證到本地await licenseManager.saveLicense(licenseKey);}return result;} catch (err) {return { valid: false, error: err.message };}
});// 啟動時自動驗證本地許可證
ipcMain.handle("check-saved-license", async () => {try {const savedLicense = await licenseManager.loadLicense();if (!savedLicense) return { valid: false, error: "未找到許可證" };const result = await licenseManager.verifyLicense(savedLicense);return result;} catch (err) {return { valid: false, error: err.message };}
});// 創建窗口等常規邏輯...
function createWindow() {const mainWindow = new BrowserWindow({width: 800,height: 600,webPreferences: {preload: path.join(__dirname, "preload.js"),  // 預加載腳本contextIsolation: true}});mainWindow.loadFile("src/renderer/index.html");
}app.whenReady().then(createWindow);
4.2 預加載腳本(preload.js)

暴露 IPC 接口給渲染進程:

const { contextBridge, ipcRenderer } = require("electron");contextBridge.exposeInMainWorld("licenseAPI", {verifyLicense: (key) => ipcRenderer.invoke("verify-license", key),checkSavedLicense: () => ipcRenderer.invoke("check-saved-license")
});
4.3 渲染進程界面(許可證輸入與驗證)

創建一個簡單的 HTML 界面(src/renderer/index.html),讓用戶輸入許可證密鑰:

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>許可證驗證</title><style>.container { margin: 20px; }input { width: 300px; padding: 8px; margin: 10px 0; }button { padding: 8px 16px; cursor: pointer; }.status { margin-top: 10px; padding: 8px; }.valid { background: #d4edda; color: #155724; }.invalid { background: #f8d7da; color: #721c24; }</style>
</head>
<body><div class="container"><h2>請輸入許可證密鑰</h2><input type="text" id="licenseKey" placeholder="粘貼許可證密鑰"><button onclick="verify()">驗證</button><div id="status" class="status"></div></div><script>// 頁面加載時檢查本地是否有已保存的許可證window.addEventListener("DOMContentLoaded", async () => {const result = await window.licenseAPI.checkSavedLicense();updateStatus(result);});// 驗證用戶輸入的許可證async function verify() {const key = document.getElementById("licenseKey").value;if (!key) {alert("請輸入許可證密鑰");return;}const result = await window.licenseAPI.verifyLicense(key);updateStatus(result);}// 更新狀態顯示function updateStatus(result) {const statusEl = document.getElementById("status");if (result.valid) {statusEl.textContent = `許可證有效!用戶:${result.data.email},過期時間:${result.data.expires}`;statusEl.className = "status valid";// 驗證成功后可跳轉到主應用界面} else {statusEl.textContent = `驗證失敗:${result.error}`;statusEl.className = "status invalid";}}</script>
</body>
</html>

步驟 5:功能限制邏輯

根據許可證驗證結果限制應用功能(例如在主界面中):

// 主應用界面的腳本中
async function initApp() {const licenseResult = await window.licenseAPI.checkSavedLicense();if (!licenseResult.valid) {// 未通過驗證,跳轉到許可證輸入頁window.location.href = "license.html";return;}// 根據許可證數據啟用/禁用功能const features = licenseResult.data.features;if (!features.includes("export")) {document.getElementById("exportBtn").disabled = true;document.getElementById("exportBtn").title = "需要高級許可證";}
}

關鍵注意事項

  1. 私鑰安全private.pem 絕不能隨客戶端打包,僅限服務端使用,泄露會導致許可證可被偽造。
  2. 公鑰保護:公鑰會內置到客戶端,可通過代碼混淆工具(如 electron-obfuscator)防止被輕易提取。
  3. 離線局限性:該包僅支持離線驗證,若需遠程吊銷許可證,需額外添加聯網檢查(如定期向服務器驗證許可證狀態)。
  4. 版本兼容:確保 secure-electron-license-keys 版本與 Electron 版本兼容(建議使用最新穩定版)。

通過以上步驟,你的 Electron 應用將具備基本的許可證驗證功能,可有效控制用戶訪問權限。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/94921.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/94921.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/94921.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AI推理的“靈魂五問”:直面2025算力鴻溝與中國的破局之路

摘要&#xff1a;2025年&#xff0c;AI產業的重心已從訓練全面轉向推理&#xff0c;但一場嚴峻的“體驗”危機正悄然上演。中美AI推理性能的巨大鴻溝&#xff0c;正讓國內廠商面臨用戶流失的切膚之痛。本文以問答形式&#xff0c;直面當前中國AI產業在推理“最后一公里”上最尖…

2025 TexLive+VScode排版IEEE TGRS論文

2025 TexLiveVScode排版IEEE TGRS論文 本文主要內容&#xff1a; 軟件安裝 latex 排版 TRGS 論文期間遇到的問題 清晰圖片導出 Latex公式、圖、表、算法、參考文獻的使用和引用 1. 前言 首先使用Overleaf網頁版排版&#xff0c;但是后期排版圖片太大&#xff0c;大小有限制&…

Redis數據組織方式

前言 Redis之所以高效&#xff0c;源自其優秀的架構設計。作為KV鍵值對存儲數據庫&#xff0c;數據的存儲放在了內存中&#xff0c;KV鍵值對的組織方式更是其高效的原因之一。本文介紹其數據組織方式。 一、總體架構 在使用Redis時&#xff0c;服務端接收多個客戶端的命令進行…

java組件安全vulhub靶場

>1--XStream1.打開靶場cd vulhub-master/xstream/CVE-2021-29505 docker up -d2.下載反序列化工具https://github.com/frohoff/ysoserial可以使用clone命令進行下載&#xff0c;也可以直接下載jar文件3.使用以下命令來開啟腳本&#xff0c;將是反彈shell的語句進行base64編碼…

UCMT部分復現

復現結果&#xff1a;88.03272&#xff0c;誤差在接受范圍內 補充信息 作者未解決后續報錯問題&#xff0c;不建議復現

IntelliJ IDEA 新手全方位使用指南

摘要本文面向剛接觸軟件開發、使用 IntelliJ IDEA 的新手&#xff0c;詳細介紹了 IDEA 的背景、版本區別、核心功能、運行原理、界面操作、項目管理、運行配置、以及 Git 版本控制基礎。文章突出實用操作和理解流程&#xff0c;幫助新手快速熟悉IDEA環境&#xff0c;順利完成項…

Python如何將圖片轉換為PDF格式

引言 在日常工作和學習中&#xff0c;我們經常需要將多張圖片合并成一個PDF文件&#xff0c;以便于分享或打印。Python提供了多種庫來實現這一需求&#xff0c;本文將詳細介紹三種常用的方法&#xff1a;img2pdf庫、Pillow庫和PyMuPDF庫&#xff0c;并附上完整的代碼示例。 方法…

Python如何合并兩個Excel文件

引言 在日常數據處理中&#xff0c;合并Excel文件是常見需求。Python提供了多種庫&#xff08;如pandas、openpyxl&#xff09;來實現這一操作。本文將詳細介紹兩種主流方法&#xff0c;并附上完整代碼示例&#xff0c;幫助您高效完成Excel合并任務。 方法一&#xff1a;使用pa…

【SQL進階】用EXPLAIN看透SQL執行計劃:從“盲寫“到“精準優化“

用EXPLAIN洞察SQL執行計劃&#xff1a;從"盲目編寫"到"精準優化" 很多開發者在編寫SQL時僅憑直覺&#xff0c;直到查詢超時才發現問題。MySQL內置的EXPLAIN工具能提前揭示查詢執行邏輯&#xff0c;幫助預防性能隱患。本文將帶你掌握EXPLAIN的核心用法&…

電影藝術好,電影知識得學

關于電影應該談什么導演風格、演員技術、劇本結構、票房、政治因素等。一、紙上談電影電影制作期&#xff1a;研發、前制、拍攝、后制、發行。一般成員只在某個時期出現。制片和導演會從頭監督到尾。研發期&#xff1a; 劇本概念發想與成形的時期。創作自由度比較大&#xff0c…

FPGA學習筆記——簡易的DDS信號發生器

目錄 一、任務 二、分析 三、ROM IP核配置 四、Visio圖 五、代碼 &#xff08;1&#xff09;.v代碼 &#xff08;2&#xff09;仿真代碼 六、仿真 七、實驗現象 一、任務 用串口模塊&#xff0c;用上位機發送指令&#xff0c;FPGA接收&#xff0c;然后輸出對應的波形&…

在NVIDIA Orin上用TensorRT對YOLO12進行多路加速并行推理時內存泄漏 (中)

接上篇 在NVIDIA Orin上用TensorRT對YOLO12進行多路加速并行推理時內存泄漏&#xff08;上&#xff09; 通過上篇的分析&#xff0c;發現問題在采集數據到傳入GPU之前的階段。但隨著新一輪長時間測試發現&#xff0c;問題依然存在。 如上圖&#xff0c;在運行20多分鐘內存開始…

計數組合學7.17(Murnaghan–Nakayama 規則 )

7.17 Murnaghan–Nakayama 規則 我們已經成功地用基 mλm_\lambdamλ?、hλh_\lambdahλ? 和 eλe_\lambdaeλ? 表示了 Schur 函數 sλs_\lambdasλ?。本節我們將考慮冪和對稱函數 pλp_\lambdapλ?。一個斜分劃 λ/μ\lambda / \muλ/μ 是連通的&#xff0c;如果其分拆圖…

使用 jlink 構建輕巧的自定義JRE

從 JDK 9 開始&#xff0c;Oracle JDK 和 OpenJDK 不再默認包含獨立的 JRE 目錄&#xff0c;而是提供了 jlink 工具&#xff08;Java 鏈接器&#xff09;&#xff0c;允許你根據需求自定義生成最小化的 JRE&#xff08;包含必要的模塊&#xff09;。以下是使用 jlink 生成 JRE …

[IOMMU]面向芯片/SoC驗證工程的IOMMU全景速覽

面向芯片/SoC驗證工程的IOMMU全景速覽 摘要:面向芯片/SoC 驗證工程的 IOMMU 全景速覽:包含基礎概念、主流架構要點(ARM SMMU、Intel VT?d、RISC?V IOMMU),Linux 軟件棧關系,SoC 上的驗證方法(功能、錯誤、性能、系統化流程和覆蓋),以及一個可用的“通用 IOMM…

Jenkins全鏈路教程——Jenkins用戶權限矩陣配置

在企業級CI/CD場景中&#xff0c;“權限混亂”往往比“構建失敗”更致命——測試員誤刪生產流水線、實習生修改關鍵插件配置、多團隊共用賬號導致責任無法追溯……這些問題&#xff0c;99%都能用權限矩陣徹底解決&#xff01;今天&#xff0c;我們不僅會拆解權限矩陣的底層邏輯…

庫函數蜂鳴器的使用(STC8)

使用庫函數控制蜂鳴器&#xff08;STC8&#xff09; 在STC8系列單片機中&#xff0c;可以通過庫函數或直接操作寄存器來控制蜂鳴器。以下是基于STC8庫函數的常用方法&#xff1a; GPIO板蜂鳴器 #include "GPIO.h" #include "Delay.h"void GPIO_config()…

redis8.0.3部署于mac

macOS11因版本過低&#xff0c;安裝redis時&#xff0c;Homebrew和源碼編譯兩種方式都無法成功。將操作系統升級至macOS15再安裝。Redis&#xff08;Remote Dictionary Server&#xff09;是一個開源的內存數據庫&#xff0c;遵守 BSD 協議&#xff0c;它提供了一個高性能的鍵值…

【和春筍一起學C++】(三十三)名稱空間的其他特性

目錄 嵌套式名稱空間 拓展——未命名的名稱空間 嵌套式名稱空間 示例代碼1&#xff1a; namespace electronicEquipment {namespace computer{double price 4999.0;string modelNumber;string name;}namespace ElectronicWatch{double price 99.0;string modelNumber;stri…

異步電動機負載運行特性全解析

異步電動機負載運行特性詳解 ——從空載到負載的完整分析一、為什么需要再談“負載運行” 在上一篇《感應電動機空載特性深度剖析》中&#xff0c;我們已經看到&#xff1a;空載時&#xff0c;若定子加額定電壓&#xff0c;轉子轉速 $n \approx n_s$&#xff08;同步轉速&#…