![](/img/trans.png)
[英]Java Thread Serialization , why serialized Thread Object can be started
[英]Serialization - How to secure a serialized JAVA object?
如果我通過 .network 發送序列化的 object,我如何保護序列化的 object? 我懷疑黑客可能會中斷/破解我的數據。
任何人都可以詳細說明如何實現這個嗎?
此演示文稿提供了有關攻擊者如何有效篡改Java序列化流的想法:
https://www.owasp.org/images/e/eb/OWASP_IL_2008_Shai_Chen_PT_to_Java_Client_Server_Apps.ppt
如果服務器的類路徑上存在易受攻擊的類,則還存在注入意外行為並注入代碼的風險。 看到這篇文章:
[Look-ahead Java反序列化] [3]
java.crypto.SealedObject
正是您要找的。
您可以加密或散列它,但java序列化格式是通過網絡發送的一個很好的選擇 - 更好的解決方案是JSON / XML(加密或用一些加密算法簽名)
如前所述,請查看加密,但更具體地說,請查看用於java中網絡通信的hte SSL / TLS庫。
http://juliusdavies.ca/commons-ssl/ssl.html
當Java內置一個非常強大的庫時,無需嘗試實現安全加密通信。
在我看來,您可以使用SSLSocket
或SealedObject
。 但是,它會讓你的事情變得有點沉重。 但是,本文還介紹了其中一個選項。 http://www.ibm.com/developerworks/library/j-5things1/
您可以使用簽名對象和密封對象來保護序列化對象
我在這里的線程中添加了一個有用的資源,Oracle 的Java SE 安全編碼指南(特別是在這種情況下,指南中的第 8 節“序列化和反序列化”):
https://www.oracle.com/java/technologies/javase/seccodeguide.html#8
保護 java 中任何 object 的一個好方法是在構造函數中強制執行不變量。 例如,想象一個 class Person
,您不想允許任何 13 歲以下的人的實例化:
public class Person implements Serializable{
private String name;
private Integer age;
public Person(final String name, final Integer age) {
if(age < 13) {
throw new IllegalArgumentException("invalid age");
}
this.name = name;
this.age = age;
}
}
但是,當您實現Serializable
時,可能會編寫繞過構造函數的代碼,這應該是我們的主要防御機制,因此有可能破壞封裝:
@Test
void testEncapsulationSerialization() throws IOException, ClassNotFoundException {
Person a = new Person("dave", 23);
ByteArrayOutputStream boas = new ByteArrayOutputStream();
try (ObjectOutputStream oos = new ObjectOutputStream(boas)) {
oos.writeObject(a);
}
byte[] bytes = boas.toByteArray();
bytes[237] = 12; // trick: we are modifying the array of bytes manually
try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
Person b = (Person) ois.readObject();
System.out.println(a);
System.out.println(b);
}
}
通過這個測試,我們能夠創建一個年齡為 12 歲的Person
類型的 object(這在我們的構造函數中是不允許的)。
所以在這種情況下,如果你想保護序列化,你需要重寫Person
class readResolve()
方法來調用你的構造函數:
private Object readResolve() throws ObjectStreamException {
return new Person(this);
}
這樣我們將強制任何實例化都遵循構造函數中聲明的不變量。
此外,如果您有一個實現序列化的父對象 class,您可能還需要覆蓋readObject()
和writeObject()
方法。
此外,您應該確保 object 的不變性,因為 java 的默認可擴展性不利於安全。
總而言之,我們應該避免使用Serializable
(和Clonable
),因為如果我們不明確保護它們,它們都會破壞封裝。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.