2012-06-12 219 views
0

我有一個接口,實現類通過MEF在我的應用程序中導出。實現類在單獨的程序集中,並且在編譯時不知道(想想插件)。防止通過接口攔截呼叫

該接口基本上包含一個調用,該調用說'這裏是一串鍵值對,現在初始化您的許可狀態'。即

public LicensingInfo InitialiseLicense(IEnumerable<KeyValuePair<string, string>> keys)

我想知道的是 - 是否有保護該接口從「中間人」執行的方法嗎?即一個接收來自我的應用程序的調用,然後用不同的一組鍵 - 值對在插件程序集上調用相同的方法,基本上說'是 - 在這裏你去 - 有一切'。

我的確嘗試過用不同的方式,因爲應用程序會調用插件程序集並傳入一個可以查詢的對象。這種方法可能是這個樣子:

public LicensingInfo InitialiseLicense(ILicenseQueryProvider provider)

然而,再次用這種方法我認爲,攔截對象可能只是簡單地給不同的供應商庫。

那麼,有沒有一種方法可以防止這種接口攔截,或者我應該重構它,使插件程序集完全負責許可證載入等自己的代碼中?或者,還有另外一種方式,或許我可以重構它,但我沒有考慮過它?

+2

如果攻擊者可以在機器上放置代碼,他已經擊敗了你。 – SLaks

+0

有信任關係嗎?例如,插件開發人員相信您會向他傳遞一組代表用戶的密鑰,並確定用戶有權訪問哪些內容?或者你正在開發雙方,但你想確保你的用戶沒有設法攔截你的電話,並允許他自己訪問所有的數據? –

+0

@ChrisShain - 這將是後者。這是我們公司正在製作的一個應用程序,它將附帶我們也在開發的插件。我們只是不想讓竊取變得容易。我的意思是,這可能不是最簡單的事情,但我寧願儘可能地接近「實現真正的痛苦」。 –

回答

2

我相信你可以讓它更難以破解,但不能通過界面。

這裏就是你要做的:

您需要2個+ N項目:一個爲EXE(姑且稱之爲PROGRAM.EXE),一個用於合同(contracts.dll),以及一個爲每個n個插件(plugin.dll)。

program.exe對contracts.dll有一個硬引用,就像plugin.dll一樣。

使用強名稱密鑰對其全部簽名。請參閱http://msdn.microsoft.com/en-us/library/xc31ft41.aspx

而不是接口ILicenceQueryProvider,在contracts.dll中創建一個密封的類LicenceQueryProvider。確保它沒有公共構造函數,只有內部構造函數,並且沒有修改對象的方法(在構造,不可變和只讀字段上初始化)。

標記與一個InternalsVisibleToAttribute的contracts contracts.dll,授予program.exe訪問內部構造函數。請參閱http://msdn.microsoft.com/en-us/library/System.Runtime.CompilerServices.InternalsVisibleToAttribute.aspx

這樣,program.exe就可以調用此對象上的構造函數,並且plugin.dll可以從中讀取它。

plugin.dll「知道」對象類沒有被修改,因爲強名稱簽名。而且由於它是封閉的,中間的一個人在另一個實現中不能替代。

現在記得我說過你可以讓它更難以破解,但這不是不可能的,永遠不會,特別是如果你使用託管代碼。

例如,中間的人可以使用反射來實例化具有內部構造函數的對象。

更糟糕的是,在您的插件中存在從此對象讀取的代碼,並根據許可證信息作出決定。黑客可以將您的plugin.dll反編譯爲IL,並將代碼替換爲始終授予所有權限的代碼。

混淆只會有一點幫助,但不會對反射攻擊有幫助。本機代碼會使它更難一些,但本機代碼也可以修補。

最終,代碼在黑客的機器上,黑客可以做他想做的事。他甚至可以在調試器下運行它,並修改內存中的數據。這是所有版權保護和授權機制面臨的問題。在我看來,許可證使客戶更難使用你的軟件,並且不會阻止一個堅定的黑客。你(或你的公司)想要讓你的客戶難以使用你的軟件嗎?

現在這並不意味着沒有解決方案。事實上有:黑客不能修改他的機器上沒有的代碼。讓代碼在您控制的服務器上運行。客戶端應用程序通過Web服務訪問它。 Web服務對用戶進行身份驗證(不是調用代碼,這是不可能的)。瞭解用戶,該服務可以驗證用戶的許可證。這是唯一的解決方案。

UPDATE

只是要清楚:這樣的服務需要運行,對用戶,而不僅僅是一個許可檢查具有價值的實際代碼。在後一種情況下,黑客可能會修改客戶端以免干擾該呼叫,甚至不能替換假許可證服務器。但是,假設許可證比重新生成服務中的實際邏輯更便宜。在這種情況下,即使黑客也會喜歡重新購買代碼。

+0

是的,我幾乎同意你所說的一切 - 但我確實有一個問題 - 你爲什麼要把密封的提供者放在第三個DLL中,而不是在主應用程序中?我絕對可以看到它的好處 - 我也考慮過這種方法,但我認爲反射構造函數調用非常簡單。然而,這是10-80-10的原則,我想趕上80,而不是硬核10 ...我並不一定同意許可證使用戶很難,除非你的實施很糟糕。我會盡我所能確保它不會:)。謝謝。 –

+0

我會把它放在第三個程序集中,就像其他契約(即MEF的接口)一樣,這樣我就可以在不需要重新編譯插件的情況下更新我的exe。雖然我必須承認,如果插件是由第三方開發的,這一點更爲重要。順便說一句,請注意,通過反射問題的內部構造函數存在,當類也坐落在program.exe中。 –

1

沒有防彈的方法來保護您的軟件。

我們曾經使用Safenet公司的Sentinel硬件密鑰,dotfuscator pro和智能組件來保護我們的一些應用程序。

硬件密鑰可以用來存儲許可證(即每個功能/插件都有自己的許可證,可以在硬件密鑰上啓用並由應用程序查詢)。可選地,他們的產品可用於加密您的應用程序 - 應用程序被加密,然後只能在內存中解密並在正確的硬件密鑰連接到系統時啓動。有一些反調試機制可以讓某人使用調試器變得更加困難,等待應用程序在內存中解密並複製它。

Dotfuscator和智能程序集可以用來「混淆」應用程序的代碼,以使用反射器等工具進行反編譯。

這些工具都不是防彈的。但是「真的很難實現/竊取」?我會這麼說,但這是一個代價......你肯定可以在這些工具上投入大量資金。

+0

全部都是如此。不幸的是,所有這些都會讓您的合法客戶難以使用您的軟件。而且它們讓你更難以出售它:現在你已經物理運送加密狗了!而且你需要一個服務檯,接受不能以任何理由工作的用戶的電話(「我的機器上沒有USB端口」)。你需要更換破損的加密狗。結束等等。這是一個真正的噩夢,也是一個昂貴的過程,對您的客戶和您來說都是如此。 –

+0

硬件鑰匙對於少數產品(低產量,高價格,在客戶現場直接支持的產品)有意義,但僅此而已。混淆工具對用戶來說是完全不顯眼的,並且總比沒有好......他們肯定會使反編譯器複製/粘貼C#代碼比反編譯起來困難得多。 – stmax

+0

需要客戶端直接支持的軟件並不需要加密狗。事實上,「要求在客戶端直接提供支持」可能與「在客戶端需要加密狗」一樣好,甚至可能更好。 –