軟件License授權原理

軟件License授權原理

你知道License是如何防止別人破解的嗎?本文將介紹License的生成原理,理解了License的授權原理你不但可以防止別人破解你的License,你甚至可以研究別人的License找到它們的漏洞。喜歡本文的朋友建議收藏+關注,方便以后復習查閱。

什么是License?

在我們向客戶銷售商業軟件的時候,常常需要對所發布的軟件實行一系列管控措施,諸如驗證使用者身份、軟件是否到期,以及保存版權信息和開發商詳情等。考慮到諸多應用場景可能處于離線環境,無法依賴網絡進行實時認證,所以還需要考慮單機認證時的防破解問題。總之,License許可證利用HTTPS網站的證書和簽名技術,一方面證明當前使用者是申請License的本人,另一方面要防止惡意破解,并偽造篡改License達到白嫖的目的。

為什么使用License授權?

License的作用是什么呢?收費軟件的License其目的肯定是防止用戶白嫖啦,所以License還應該具有以下一些功能:

  • 授權使用

明確用戶需要滿足的使用條件,如單用戶、多用戶、企業內部使用、全球使用等,并且通常會限定可安裝和激活的設備數量。

  • 限制功能

根據不同等級的License,軟件可以提供不同等級的功能,例如基礎版、專業版、企業版等,License可以解鎖相應版本的功能。

  • 期限控制

規定軟件的使用期限,可能是永久授權,也可能是訂閱式授權,到期后用戶需要續費才能繼續使用。

  • 版權保護

重申軟件的知識產權歸屬,禁止未經授權的復制、分發、反編譯、篡改或逆向工程等侵犯版權的行為。

  • 法律保障

License作為法律合同,確立了軟件提供商和用戶之間的法律關系,明確了雙方的權利和責任,如果發生違反協議的情況,軟件提供商有權采取法律手段追究責任。

  • 技術支持和升級服務

部分License中會規定用戶是否有權享有免費的技術支持、軟件更新和維護服務,以及這些服務的有效期限。

  • 合規性要求

對于特殊行業或特定地區,License可能還涉及到滿足特定法規、標準或認證的要求。

歸納起來,我們可以總結出License的作用是:

  • 控制軟件使用者的使用權限
  • 申明軟件所有者的版權
  • 規定軟件的使用規范

最后兩點主要是法律相關的,第一點才是本文的重點,即如何生成License,以及如何通過License對軟件用戶進行限制。

License分類

依據用途的不同,License可分為兩大類別:商用License非商用License

非商用License主要服務于諸如展覽展示活動、各類研發活動等多種非直接盈利性的應用場景;

商用License,則通常適用于那些開展商業運營活動的企業場所。

基于使用的期限,License可以劃分為固定期限License和永久License兩類。

固定期限License在激活后的指定時間內有效,過了預設的使用期限,用戶必須更新許可期限并通過重新激活才能繼續使用;

而永久License則是在激活后賦予用戶無時間限制的使用權,一旦激活,無需擔憂許可失效的問題,可以無限期地持續使用軟件。

如何實現License授權?

要想生成一個安全性高的License,必須讓其滿足以下幾個特征:

  • 保密性
  • 防篡改
  • 時效性
  • 可找回

保密性是指License里攜帶的data信息具有一定的隱蔽性,這樣可以防止想要破解License的人尋找到生成License的規律,進而偽造自己的License。

防篡改是指防止License里攜帶的重要信息被篡改,例如License有效時間如果被篡改,那么License就起不到限制用戶使用期限的作用了。

時效性是指License會記錄軟件可以使用的有效期,并在驗證License的時候判斷其是否過期。

可找回是指用戶申請的License一旦丟失或者要續期,基于第一次申請License時創建的源文件,再一次生成新的License,新的License會攜帶用戶當初申請時的信息。

由于License必須滿足以上特性,所以在介紹License實現原理之前,我們先來學習一下非對稱加密和簽名&驗簽。

非對稱加密

