2010-03-10 24 views
6

從應用程序本身之外從.NET應用程序中檢索嵌入式資源有多難?即使資源被壓縮和普通加密,使用工具檢索它們有多困難? (我不關心數據本身,資源本身的檢索的只是方法的保護).NET中的資源有多安全?


編輯:

我覺得我的問題被誤解了,這是少談加密還有更多關於檢索的內容,除了反射鏡之外,還有什麼可以使用的?

+2

加密的方式,究竟是什麼? – 2010-03-10 19:38:24

+0

很多工具都可以做到這一點。 ILSpy可以做到這一點。資源很容易檢索。在.NET程序集內部使用的解密方法可以很容易地逆轉。 – BrainSlugs83 2014-06-06 03:29:39

回答

8

使用諸如.NET Reflector.NET Resourcer之類的工具從編譯後的.NET DLL中檢索資源是微不足道的。

+0

您是否有其他方式知道?我將測試Resourcer,但Reflector目前不是問題。 – 2010-03-10 20:36:54

+2

那麼,你可以寫一點代碼。 Assembly.GetManifestResourceStream()。 – 2010-03-10 20:39:31

+0

另外,請嘗試在Visual Studio中打開程序集。只是好奇,你發現Reflector不能提取它們嗎? – 2010-03-10 21:17:07

6

如果您使用應用程序中嵌入的密鑰加密資源,那麼通過一點逆向工程就可以輕鬆地檢索密鑰,從而獲取資源。

如果您使用安全算法對它們進行加密並要求用戶輸入密碼,那麼如果沒有密碼,將無法提取資源。但我想這不是你想要的。我想你想阻止用戶在應用程序之外使用你的資源?

如果是的話,簡短的答案是:.NET中的資源不安全。

+3

我提高了你;但是,ANYING中的資源並不安全。使用什麼語言並不重要,如果加密密鑰嵌入在應用程序本身中,則可以將其拔出。 – NotMe 2010-03-10 20:18:49

2

如果我告訴你一個有一百萬美元的保險箱,那麼走開,你最終會進入安全。沒有技術可以保護這些資金,你唯一真正的障礙就是時間。

軟件也一樣。保護資源的唯一方法就是不要把它們放在有人可以的地方,給予足夠的時間,去找他們。我知道的最有效的選擇是將關鍵資源存儲在您控制的服務器上。

當然,很多人得到這個錯誤。不管怎樣,他們都允許將安全資源臨時複製到用戶的計算機上。在這一點上,遊戲丟失了。這意味着您只能真正確保擁有自然臨時克隆的資源。例如,過期的安全令牌或計算結果不會顯示如何計算。

2

問題不在於.NET資源,而在於一般的安全問題。您可以將這個問題改爲「我的客戶端應用程序存儲我不想進行反向工程的祕密」,而不是改變意圖。

什麼是在您的資源文件中,爲什麼它需要被保護?你有沒有考慮過一種設計,你根本不把這些祕密存儲在客戶端?如果您在保護客戶端機密方面進行銀行業務,我認爲您會感到失望。

+1

怎樣才能讓您使用第三方庫的許可證文件? - 如果您想在客戶端上使用第三方庫,則需要能夠獲取客戶端上的許可證文件 - 但您不希望最終用戶能夠將許可證文件取出並重新使用它自己... - 如果它泄漏,許可證被吊銷。那麼你如何保護它? – BrainSlugs83 2014-06-06 03:34:22

3

下面是一些快速代碼來從組件中獲取資源。你決定它是多麼容易和安全...

class Program 
{ 
    static void Main(string[] args) 
    { 
     var assemblies = from file in args 
         let assembly = TryLoad(file) 
         where assembly != null 
         from rName in assembly.GetManifestResourceNames() 
         select new { assembly, rName }; 

     foreach (var item in assemblies) 
      using (var rs = item.assembly 
           .GetManifestResourceStream(item.rName)) 
       SaveTo(rs, item.rName); 

    } 

    static void SaveTo(Stream stream, string name) 
    { 
     var buffer = new byte[32*1024]; 
     var bufferLen = 1; 
     using (var fs = new FileStream(name, FileMode.Create)) 
      while (bufferLen > 0) 
       if ((bufferLen = stream.Read(buffer, 0, buffer.Length)) > 0) 
        fs.Write(buffer, 0, bufferLen); 
    } 

    static Assembly TryLoad(string filename) 
    { 
     if (string.IsNullOrEmpty(filename) || 
      !File.Exists(filename)) 
      return null; 
     try 
     { 
      var fullName = Path.GetFullPath(filename); 
      return Assembly.LoadFile(fullName); 
     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine(ex); 
      return null; 
     } 
    } 
}