可以的。推薦的是使用綠盾加密,采用的是文件透明加密模塊,對(duì)平常辦公使用是沒(méi)有影響的。而且綠盾支持與SVN等源代碼管理工具無(wú)縫結(jié)合。
創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比富陽(yáng)網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式富陽(yáng)網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋富陽(yáng)地區(qū)。費(fèi)用合理售后完善,十余年實(shí)體公司更值得信賴。
如果企業(yè)內(nèi)部SVN服務(wù)器采取透明模式,即加密文件是可以存放在SVN服務(wù)器上的,需要達(dá)到的效果是SVN服務(wù)器上文件密文存儲(chǔ)。則配合天銳綠盾應(yīng)用服務(wù)器安全接入系統(tǒng)來(lái)實(shí)現(xiàn)只有安裝了加密客戶端的Windows、Linux、MAC端才能夠正常的訪問(wèn)公司內(nèi)部的SVN服務(wù)器。
如果企業(yè)內(nèi)部采用eclipse、VS等開發(fā)工具,從這些開發(fā)工具將代碼直接上傳到SVN服務(wù)器上時(shí)會(huì)自動(dòng)解密。為了避免明文、密文混亂存放導(dǎo)致版本比對(duì)時(shí)出現(xiàn)錯(cuò)誤等問(wèn)題。因此,SVN服務(wù)器上需統(tǒng)一存放明文文件。則通過(guò)服務(wù)器白名單功能實(shí)現(xiàn)對(duì)終端電腦數(shù)據(jù)進(jìn)行強(qiáng)制透明加密,對(duì)上傳到應(yīng)用服務(wù)器數(shù)據(jù)實(shí)現(xiàn)上傳自動(dòng)解密、下載自動(dòng)加密。再配合天銳綠盾應(yīng)用服務(wù)器安全接入系統(tǒng)實(shí)現(xiàn)只有安裝了加密客戶端的Windows、Linux、MAC端才能夠正常的訪問(wèn)公司內(nèi)部的SVN服務(wù)器。
賽虎信息科技始終傾力為企事業(yè)單位的信息安全、綠盾數(shù)據(jù)防泄密提供一體化顧問(wèn)式解決方案,為客戶提供優(yōu)質(zhì)的內(nèi)網(wǎng)安全管理產(chǎn)品和適合多種行業(yè)的應(yīng)用解決方案。
先回答你的問(wèn)題,然后擴(kuò)展開說(shuō)說(shuō)我的看法。 有些公司是這樣做的:為工作場(chǎng)所劃分保護(hù)級(jí)別。 為每臺(tái)服務(wù)器和計(jì)算機(jī)定義保護(hù)級(jí)別,并制定相應(yīng)保護(hù)級(jí)別下的保護(hù)策略,包括授權(quán)和訪問(wèn)方法。 將場(chǎng)所分為工作區(qū)和上網(wǎng)區(qū),工作區(qū)不連外網(wǎng),上網(wǎng)區(qū)是員工共享的非專用機(jī)。 封閉所有計(jì)算機(jī)的外部接口,比如USB口、光驅(qū)沒(méi)有刻錄功能、disable藍(lán)牙,不允許計(jì)算機(jī)和U盤或手機(jī)等外設(shè)交換數(shù)據(jù)。 所有對(duì)外發(fā)的數(shù)據(jù)統(tǒng)一由高層來(lái)接口審核。所有計(jì)算機(jī)安裝后臺(tái)監(jiān)控軟件,監(jiān)控操作行為。 普通員工不配置筆記本電腦。 辦公空間安裝攝像頭監(jiān)視異常行為。 和員工簽署保密協(xié)議。等等上面的措施的確能起到一定保護(hù)作用,但是不能保證絕對(duì)不發(fā)生問(wèn)題:公司開展業(yè)務(wù)必然要和外部進(jìn)行信息交流,即使在硬件上做到了上述這些,如果真有居心不良的員工,那么只是增加了作案的難度,只要能上網(wǎng),想把信息傳到外部還是有辦法的,比如把想竊取的信息通過(guò)編碼的方式打包到正常外發(fā)的文件里。 可以在攝像頭死角的地方,暴力破壞計(jì)算機(jī),或者把計(jì)算機(jī)硬盤拆下來(lái)拿回去研究。 最不濟(jì)還可以把核心代碼寫到筆記上,你總不能不讓員工寫讀書筆記吧。 互聯(lián)網(wǎng)公司產(chǎn)品的很多代碼都是基于開源框架演化來(lái)的,有些開源許可是基于GPL的,是要求其衍生物是免費(fèi)開放源代碼的。雖然有很多公司會(huì)取巧地繞開這個(gè)限定條件。 對(duì)于游戲公司,設(shè)計(jì)、策劃、代碼的保護(hù)是蠻重要的,因?yàn)殚_發(fā)期的游戲設(shè)計(jì)一旦外漏,很可能就失去了市場(chǎng)先機(jī)。 照我看,除了專用算法、特定的格式保護(hù)、極少數(shù)產(chǎn)品本身固有的設(shè)計(jì)、某些特殊行業(yè)(比如網(wǎng)游)之外,很多代碼都是通用的,可開放的。有以下一些建議:清晰自己所在的行業(yè)特點(diǎn),對(duì)代碼外泄做個(gè)風(fēng)險(xiǎn)評(píng)估,確定保護(hù)代碼安全的思路和策略; 劃分核心代碼和非核心代碼,分別制定保護(hù)策略; 在核心代碼上下功夫,能接觸這些代碼的人一定是可以信任的人,盡可能地少,但也要考慮備份人選; 把核心代碼做成編譯好的庫(kù)供程序調(diào)用,這樣就能降低核心代碼泄漏的風(fēng)險(xiǎn); 員工入職簽署保密協(xié)議; 選拔高層注重品德和忠誠(chéng)度,簽訂競(jìng)業(yè)保護(hù)協(xié)議; 最后公司領(lǐng)導(dǎo)要有一個(gè)開放心態(tài),正因?yàn)橛虚_源的出現(xiàn),才促進(jìn)了計(jì)算機(jī)軟件的發(fā)展,固守著自己的一畝三分地,早晚要被對(duì)手超越。想在競(jìng)爭(zhēng)中脫穎而出,首先要去除管理者的保守心態(tài)。開放、公平競(jìng)爭(zhēng)才讓公司更有底氣和信心。
首先要明確,哪些數(shù)據(jù)是核心機(jī)密數(shù)據(jù),不能讓普通員工輕易接觸到的,即使是研發(fā)型公司的代碼,也是會(huì)劃分等級(jí)的,要在保證員工的工作效率的前提下,對(duì)代碼實(shí)施保護(hù)措施。
下面簡(jiǎn)單談一下我的看法,講講如何防止員工的代碼泄露。
首先要明確以下兩點(diǎn):
1、不影響被防范的成員(比如新程序員)工作。讓其能正常運(yùn)行、調(diào)試、查看日志等。
2、對(duì)核心代碼封死,需要保護(hù)的部分不可見(jiàn)。
再來(lái)看看有哪些具體做法:
簽署保密協(xié)議
對(duì)源代碼分級(jí),清楚知道什么是需要保護(hù)的
為版本管理服務(wù)器上的工程設(shè)置讀取密碼
源碼版本控制,按照職責(zé)和權(quán)限進(jìn)行劃分
確保架構(gòu)做分層
屏蔽USB和光驅(qū)
每人兩臺(tái)電腦,分別連接不同網(wǎng)絡(luò)
封閉式開發(fā)、禁止上互聯(lián)網(wǎng)
使用加密軟件
使用加水印功能
使用云桌面技術(shù)
實(shí)施網(wǎng)絡(luò)隔離
……
當(dāng)然,每個(gè)公司會(huì)根據(jù)自身的實(shí)際情況來(lái)選擇一種適合的方法,前提是不影響員工工作效率,不能讓員工產(chǎn)生抵觸情緒。公司的價(jià)值都是員工創(chuàng)造的,所以一定要秉著以人為本的原則,讓員工對(duì)公司忠誠(chéng),減少離職,這才是利益最大化的方法。
在以上這些方法中,個(gè)人較為推薦的是使用云桌面或者實(shí)施網(wǎng)絡(luò)隔離,通過(guò)云桌面實(shí)現(xiàn)數(shù)據(jù)不落地,防止被拷貝;實(shí)施網(wǎng)絡(luò)隔離可以有效阻斷數(shù)據(jù)的外泄。之前看過(guò)《企業(yè)網(wǎng)絡(luò)隔離建設(shè)指南》,感覺(jué)還不錯(cuò),推薦給大家參考一下。
在本文中,我們討論了對(duì)付 13 種不同靜態(tài)暴露的技巧。對(duì)于每種暴露,我們解釋了不處理這些安全性問(wèn)題所造成的影響。我們還為您推薦了一些準(zhǔn)則,要開發(fā)不受這些靜態(tài)安全性暴露威脅的、健壯且安全的 Java 應(yīng)用程序,您應(yīng)該遵循這些準(zhǔn)則。一有合適的時(shí)機(jī),我們就提供代碼樣本(既有暴露的代碼也有無(wú)暴露的代碼)。
對(duì)付高嚴(yán)重性暴露的技巧
請(qǐng)遵循下列建議以避免高嚴(yán)重性靜態(tài)安全性暴露:
限制對(duì)變量的訪問(wèn)
讓每個(gè)類和方法都成為 final,除非有足夠的理由不這樣做
不要依賴包作用域
使類不可克隆
使類不可序列化
使類不可逆序列化
避免硬編碼敏感數(shù)據(jù)
查找惡意代碼
限制對(duì)變量的訪問(wèn)
如果將變量聲明為 public,那么外部代碼就可以操作該變量。這可能會(huì)導(dǎo)致安全性暴露。
影響
如果實(shí)例變量為 public,那么就可以在類實(shí)例上直接訪問(wèn)和操作該實(shí)例變量。將實(shí)例變量聲明為 protected 并不一定能解決這一問(wèn)題:雖然不可能直接在類實(shí)例基礎(chǔ)上訪問(wèn)這樣的變量,但仍然可以從派生類訪問(wèn)這個(gè)變量。
清單 1 演示了帶有 public 變量的代碼,因?yàn)樽兞繛?public 的,所以它暴露了。
清單 1. 帶有 public 變量的代碼
class Test {
public int id;
protected String name;
Test(){
id = 1;
name = "hello world";
}
//code
}
public class MyClass extends Test{
public void methodIllegalSet(String name){
this.name = name; // this should not be allowed
}
public static void main(String[] args){
Test obj = new Test();
obj.id = 123; // this should not be allowed
MyClass mc = new MyClass();
mc.methodIllegalSet("Illegal Set Value");
}
}
建議
一般來(lái)說(shuō),應(yīng)該使用取值方法而不是 public 變量。按照具體問(wèn)題具體對(duì)待的原則,在確定哪些變量特別重要因而應(yīng)該聲明為 private 時(shí),請(qǐng)將編碼的方便程度及成本同安全性需要加以比較。清單 2 演示了以下列方式來(lái)使之安全的代碼:
清單 2. 不帶有 public 變量的代碼
class Test {
private int id;
private String name;
Test(){
id = 1;
name = "hello world";
}
public void setId(int id){
this.id = id;
}
public void setName(String name){
this.name = name;
}
public int getId(){
return id;
}
public String getName(){
return name;
}
}
讓每個(gè)類和方法都為 final
不允許擴(kuò)展的類和方法應(yīng)該聲明為 final。這樣做防止了系統(tǒng)外的代碼擴(kuò)展類并修改類的行為。
影響
僅僅將類聲明為非 public 并不能防止攻擊者擴(kuò)展類,因?yàn)槿匀豢梢詮乃约旱陌鼉?nèi)訪問(wèn)該類。
建議
讓每個(gè)類和方法都成為 final,除非有足夠的理由不這樣做。按此建議,我們要求您放棄可擴(kuò)展性,雖然它是使用諸如 Java 語(yǔ)言之類的面向?qū)ο笳Z(yǔ)言的主要優(yōu)點(diǎn)之一。在試圖提供安全性時(shí),可擴(kuò)展性卻成了您的敵人;可擴(kuò)展性只會(huì)為攻擊者提供更多給您帶來(lái)麻煩的方法。
不要依賴包作用域
沒(méi)有顯式地標(biāo)注為 public、private 或 protected 的類、方法和變量在它們自己的包內(nèi)是可訪問(wèn)的。
影響
如果 Java 包不是封閉的,那么攻擊者就可以向包內(nèi)引入新類并使用該新類來(lái)訪問(wèn)您想保護(hù)的內(nèi)容。諸如 java.lang 之類的一些包缺省是封閉的,一些 JVM 也讓您封閉自己的包。然而,您最好假定包是不封閉的。
建議
從軟件工程觀點(diǎn)來(lái)看,包作用域具有重要意義,因?yàn)樗梢宰柚箤?duì)您想隱藏的內(nèi)容進(jìn)行偶然的、無(wú)意中的訪問(wèn)。但不要依靠它來(lái)獲取安全性。應(yīng)該將類、方法和變量顯式標(biāo)注為 public、private 或 protected 中適合您特定需求的那種。
使類不可克隆
克隆允許繞過(guò)構(gòu)造器而輕易地復(fù)制類實(shí)例。
影響
即使您沒(méi)有有意使類可克隆,外部源仍然可以定義您的類的子類,并使該子類實(shí)現(xiàn) java.lang.Cloneable。這就讓攻擊者創(chuàng)建了您的類的新實(shí)例??截惉F(xiàn)有對(duì)象的內(nèi)存映象生成了新的實(shí)例;雖然這樣做有時(shí)候是生成新對(duì)象的可接受方法,但是大多數(shù)時(shí)候是不可接受的。清單 3 說(shuō)明了因?yàn)榭煽寺《┞兜拇a:
清單 3. 可克隆代碼
class MyClass{
private int id;
private String name;
public MyClass(){
id=1;
name="HaryPorter";
}
public MyClass(int id,String name){
this.id=id;
this.name=name;
}
public void display(){
System.out.println("Id ="+id+"
"+"Name="+name);
}
}
// hackers code to clone the user class
public class Hacker extends MyClass implements Cloneable {
public static void main(String[] args){
Hacker hack=new Hacker();
try{
MyClass o=(MyClass)hack.clone();
o.display();
}
catch(CloneNotSupportedException e){
e.printStackTrace();
}
}
}
建議
要防止類被克隆,可以將清單 4 中所示的方法添加到您的類中:
清單 4. 使您的代碼不可克隆
public final Object clone()
throws java.lang.CloneNotSupportedException{
throw new java.lang.CloneNotSupportedException();
}
如果想讓您的類可克隆并且您已經(jīng)考慮了這一選擇的后果,那么您仍然可以保護(hù)您的類。要做到這一點(diǎn),請(qǐng)?jiān)谀念愔卸x一個(gè)為 final 的克隆方法,并讓它依賴于您的一個(gè)超類中的一個(gè)非 final 克隆方法,如清單 5 中所示:
清單 5. 以安全的方式使您的代碼可克隆
public final Object clone()
throws java.lang.CloneNotSupportedException {
super.clone();
}
類中出現(xiàn) clone() 方法防止攻擊者重新定義您的 clone 方法。
使類不可序列化
序列化允許將類實(shí)例中的數(shù)據(jù)保存在外部文件中。闖入代碼可以克隆或復(fù)制實(shí)例,然后對(duì)它進(jìn)行序列化。
影響
序列化是令人擔(dān)憂的,因?yàn)樗试S外部源獲取對(duì)您的對(duì)象的內(nèi)部狀態(tài)的控制。這一外部源可以將您的對(duì)象之一序列化成攻擊者隨后可以讀取的字節(jié)數(shù)組,這使得攻擊者可以完全審查您的對(duì)象的內(nèi)部狀態(tài),包括您標(biāo)記為 private 的任何字段。它也允許攻擊者訪問(wèn)您引用的任何對(duì)象的內(nèi)部狀態(tài)。
建議
要防止類中的對(duì)象被序列化,請(qǐng)?jiān)陬愔卸x清單 6 中的 writeObject() 方法:
清單 6. 防止對(duì)象序列化
private final void writeObject(ObjectOutputStream out)
throws java.io.NotSerializableException {
throw new java.io.NotSerializableException("This object cannot
be serialized");
}
通過(guò)將 writeObject() 方法聲明為 final,防止了攻擊者覆蓋該方法。
使類不可逆序列化
通過(guò)使用逆序列化,攻擊者可以用外部數(shù)據(jù)或字節(jié)流來(lái)實(shí)例化類。
影響
不管類是否可以序列化,都可以對(duì)它進(jìn)行逆序列化。外部源可以創(chuàng)建逆序列化成類實(shí)例的字節(jié)序列。這種可能為您帶來(lái)了大量風(fēng)險(xiǎn),因?yàn)槟荒芸刂颇嫘蛄谢瘜?duì)象的狀態(tài)。請(qǐng)將逆序列化作為您的對(duì)象的另一種公共構(gòu)造器 — 一種您無(wú)法控制的構(gòu)造器。
建議
要防止對(duì)對(duì)象的逆序列化,應(yīng)該在您的類中定義清單 7 中的 readObject() 方法:
清單 7. 防止對(duì)象逆序列化
private final void readObject(ObjectInputStream in)
throws java.io.NotSerializableException {
throw new java.io.NotSerializableException("This object cannot
be deserialized");
}
通過(guò)將該方法聲明為 final,防止了攻擊者覆蓋該方法。
避免硬編碼敏感數(shù)據(jù)
您可能會(huì)嘗試將諸如加密密鑰之類的秘密存放在您的應(yīng)用程序或庫(kù)的代碼。對(duì)于你們開發(fā)人員來(lái)說(shuō),這樣做通常會(huì)把事情變得更簡(jiǎn)單。
影響
任何運(yùn)行您的代碼的人都可以完全訪問(wèn)以這種方法存儲(chǔ)的秘密。沒(méi)有什么東西可以防止心懷叵測(cè)的程序員或虛擬機(jī)窺探您的代碼并了解其秘密。
建議
可以以一種只可被您解密的方式將秘密存儲(chǔ)在您代碼中。在這種情形下,秘密只在于您的代碼所使用的算法。這樣做沒(méi)有多大壞處,但不要洋洋得意,認(rèn)為這樣做提供了牢固的保護(hù)。您可以遮掩您的源代碼或字節(jié)碼 — 也就是,以一種為了解密必須知道加密格式的方法對(duì)源代碼或字節(jié)碼進(jìn)行加密 — 但攻擊者極有可能能夠推斷出加密格式,對(duì)遮掩的代碼進(jìn)行逆向工程從而揭露其秘密。
這一問(wèn)題的一種可能解決方案是:將敏感數(shù)據(jù)保存在屬性文件中,無(wú)論什么時(shí)候需要這些數(shù)據(jù),都可以從該文件讀取。如果數(shù)據(jù)極其敏感,那么在訪問(wèn)屬性文件時(shí),您的應(yīng)用程序應(yīng)該使用一些加密/解密技術(shù)。
查找惡意代碼
從事某個(gè)項(xiàng)目的某個(gè)心懷叵測(cè)的開發(fā)人員可能故意引入易受攻擊的代碼,打算日后利用它。這樣的代碼在初始化時(shí)可能會(huì)啟動(dòng)一個(gè)后臺(tái)進(jìn)程,該進(jìn)程可以為闖入者開后門。它也可以更改一些敏感數(shù)據(jù)。
這樣的惡意代碼有三類:
類中的 main 方法
定義過(guò)且未使用的方法
注釋中的死代碼
影響
入口點(diǎn)程序可能很危險(xiǎn)而且有惡意。通常,Java 開發(fā)人員往往在其類中編寫 main() 方法,這有助于測(cè)試單個(gè)類的功能。當(dāng)類從測(cè)試轉(zhuǎn)移到生產(chǎn)環(huán)境時(shí),帶有 main() 方法的類就成為了對(duì)應(yīng)用程序的潛在威脅,因?yàn)殛J入者將它們用作入口點(diǎn)。
請(qǐng)檢查代碼中是否有未使用的方法出現(xiàn)。這些方法在測(cè)試期間將會(huì)通過(guò)所有的安全檢查,因?yàn)樵诖a中不調(diào)用它們 — 但它們可能含有硬編碼在它們內(nèi)部的敏感數(shù)據(jù)(雖然是測(cè)試數(shù)據(jù))。引入一小段代碼的攻擊者隨后可能調(diào)用這樣的方法。
避免最終應(yīng)用程序中的死代碼(注釋內(nèi)的代碼)。如果闖入者去掉了對(duì)這樣的代碼的注釋,那么代碼可能會(huì)影響系統(tǒng)的功能性。
可以在清單 8 中看到所有三種類型的惡意代碼的示例:
清單 8. 潛在惡意的 Java 代碼
public void unusedMethod(){
// code written to harm the system
}
public void usedMethod(){
//unusedMethod(); //code in comment put with bad intentions,
//might affect the system if uncommented
// int x = 100;
// x=x+10; //Code in comment, might affect the
//functionality of the system if uncommented
}
建議
應(yīng)該將(除啟動(dòng)應(yīng)用程序的 main() 方法之外的)main() 方法、未使用的方法以及死代碼從應(yīng)用程序代碼中除去。在軟件交付使用之前,主要開發(fā)人員應(yīng)該對(duì)敏感應(yīng)用程序進(jìn)行一次全面的代碼評(píng)審。應(yīng)該使用“Stub”或“dummy”類代替 main() 方法以測(cè)試應(yīng)用程序的功能。
對(duì)付中等嚴(yán)重性暴露的技巧
請(qǐng)遵循下列建議以避免中等嚴(yán)重性靜態(tài)安全性暴露:
不要依賴初始化
不要通過(guò)名稱來(lái)比較類
不要使用內(nèi)部類
不要依賴初始化
您可以不運(yùn)行構(gòu)造器而分配對(duì)象。這些對(duì)象使用起來(lái)不安全,因?yàn)樗鼈儾皇峭ㄟ^(guò)構(gòu)造器初始化的。
影響
在初始化時(shí)驗(yàn)證對(duì)象確保了數(shù)據(jù)的完整性。
例如,請(qǐng)想象為客戶創(chuàng)建新帳戶的 Account 對(duì)象。只有在 Account 期初余額大于 0 時(shí),才可以開設(shè)新帳戶??梢栽跇?gòu)造器里執(zhí)行這樣的驗(yàn)證。有些人未執(zhí)行構(gòu)造器而創(chuàng)建 Account 對(duì)象,他可能創(chuàng)建了一個(gè)具有一些負(fù)值的新帳戶,這樣會(huì)使系統(tǒng)不一致,容易受到進(jìn)一步的干預(yù)。
建議
在使用對(duì)象之前,請(qǐng)檢查對(duì)象的初始化過(guò)程。要做到這一點(diǎn),每個(gè)類都應(yīng)該有一個(gè)在構(gòu)造器中設(shè)置的私有布爾標(biāo)志,如清單 9 中的類所示。在每個(gè)非 static 方法中,代碼在任何進(jìn)一步執(zhí)行之前都應(yīng)該檢查該標(biāo)志的值。如果該標(biāo)志的值為 true,那么控制應(yīng)該進(jìn)一步繼續(xù);否則,控制應(yīng)該拋出一個(gè)例外并停止執(zhí)行。那些從構(gòu)造器調(diào)用的方法將不會(huì)檢查初始化的變量,因?yàn)樵谡{(diào)用方法時(shí)沒(méi)有設(shè)置標(biāo)志。因?yàn)檫@些方法并不檢查標(biāo)志,所以應(yīng)該將它們聲明為 private 以防止用戶直接訪問(wèn)它們。
清單 9. 使用布爾標(biāo)志以檢查初始化過(guò)程
public class MyClass{
private boolean initialized = false;
//Other variables
public MyClass (){
//variable initialization
method1();
initialized = true;
}
private void method1(){ //no need to check for initialization variable
//code
}
public void method2(){
try{
if(initialized==true){
//proceed with the business logic
}
else{
throw new Exception("Illegal State Of the object");
}
}catch(Exception e){
e.printStackTrace();
}
}
}
如果對(duì)象由逆序列化進(jìn)行初始化,那么上面討論的驗(yàn)證機(jī)制將難以奏效,因?yàn)樵谠撨^(guò)程中并不調(diào)用構(gòu)造器。在這種情況下,類應(yīng)該實(shí)現(xiàn) ObjectInputValidation 接口:
清單 10. 實(shí)現(xiàn) ObjectInputValidation
interface java.io.ObjectInputValidation {
public void validateObject() throws InvalidObjectException;
}
所有驗(yàn)證都應(yīng)該在 validateObject() 方法中執(zhí)行。對(duì)象還必須調(diào)用 ObjectInputStream.RegisterValidation() 方法以為逆序列化對(duì)象之后的驗(yàn)證進(jìn)行注冊(cè)。 RegisterValidation() 的第一個(gè)參數(shù)是實(shí)現(xiàn) validateObject() 的對(duì)象,通常是對(duì)對(duì)象自身的引用。注:任何實(shí)現(xiàn) validateObject() 的對(duì)象都可能充當(dāng)對(duì)象驗(yàn)證器,但對(duì)象通常驗(yàn)證它自己對(duì)其它對(duì)象的引用。RegisterValidation() 的第二個(gè)參數(shù)是一個(gè)確定回調(diào)順序的整數(shù)優(yōu)先級(jí),優(yōu)先級(jí)數(shù)字大的比優(yōu)先級(jí)數(shù)字小的先回調(diào)。同一優(yōu)先級(jí)內(nèi)的回調(diào)順序則不確定。
當(dāng)對(duì)象已逆序列化時(shí),ObjectInputStream 按照從高到低的優(yōu)先級(jí)順序調(diào)用每個(gè)已注冊(cè)對(duì)象上的 validateObject()。
不要通過(guò)名稱來(lái)比較類
有時(shí)候,您可能需要比較兩個(gè)對(duì)象的類,以確定它們是否相同;或者,您可能想看看某個(gè)對(duì)象是否是某個(gè)特定類的實(shí)例。因?yàn)?JVM 可能包括多個(gè)具有相同名稱的類(具有相同名稱但卻在不同包內(nèi)的類),所以您不應(yīng)該根據(jù)名稱來(lái)比較類。
影響
如果根據(jù)名稱來(lái)比較類,您可能無(wú)意中將您不希望授予別人的權(quán)利授予了闖入者的類,因?yàn)殛J入者可以定義與您的類同名的類。
例如,請(qǐng)假設(shè)您想確定某個(gè)對(duì)象是否是類 com.bar.Foo 的實(shí)例。清單 11 演示了完成這一任務(wù)的錯(cuò)誤方法:
清單 11. 比較類的錯(cuò)誤方法
if(obj.getClass().getName().equals("Foo")) // Wrong!
// objects class is named Foo
}else{
// object's class has some other name
}
建議
在那些非得根據(jù)名稱來(lái)比較類的情況下,您必須格外小心,必須確保使用了當(dāng)前類的 ClassLoader 的當(dāng)前名稱空間,如清單 12 中所示:
清單 12. 比較類的更好方法
if(obj.getClass() == this.getClassLoader().loadClass("com.bar.Foo")){
// object's class is equal to
//the class that this class calls "com.bar.Foo"
}else{
// object's class is not equal to the class that
// this class calls "com.bar.Foo"
}
然而,比較類的更好方法是直接比較類對(duì)象看它們是否相等。例如,如果您想確定兩個(gè)對(duì)象 a 和 b 是否屬同一個(gè)類,那么您就應(yīng)該使用清單 13 中的代碼:
清單 13. 直接比較對(duì)象來(lái)看它們是否相等
if(a.getClass() == b.getClass()){
// objects have the same class
}else{
// objects have different classes
}
盡可能少用直接名稱比較。
不要使用內(nèi)部類
Java 字節(jié)碼沒(méi)有內(nèi)部類的概念,因?yàn)榫幾g器將內(nèi)部類轉(zhuǎn)換成了普通類,而如果沒(méi)有將內(nèi)部類聲明為 private,則同一個(gè)包內(nèi)的任何代碼恰好能訪問(wèn)該普通類。
影響
因?yàn)橛羞@一特性,所以包內(nèi)的惡意代碼可以訪問(wèn)這些內(nèi)部類。如果內(nèi)部類能夠訪問(wèn)括起外部類的字段,那么情況會(huì)變得更糟??赡芤呀?jīng)將這些字段聲明為 private,這樣內(nèi)部類就被轉(zhuǎn)換成了獨(dú)立類,但當(dāng)內(nèi)部類訪問(wèn)外部類的字段時(shí),編譯器就將這些字段從專用(private)的變?yōu)樵诎╬ackage)的作用域內(nèi)有效的。內(nèi)部類暴露了已經(jīng)夠糟糕的了,但更糟糕的是編譯器使您將某些字段成為 private 的舉動(dòng)成為徒勞。
建議 如果能夠不使用內(nèi)部類就不要使用內(nèi)部類。
對(duì)付低嚴(yán)重性暴露的技巧
請(qǐng)遵循下列建議以避免低嚴(yán)重性靜態(tài)安全性暴露:
避免返回可變對(duì)象
檢查本機(jī)方法
避免返回可變對(duì)象
Java 方法返回對(duì)象引用的副本。如果實(shí)際對(duì)象是可改變的,那么使用這樣一個(gè)引用調(diào)用程序可能會(huì)改變它的內(nèi)容,通常這是我們所不希望見(jiàn)到的。
影響
請(qǐng)考慮這個(gè)示例:某個(gè)方法返回一個(gè)對(duì)敏感對(duì)象的內(nèi)部數(shù)組的引用,假定該方法的調(diào)用程序不改變這些對(duì)象。即使數(shù)組對(duì)象本身是不可改變的,也可以在數(shù)組對(duì)象以外操作數(shù)組的內(nèi)容,這種操作將反映在返回該數(shù)組的對(duì)象中。如果該方法返回可改變的對(duì)象,那么事情會(huì)變得更糟;外部實(shí)體可以改變?cè)谀莻€(gè)類中聲明的 public 變量,這種改變將反映在實(shí)際對(duì)象中。
清單 14 演示了脆弱性。getExposedObj() 方法返回了 Exposed 對(duì)象的引用副本,該對(duì)象是可變的:
清單 14. 返回可變對(duì)象的引用副本
class Exposed{
private int id;
private String name;
public Exposed(){
}
public Exposed(int id, String name){
this.id = id;
this.name = name;
}
public int getId(){
return id;
}
public String getName(){
return name;
}
public void setId(int id){
this.id=id;
}
public void setName(String name){
this.name = name;
}
public void display(){
System.out.println("Id = "+ id + " Name = "+ name);
}
}
public class Exp12{
private Exposed exposedObj = new Exposed(1,"Harry Porter");
public Exposed getExposedObj(){
return exposedObj; //returns a reference to the object.
}
public static void main(String[] args){
Exp12 exp12 = new Exp12();
exp12.getExposedObj().display();
Exposed exposed = exp12.getExposedObj();
exposed.setId(10);
exposed.setName("Hacker");
exp12.getExposedObj().display();
}
}
建議
如果方法返回可改變的對(duì)象,但又不希望調(diào)用程序改變?cè)搶?duì)象,請(qǐng)修改該方法使之不返回實(shí)際對(duì)象而是返回它的副本或克隆。要改正清單 14 中的代碼,請(qǐng)讓它返回 Exposed 對(duì)象的副本,如清單 15 中所示:
清單 15. 返回可變對(duì)象的副本
public Exposed getExposedObj(){
return new Exposed(exposedObj.getId(),exposedObj.getName());
}
或者,您的代碼也可以返回 Exposed 對(duì)象的克隆。
檢查本機(jī)方法
本機(jī)方法是一種 Java 方法,其實(shí)現(xiàn)是用另一種編程語(yǔ)言編寫的,如 C 或 C++。有些開發(fā)人員實(shí)現(xiàn)本機(jī)方法,這是因?yàn)?Java 語(yǔ)言即使使用即時(shí)(just-in-time)編譯器也比許多編譯過(guò)的語(yǔ)言要慢。其它人需要使用本機(jī)代碼是為了在 JVM 以外實(shí)現(xiàn)特定于平臺(tái)的功能。
影響
使用本機(jī)代碼時(shí),請(qǐng)小心,因?yàn)閷?duì)這些代碼進(jìn)行驗(yàn)證是不可能的,而且本機(jī)代碼可能潛在地允許 applet 繞過(guò)通常的安全性管理器(Security Manager)和 Java 對(duì)設(shè)備訪問(wèn)的控制。
建議
如果非得使用本機(jī)方法,那么請(qǐng)檢查這些方法以確定:
它們返回什么
它們獲取什么作為參數(shù)
它們是否繞過(guò)安全性檢查
它們是否是 public、private 等等
它們是否含有繞過(guò)包邊界從而繞過(guò)包保護(hù)的方法調(diào)用
結(jié)束語(yǔ)
編寫安全 Java 代碼是十分困難的,但本文描述了一些可行的實(shí)踐來(lái)幫您編寫安全 Java 代碼。這些建議并不能解決您的所有安全性問(wèn)題,但它們將減少暴露數(shù)目。最佳軟件安全性實(shí)踐可以幫助確保軟件正常運(yùn)行。安全至關(guān)重要和高可靠系統(tǒng)設(shè)計(jì)者總是花費(fèi)大量精力來(lái)分析和跟蹤軟件行為。只有通過(guò)將安全性作為至關(guān)緊要的系統(tǒng)特性來(lái)對(duì)待 — 并且從一開始就將它構(gòu)建到應(yīng)用程序中,我們才可以避免亡羊補(bǔ)牢似的、修修補(bǔ)補(bǔ)的安全性方法。
參考資料
請(qǐng)通過(guò)單擊文章頂部或底部的討論來(lái)參加本文的論壇。
了解關(guān)于 Java 安全性 API 的更多知識(shí)。
developerWorks 安全專題上通常含有有關(guān)計(jì)算機(jī)安全性的優(yōu)秀資源。
Larry Koved、 Anthony J. Nadalin、Don Neal 和 Tim Lawson 合作編寫的 “The evolution of Java security”(developerWorks,1998 年)對(duì) Java 語(yǔ)言的安全性模型早期開發(fā)進(jìn)行了深入探討。
Sing Li 在他的 Java 安全性系列文章(由兩部分組成的)(developerWorks, 2001 年 2 月)中向開發(fā)人員顯示:盡管社區(qū)可能不得不重新考慮 Java 2 中的安全性設(shè)計(jì),還是出現(xiàn)了只對(duì)開發(fā)人員有幫助,可以滿足他們的需求的一致的進(jìn)展:
第一部分
第二部分
John Viega、Tom Mutdosch、 Gary McGraw 和 Ed Felten 合著的 “Statically scanning Java code for security vulnerabilities” (IEEE Software,2000 年 9 月)介紹了一種 Java 工具,可以使用該工具來(lái)檢查您的 Java 代碼中的安全性漏洞。
G. McGraw 和 E. Felten 合作編寫的 Securing Java: Getting Down to Business with Mobile Code(John Wiley 和 Sons,1998 年)深入涵蓋了 Java 安全性。(文檔是 PDF 格式的。)
定期檢查 IBM 研究 Java 安全頁(yè)面以便 IBM 在安全性領(lǐng)域的創(chuàng)新有重要發(fā)展時(shí)能夠跟蹤這一創(chuàng)新。
如果您的 Java 代碼運(yùn)行在 S/390 系統(tǒng)上,那么您將需要查閱 S/390 Java 安全頁(yè)面以獲取額外的信息。
關(guān)于作者
Bijaya Nanda Sahu 是就職于印度 IBM Global Services 的軟件工程師。他從事過(guò)各種因特網(wǎng)技術(shù)和框架(J2EE、WSBCC、JADE)、 WebSphere 相關(guān)技術(shù)、UML 和 OOAD 方面的工作。目前,他從事因特網(wǎng)銀行安全性問(wèn)題方面的工作,重點(diǎn)在 WebSphere Application Server 和 Portal Server 上??梢酝ㄟ^(guò) bijaya.sahu@in.ibm.com 和他聯(lián)系
以下從技術(shù)角度就常見(jiàn)的保護(hù)措施 和常用工具來(lái)看看如何有效保護(hù)java代碼:1. 將java包裝成exe 特點(diǎn):將jar包裝成可執(zhí)行文件,便于使用,但對(duì)java程序沒(méi)有任何保護(hù)。不要以為生成了exe就和普通可執(zhí)行文件效果一樣了。這些包裝成exe的程序運(yùn)行時(shí)都會(huì)將jar文件釋放到臨時(shí)目錄,很容易獲取。常用的工具有exe4j、jsmooth、NativeJ等等。jsmooth生成的exe運(yùn)行時(shí)臨時(shí)目錄在exe所在目錄中或是用戶臨時(shí)目錄 中;exe4j生成的exe運(yùn)行時(shí)臨時(shí)目錄在用戶臨時(shí)目錄中;NativeJ生成的exe直接用winrar打開,然后用zip格式修復(fù)成一個(gè)jar文件,就得到了原文件。如果只是為了使用和發(fā)布方便,不需要保護(hù)java代碼,使用這些工具是很好的選擇。2. java混淆器特點(diǎn):使用一種或多種處理方式將class文件、java源代碼進(jìn)行混淆處理后生成新的class,使混淆后的代碼不易被反編譯,而反編譯后的代碼難以閱 讀和理解。這類混淆器工具很多,而且也很有成效。缺點(diǎn):雖然混淆的代碼反編譯后不易讀懂,但對(duì)于有經(jīng)驗(yàn)的人或是多花些時(shí)間,還是能找到或計(jì)算出你代碼中隱藏的敏感內(nèi)容,而且在很多應(yīng)用中不是全部代碼都能混淆的,往往一些關(guān)鍵的庫(kù)、類名、方法名、變量名等因使用要求的限制反而還不能混淆。3. 隔離java程序到服務(wù)端特點(diǎn):把java程序放到服務(wù)端,讓用戶不能訪問(wèn)到class文件和相關(guān)配套文件,客戶端只通過(guò)接口訪問(wèn)。這種方式在客戶/服務(wù)模式的應(yīng)用中能較好地保護(hù)java代碼。缺點(diǎn)是:必須是客戶/服務(wù)模式,這種特點(diǎn)限制了此種方式的使用范圍;客戶端因?yàn)檫壿嫷谋┞妒冀K是較為薄弱的環(huán)節(jié),所以訪問(wèn)接口時(shí)一般都需要安全性認(rèn)證。4. java加密保護(hù)特點(diǎn):自定義ClassLoader,將class文件和相關(guān)文件加密,運(yùn)行時(shí)由此ClassLoader解密相關(guān)文件并裝載類,要起到保護(hù)作用必須自定 義本地代碼執(zhí)行器將自定義ClassLoader和加密解密的相關(guān)類和配套文件也保護(hù)起來(lái)。此種方式能很有效地保護(hù)java代碼。缺點(diǎn):可以通過(guò)替換JRE包中與類裝載相關(guān)的java類或虛擬機(jī)動(dòng)態(tài)庫(kù)截獲java字節(jié)碼。 jar2exe屬于這類工具。5. 提前編譯技術(shù)(AOT) 特點(diǎn):將java代碼靜態(tài)編譯成本地機(jī)器碼,脫離通用JRE。此種方式能夠非常有效地保護(hù)java代碼,且程序啟動(dòng)比通用JVM快一點(diǎn)。具有代表性的是GNU的gcj,可以做到對(duì)java代碼完全提前編譯,但gcj存在諸多局限性,如:對(duì)JRE 5不能完整支持、不支持JRE 6及以后的版本。由于java平臺(tái)的復(fù)雜性,做到能及時(shí)支持最新java版本和JRE的完全提前編譯是非常困難的,所以這類工具往往采取靈活方式,該用即時(shí)編譯的地方還是 要用,成為提前編譯和即時(shí)編譯的混合體。缺點(diǎn):由于與通用JRE的差異和java運(yùn)用中的復(fù)雜性,并非java程序中的所有jar都能得到完全的保護(hù);只能使用此種工具提供的一個(gè)運(yùn)行環(huán)境,如果工具更新滯后或你需要特定版本的JRE,有可能得不到此種工具的支持。 Excelsior JET屬于這類工具。6. 使用jni方式保護(hù)特點(diǎn):將敏感的方法和數(shù)據(jù)通過(guò)jni方式處理。此種方式和“隔離java程序到服務(wù)端”有些類似,可以看作把需要保護(hù)的代碼和數(shù)據(jù)“隔離”到動(dòng)態(tài)庫(kù)中,不同的是可以在單機(jī)程序中運(yùn)用。缺點(diǎn)和上述“隔離java程序到服務(wù)端”類似。7. 不脫離JRE的綜合方式保護(hù)特點(diǎn):非提前編譯,不脫離JRE,采用多種軟保護(hù)方式,從多方面防止java程序被竊取。此種方式由于采取了多種保護(hù)措施,比如自定義執(zhí)行器和裝載器、加密、JNI、安全性檢測(cè)、生成可執(zhí)行文件等等,使保護(hù)力度大大增強(qiáng),同樣能夠非常有效地保護(hù)java代碼。缺點(diǎn):由于jar文件存在方式的改變和java運(yùn)用中的復(fù)雜性,并非java程序中的所有jar都能得到完全的保護(hù);很有可能并不支持所有的JRE版本。 JXMaker屬于此類工具。8. 用加密鎖硬件保護(hù)特點(diǎn):使用與硬件相關(guān)的專用程序?qū)ava虛擬機(jī)啟動(dòng)程序加殼,將虛擬機(jī)配套文件和java程序加密,啟動(dòng)的是加殼程序,由加殼程序建立一個(gè)與硬件相關(guān)的 受保護(hù)的運(yùn)行環(huán)境,為了加強(qiáng)安全性可以和加密鎖內(nèi)植入的程序互動(dòng)。此種方式與以上“不脫離JRE的綜合方式保護(hù)”相似,只是使用了專用硬件設(shè)備,也能很好地保護(hù)java代碼。缺點(diǎn):有人認(rèn)為加密鎖用戶使用上不太方便,且每個(gè)安裝需要附帶一個(gè)。從以上描述中我們可以看出:1. 各種保護(hù)方式都有其優(yōu)缺點(diǎn),應(yīng)根據(jù)實(shí)際選用2. 要更好地保護(hù)java代碼應(yīng)該使用綜合的保護(hù)措施3. 單機(jī)環(huán)境中要真正有效保護(hù)java代碼,必須要有本地代碼程序配合當(dāng)然,安全都是相對(duì)的,一方面看你的保護(hù)措施和使用的工具能達(dá)到的程度,一方面看黑客的意愿和能力,不能只從技術(shù)上保護(hù)知識(shí)產(chǎn)權(quán)??傊?,在java 代碼保護(hù)方面可以采取各種可能的方式,不可拘泥于那些條條框框。
網(wǎng)站標(biāo)題:java源代碼安全管理,java安全編程
標(biāo)題URL:http://jinyejixie.com/article14/dsseede.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計(jì)、小程序開發(fā)、電子商務(wù)、虛擬主機(jī)、網(wǎng)站維護(hù)、域名注冊(cè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
網(wǎng)頁(yè)設(shè)計(jì)公司知識(shí)