有非對稱加密必然就會有對稱加密,對稱加密就是我們一般意義上的加密算法,這種算法在加密和解密時都使用同一個密鑰,所以對稱加密算法的密鑰又叫做共享密鑰。對稱加密算法一般使用AES(Advanced Encryption Standard)加密算法。

非對稱加密有兩個密鑰,一個公鑰一個私鑰。公鑰是公開的,供多個人使用;私鑰是非公開的,僅一個人或者少數群體使用。當非對稱加密算法用作加解密時,公鑰用來對明文加密,私鑰用來給密文解密,這個順序不能顛倒。你可以這樣理解,密文是私密的東西,只有少數人才能解密,所以少數人手里的私鑰用來解密,多數人手里的公鑰不能解密只能加密。

為什么要區分公鑰和私鑰呢?直接使用一個共享密鑰不行嗎?可以,但是前提是你能夠安全的將共享密鑰傳遞給對方。共享密鑰如何在線上安全的同步給對方是一個問題,畢竟在網絡上傳輸信息很容易暴露。如果使用非對稱密鑰就可以將公鑰同步給消息發送者,而消息接收者則保留私鑰用來解密消息,這樣即使公鑰被中間人盜取,他也只能用來做加密操作而不能解密密文。

簽名&驗簽

雖然非對稱加密可以解決“密鑰分配問題”,但是它不能防止偽造消息的問題。既然公鑰可以公之于眾,大家都知道你的消息要怎么加密,假如A想給B發送消息,那么中間人X可不可以將A發送的消息攔截,并將自己的消息加密以后發送給B呢?當然可以!

這就好比你買了一張周杰倫的演唱會的門票,我看到了之后自己偽造了一個一模一樣的,如此一來我也可以去看周杰倫的演唱會。這時官方組織者發現了這個漏洞以后,規定周杰倫的演唱會門票需要帶上官方印章才能進場,此時我就算把門票畫的再惟妙惟肖,少了官方印章,我的這張假門票依然是張廢紙。

如何解決這個問題呢?答案就是給你的消息“蓋章”,即簽名,簽名就是認證你的身份。這里還是使用非對稱密鑰算法,只不過使用的順序和加密消息時恰好相反。簽名時是私鑰用來加密,公鑰用來解密。

你可以這樣理解,給消息簽名就好比給文件蓋章,你會隨隨便便把你自己的印章交給別人來使用嗎?當然不行!所以公鑰不適合用來簽名,私鑰用作簽名更加合理。需要注意的是簽名所使用的密鑰對由消息發送者生成并提供給消息接收者,這和給消息加密時正好相反,這樣說來消息加密和消息簽名這兩個使用場景就需要生成兩套密鑰對。

出于性能方面的考慮,大多數情況下給消息加密還是使用的對稱加密算法,為了解決“密鑰分配問題”,只會在第一次發送共享密鑰的時候才會使用非對稱加密,一旦消息接收者得到了共享密鑰,通信雙方就能夠通過共享密鑰進行通信了。

此外,使用非對稱密鑰對消息簽名也可以防止消息被人篡改,由于性能原因一般不會對消息原文進行簽名,而是先通過哈希算法形成消息摘要,再對消息摘要簽名。消息接收者驗簽時會將消息的明文進行哈希,再將消息簽名解密,兩者比對如果一致則證明消息沒有被篡改過。

License結構

前面鋪墊了一些生成License所必備的基礎知識,我們學習了生成的License如果需要防止被人破解,那就需要具有保密性、防篡改和防偽造等特點。接下來要考慮的是License需要攜帶什么信息就能讓其既安全又能限制用戶的使用權限。

License文件理論上來說至少需要以下一些信息:

  • 軟件所有者信息
  • 申請授權時間
  • 授權截止時間
  • 軟件使用者信息

下圖是License文件流的結構圖,主要字段有:

  • 魔數值
  • 分隔符
  • 申請時間
  • 到期時間
  • 公鑰的長度 & 公鑰
  • 攜帶信息的長度 & 攜帶信息

魔數值:和Java Class文件頭的魔數CAFEBABE類似,License文件頭的魔數也是起到了快速識別的作用,也有格式驗證的作用。

分隔符:用來區分各個字段,將字段之間用分隔符隔開便于結構化管理。

