AES 對 Java 應用程序許可是否安全?
我必須獲得一個 java 應用程序的許可,並且想編寫一個快速實現的程式碼,我想出的方案是:
- 應用程序計算一個字元串 X,我們假設它是電腦的 mac 地址、目前日期和一些其他資訊的 md5 和。
- 應用程序返回一個字元串 Y 等於 X 的最後 16 位數字給使用者
- 使用者聯繫軟體支持辦公室給出 Y 並且辦公室使用帶有密鑰的 AES 加密 Y 並返回一個字元串 Z 等於加密 Y 的最後 16 位數字
- 使用者在應用程序中輸入 Z 並檢查 Z 是否等於其自己的 Z,其計算方式與軟體支持處相同。如果兩者相同,則軟體解鎖。
現在我想知道兩個假設是否合理安全:
- 假設破解者知道 Y 是如何計算的,並且可以為自己的軟體副本計算它,並使用這個 Y 向支持中心請求 Z 並解鎖他的軟體副本。他是否有可能為每個可能的 Y 計算他想要一個匹配的 Z 來解鎖我的軟體的任何副本?
- 因為我的軟體在應用程序字節碼中包含加密密鑰,所以有足夠知識的破解者可以反編譯加密密鑰並創建自己的 Z 來解鎖程序(假設我已盡力混淆程式碼)。一個解決方案是使用公鑰加密,但是在我看來這沒有用,因為如果破解者能夠解碼應用程序的編譯字節碼,他將完全繞過我將放置的任何加密方案,因為最終總會有檢查條件並將該條件始終設置為 true 的程式碼的一部分將繞過我將提出的任何加密方案。是真的嗎?
首先,假設攻擊者無法從您的軟體中提取 AES 密鑰。這意味著他們能做的最好的事情就是對 AES 進行選擇明文攻擊:選擇一個塊 $ Y $ , 請求其加密 $ Z $ ,根據需要重複多次,並嘗試使用結果來找出對其他明文塊的加密有用的東西。
由於 AES 被認為是 IND-CPA 安全的,即在選擇的明文攻擊下與隨機排列無法區分,因此這不太可能起作用。如果攻擊者無法以某種方式將 AES 與隨機排列區分開來(如果 AES 像假設的那樣安全,他們不應該這樣做),他們所能做的就是嘗試編譯一長串明文/密文對,並希望在列表中找到他們想要破解的密鑰。但只要您不過多地截斷輸入*,*這也不太可能發生。(您沒有指定“數字”的含義,但只要一個數字包含至少 4 位,16 位至少等於 64 位,這應該足夠了。)
然而,這一切都假設攻擊者不能只從軟體中提取 AES 密鑰。如果可以,那麼創建自己的許可證密鑰生成器將是微不足道的。請注意,從攻擊者的角度來看,提取 AES 密鑰比僅僅修改軟體以禁用密鑰檢查更有用:知道 AES 密鑰允許他們為任何平台上的任何軟體副本創建有效的許可證密鑰*,*包括未來升級。
提取密鑰也可能比修改程式碼更容易,特別是如果您使用標準系統加密庫進行 AES 實現。(正如 CodesInChaos 所指出的,攻擊者可以在調試器下執行程式碼並記錄它所做的所有系統庫呼叫;呼叫
AESEncrypt()
或任何應該作為斷點的良好目標的呼叫。)使用您自己的混淆 AES 實現可以使它有點難,但這也不能保證能正常工作:加密程式碼在反編譯時往往看起來相當獨特,即使攻擊者沒有意識到他們正在查看 AES,他們仍然可以解除程式碼及其輸入批發的。因此,如果您不希望任何人能夠為您的軟體編寫密鑰生成器,我強烈建議您改用數字簽名。如果您不想這樣做,您的另一個選擇是混淆您的程式碼並接受這樣一個事實,即熟練且堅定的攻擊者將能夠對其進行逆向工程並編寫許可證密鑰生成器。或者,您知道,首先考慮您是否真的需要許可證密鑰。