2013-05-21 46 views
3

我目前正在製作遊戲。我在內部構建日誌記錄工具,並且有一些消息類型,如常規,日誌,異常,發送,接收,調試。Java加密日誌

發送和接收日誌包含原始日誌記錄信息,所以它們確實包含我通過網絡發送的內容。

遊戲使用客戶端 - 服務器模型並使用SSL連接,以便網絡信息不能更改。但是對於日誌記錄,我會將文本記錄爲純文本,這顯然會造成麻煩。此外,我打算簡單地遮蔽(由*的)任何個人信息(如密碼等)

但是我有幾個擔心:

  • 客戶端程序包含了信任與SSL使用和服務器的主機名/ IP和端口也不是真正的祕密。所以如果一個人知道通過網絡發送什麼,那麼他可以像他是客戶那樣行事,對吧?
  • 如果一個人可以看到客戶端發送和接收的內容,那麼他​​可能很容易製作一個機器人。 (該遊戲是一款回合制2D遊戲,所以單純靠所有的網絡數據,你應該能夠玩遊戲,我認爲,沒有以任何方式所需的鼠標沒有技能。)

因此,所有總共:如何仍然可以記錄所有信息並將其寫入文件,但是沒有其他人能夠讀取,修改或以任何方式使用它?

所有的意見都非常感謝,我也希望具體的建議,如何實現這樣一個系統。

問候。

回答

6

如果您擔心加密服務器上的數據,那麼最簡單的解決方案就是像Truecrypt這樣的全分區加密程序 - 如果有人盜取了機器/硬盤驅動器,這將保護服務器數據。

如果您正在加密客戶端計算機上的數據,那麼這意味着加密密鑰也必須位於客戶端計算機上的某個位置(即使它位於主內存中)。繼續加密或混淆日誌信息,以使用戶更難閱讀它,但請注意,如果用戶付出足夠的努力,用戶仍然可以閱讀它。也就是說,混淆數據的最佳方式是使用永不保存到磁盤的密鑰對其進行加密 - 例如,當用戶登錄時,向他們發送一個新的加密密鑰,客戶端應用程序將使用該密鑰來加密日誌數據;在您的服務器上,記錄您發送給客戶端的密鑰以及UTC時間戳。使用未加密的時間戳存儲日誌,以便當用戶的客戶端應用程序發送日誌數據時,您將知道使用哪個密鑰對其進行解密。顯然,用戶可以輕鬆地更改時間戳,但這相當於用戶只需從他們的機器中刪除日誌數據(您無法防止);同時用戶很難找出用於加密數據的密鑰,因此用戶不容易讀取或僞造日誌數據(但是如果用戶花費了足夠的努力,用戶就可以讀取/僞造日誌數據進去)。

您可以採取措施通過例如模糊處理在內存中加密密鑰。將其存儲成多個部分。例如,假設您使用的是AES 128,那麼您可以將密鑰存儲在兩個64位塊中,然後在加密數據之前將它們連接起來,然後一旦完成處理即從內存中擦除連接的密鑰。或者,您可以將兩個128位密鑰存儲在一起,並在您完成後再次從內存中擦除Xor'd密鑰。一個專門的用戶仍然可以找出關鍵,但這會讓他們更加困難。

您可以採取的另一個步驟是使用AES之外的加密算法,例如,像Twofish或Serpent這樣的其他AES入圍者(不要實現你自己的加密算法,你最好是廣播說你使用的是像AES這樣強大的算法,而不是使用弱混淆算法)。只要記住混淆加密庫的類和方法名稱,以使用戶更難找出您正在使用的加密算法。 (如果你正在編譯機器代碼,這會更加有效 - 如果你使用Java,這可能是不值得的,因爲用戶可以簡單地反編譯你的代碼並使用你自己的解密代碼來解密日誌文件。)

在確定玩家是人還是機器人方面,甚至連比您的預算更多的遊戲都能夠可靠地做到這一點 - 您所能做的就是引導用戶或向他們發送某種驗證碼他們表現出「類似機器人」的行爲,但這並不是傻瓜式的,而且您真的應該贊成不會讓惱人的合法用戶過度使用機器人。

+0

請注意,Java中的現代垃圾收集意味着您無法可靠地從內存中「擦除」任何東西。即使調出一個數組也不意味着內存管理器沒有在其他地方製作一個臨時副本。 – Jazzepi

2

你可以做的事情不多。如果客戶端是用Java編寫的,那麼反向工程很容易,或者使用像AspectJ這樣的東西來監視客戶端寫入網絡的內容。對於任何寫入日誌系統的數據也是如此,即使它最終被加密。

+0

因此 - 即使沒有日誌記錄 - 任何人都可以像它是一個真正的客戶端?您嘗試使用SSL實現的所有網絡數據都是安全的嗎?有什麼方法可以確定我是在與真人玩家還是與機器人玩? – skiwi

+0

SSL可以保護客戶端和服務器之間攔截的數據。它不會阻止客戶端檢查數據。 –

0

我和你有完全一樣的需求。有人稱'maybeWeCouldStealAVa'寫了一個很好的實現:How to append to AES encrypted file

我已經證實它的工作原理,但是當我在每行的末尾flush()時,我錯過了最後一部分消息 - 最多16個字節 - 直到寫入下一條消息。我可以在每行的結尾處關閉(),因爲這似乎是編寫填充的唯一方法。但至少它不需要讀取整個文件以便能夠附加到它。