申請時間:用戶申請License的日期。

到期時間:License的有效截止日期。

公鑰的長度 & 公鑰:公鑰長度用來記錄公鑰是多少字節,依據公鑰長度就可以讀取相應長度的公鑰數據了。

攜帶信息的長度 & 攜帶信息:攜帶信息長度用來記錄攜帶信息是多少字節,依據攜帶信息長度就可以讀取相應長度的攜帶信息了。攜帶信息里通常會包含軟件所有者、軟件使用者、License唯一ID以及設備MAC地址等信息。

想好了License文件的結構,我們就可以開始生成License啦。

生成License

申請License的總體流程如下圖所示。客戶在軟件服務商處申請License,軟件服務商生成License之后會返回給客戶License文件,自己保留一份License源文件,源文件用作以后找回License。客戶拿到License文件,在安裝、啟動軟件之后激活License。

生成License主要做了這樣幾個事情:

  • 對需要攜帶的信息加密成密文
  • 對密文簽名
  • 保存申請日期、有效截止日期和公鑰
  • 生成源文件

私鑰1加密的作用是對License的安全加固。因為License實際上可以通過Base64解碼得到里面的數據,包括公鑰信息,這樣客戶就能夠通過公鑰將攜帶的信息解析出來,倘若攜帶有敏感信息就會造成安全問題。所以這里對攜帶的信息做了先加密后簽名的處理。

另外需要強調的是,申請日期和有效截止日期也需要簽名但不需要加密。因為如果不簽名的話,客戶可以將日期解析出來之后篡改成自己想要的任何日期。

加載License

客戶申請到License之后,就可以去軟件上面激活啦。激活License首先判斷License是否合法,檢查文件頭魔數和分隔符是否正確,檢查License是否過期等。然后就是提取License的授權信息進行驗簽比對。如果有必要,還可以檢查授權信息里攜帶的MAC地址是否與安裝設備的MAC地址匹配。如果一切正常就可以通過驗證。

找回License

防破解

首先需要明確的一點就是,沒有萬無一失的防破解方案,所謂魔高一尺道高一丈,漏洞堵的再嚴實依然能找到破解的方法,唯一的區別就是破解的成本高不高而已

例如,具備一定逆向工程經驗的程序員都知道,應用程序不僅能夠被調試,也能被修改。理論上講,只要深入探究程序的代碼,定位并替換其中嵌入的原始公鑰信息,改為自己的公鑰。隨后,使用個人持有的私鑰去創建一個新的授權文件,這樣一來,就實現了對軟件授權機制的破解。

更簡單的方法是直接反編譯驗證邏輯的代碼,當驗證的時候直接返回true,即可通過驗證。

即使不能做到百分之百的安全性,我們還是應該知道一些防破解的方法,增加用戶破解的難度。防破解主要有以下幾個方面的問題需要重點限制。

  • 如何解決java代碼反編譯之后,修改驗證License的邏輯?

答:混淆代碼,增加反編譯的難度。

  • 如何防止客戶修改服務器時間以避免License過期?

答:分為離線和在線兩種情況。

在線情況下加載License信息時,可以將License里保存的過期時間和線上標準時間做比較

離線情況下,需要滿足條件:申請時間 <= 系統時間 <= 截止時間

具體實現方案是,第一次加載License成功之后,將申請時間存到A處;

定時更新A處的時間,更新前比較當前系統時間,如果系統時間 < 申請時間,說明系統時間被篡改過。否則,更新A處時間為當前系統時間;

保存的時間是經過加密的,但是有個問題是如果用戶備份了一開始的時間,過了一段時間之后用這個備份文件恢復,再修改系統時間就可以永不過期,如何解決?

1. 可以將A處的時間信息保存到數據庫里,數據庫權限設置為只有開發人員可以修改,此外數據庫安裝的機器不能與軟件安裝的機器相同,否則用戶可以將二者統一安裝到某一個虛擬機里,快到期的時候再統一恢復到初始時間。

2. A處除了保存時間以外,還需要License的唯一id、使用License的機器mac地址,這些字段是為了保證License不被重復使用。

  • 如何防止客戶在多臺服務器上使用同一個License?

答:將服務器的ip或者mac地址與License做綁定關系。

  • 如何防止用戶得到了源文件并獲取了私鑰,就可以自己偽造License?

答:避免將生成License的代碼安裝在用戶的機器環境下,最好在自己的機器環境下生成License。因為生成License之后得到的源文件一般會保存在代碼路徑下,如果用戶反編譯生成License的代碼,就能夠得到源文件信息。

最后整理了一張泳道圖,可以從整體觀察一下不限制、防止篡改系統時間和防止多設備共享License等問題的解決方案。

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

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

相關文章

【Linux】進程狀態

進程狀態 進程狀態的簡要介紹運行狀態進程排隊 阻塞狀態掛起狀態Linux中的進程狀態 進程狀態的簡要介紹 進程狀態指的是一個操作系統中正在運行的進程當前所處的狀態。根據不同的操作系統&#xff0c;進程狀態可能會有一些細微的差別&#xff0c;但最主要的是以下三種狀態 運行…

Java——方法的使用

目錄 一.方法的概念及使用 1 什么是方法(method) 2.方法定義 3 方法調用的執行過程 4 實參和形參的關系(重要) 5.沒有返回值的方法 二.方法重載 1.為什么需要方法重載 2.方法重載概念 3.方法簽名 三.遞歸 1.遞歸的概念 2.遞歸執行過程分析 3. 遞歸練習 一.方法的…

貓頭虎分享已解決Bug || 容器編排問題:OrchestrationFailure, ContainerManagementError

博主貓頭虎的技術世界 &#x1f31f; 歡迎來到貓頭虎的博客 — 探索技術的無限可能&#xff01; 專欄鏈接&#xff1a; &#x1f517; 精選專欄&#xff1a; 《面試題大全》 — 面試準備的寶典&#xff01;《IDEA開發秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鴻蒙》 …

代碼隨想錄算法訓練營第四十二天|122. 買賣股票的最佳時機 II

674. 最長連續遞增序列 public static int findLengthOfLCIS(int[] nums) {int[] dp new int[nums.length];dp[0] 1;for (int i 1; i < nums.length; i) {dfs(nums, dp, i);}Arrays.sort(dp);return dp[dp.length - 1];}public static void dfs(int[] nums, int[] dp, i…

【Python】【VS Code】VS Code中python.json和setting.json文件配置說明

目錄 1. python.json配置 2. setting.json配置 3. 解決中文亂碼 4. 實現效果 1. python.json配置 python.json 獲取步驟&#xff1a;文件 -> 首選項 -> 配置用戶代碼片段 -> python 此為VS Code的頭文件設置&#xff0c;復制以下內容到 python.json {"HEADER…

個人做抖店如何能夠快速起店?掌握好技巧是關鍵!建議收藏!

大家好&#xff0c;我是電商小布。 相信我們每個朋友在店鋪開通后&#xff0c;最關心的事情就是小店成功起店了。 那么個人做抖店想要快速起店&#xff0c;該怎么來進行操作呢&#xff1f; 接下來&#xff0c;小布重點給大家說三點&#xff1a; 首先來說一下小店的主體類型…

git常用命令記錄

1、第一次初始化 git init git add . git commit -m ‘first commit’ git remote add origin gitgithub.com:帳號名/倉庫名.git git pull origin master git push origin master # -f 強推 git clone gitgithub.com:git帳號名/倉庫名.git 2、工作基本操作 git checkout master…

dell r740服務器黃燈閃爍維修現場解決

1&#xff1a;首先看一下這款DELL非常主力的PowerEdge R740服務器長啥樣&#xff0c;不得不說就外觀來說自從IBM拋棄System X系列服務器后&#xff0c;也就戴爾這個外觀看的比較順眼。 圖一&#xff1a;是DELL R740前視圖&#xff08;這款是8盤機型&#xff09; 圖二&#xff…

QT 數據庫的增加操作和畫圖 Win

第一步、先配置CMakeLists.txt 在CMakeLists.txt中添加 find_package(Qt6 REQUIRED COMPONENTS Sql) find_package(Qt6 REQUIRED COMPONENTS Charts)target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Sql) target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Charts)避…

springboot集成JWT實現token權限認證

vuespringboot登錄與注冊功能的實現 注&#xff1a;對于JWT的學習&#xff0c;首先要完成注冊和登錄的功能&#xff0c;本篇博客是基于上述博客的進階學習&#xff0c;代碼頁也是在原有的基礎上進行擴展 ①在pom.xml添加依賴 <!-- JWT --> <dependency><grou…

Linux篇:Shell命令以及運行原理 和 權限

一. Shell命令及原理 Linux操作系統狹義上是Linux內核&#xff0c;廣義上是指Linux內核Linux外殼(Shell)和對應的配套程序 Linux外殼&#xff1a;Linux 外殼是用戶與內核之間的接口&#xff0c;用戶通過外殼與操作系統進行交互和操作。在 Linux 系統中&#xff0c;用戶可以選…

C語言——static的三大用法

被稱為面試愛考愛問題的它到底有何奧義 它難度不大并且非常常用&#xff0c;話不多說&#xff0c;直接開始 一、局部靜態變量 定義 在函數內部使用static修飾的變量被稱為局部靜態變量&#xff0c;與普通的局部變量不同&#xff0c;局部靜態變量在使用后不會被銷毀&#xff…

pycharm 遠程運行報錯 Failed to prepare environment

什么也沒動的情況下&#xff0c;遠程連接后運行是沒問題的&#xff0c;突然在運行時就運行不了了&#xff0c;解決方案 清理緩存&#xff1a; 有時候 PyCharm 的內部緩存可能出現問題&#xff0c;可以嘗試清除緩存&#xff08;File > Invalidate Caches / Restart&#xff0…

mysql優化指南之原理篇

之前碰到一個線上問題&#xff0c;在接手一個同事的項目后&#xff0c;因為工期比較趕&#xff0c;我還沒來得及了解業務背景和大致實現&#xff0c;只是了解了上線發布的順序和驗證方式就進行了上線&#xff0c;在上線進行金絲雀的時候系統還沒發生什么異常&#xff0c;于是我…

【面試題】談談MySQL的事務

事務是啥 MySQL的事務就是把多個sql語句操作打包在一起執行&#xff0c;要么全部執行&#xff0c;要么一個都別執行。這種操作稱為“原子性”&#xff0c;是事務最核心的特征。當某個sql操作出錯時&#xff0c;就會進行“回滾/rollback”操作&#xff0c;即把執行過的操作逆向…

MySQL數據庫進階第二篇(索引,SQL性能分析,使用規則)

文章目錄 一、索引概述二、索引結構三、結構 - B-Tree四、結構 - BTree五、結構 - Hash六、索引分類七、索引語法1.案例代碼 八、SQL性能分析1.查看SQl執行頻率2.慢查詢日志3.PROFILES詳情4.EXPLAIN執行計劃 九、 索引使用規則十、SQL 提示十一、覆蓋索引十二、前綴索引十三、單…

滾動加載react-infinite-scroll-component

react-infinite-scroll-component 當請求數據量過大時&#xff0c;接口返回數據時間會很長&#xff0c;數據回顯時間長&#xff0c;Dom 的渲染會有很大的性能壓力。 antd的List組件中有提到一個滾動加載的組件庫react-infinite-scroll-component 實現滾動加載 Antd&#xff1…

考研高數(高階導數的計算)

1.歸納法 常見高階導數 2.泰勒展開式 3.萊布尼茲公式 4.用導數定義證明導函數在某一點連續的例題

【kubernetes】二進制部署k8s集群之cni網絡插件flannel和calico工作原理(中)

↑↑↑↑接上一篇繼續部署↑↑↑↑ 目錄 一、k8s集群的三種接口 二、k8s的三種網絡模式 1、pod內容器之間的通信 2、同一個node節點中pod之間通信 3、不同的node節點的pod之間通信 Overlay Network VXLAN 三、flannel網絡插件 1、flannel插件模式之UDP模式&#xff0…