如何有效防止Java程序源碼被人偷窺?(3)_Mssql數(shù)據(jù)庫(kù)教程
推薦:如何快速生成100萬(wàn)不重復(fù)的8位編號(hào)最近在論壇看到有人問(wèn),如何快速生成100萬(wàn)不重復(fù)的8位編號(hào),對(duì)于這個(gè)問(wèn)題,有幾點(diǎn)是需要注意的: 1. 如何生成8位隨機(jī)數(shù),生成的數(shù)越隨機(jī),重復(fù)的可能性當(dāng)然越小 2. 控制不重復(fù)
四、應(yīng)用實(shí)例
前面介紹了如何加密和解密數(shù)據(jù)。要部署一個(gè)經(jīng)過(guò)加密的應(yīng)用,步驟如下:
步驟1:創(chuàng)建應(yīng)用。我們的例子包含一個(gè)App主類,兩個(gè)輔助類(分別稱為Foo和Bar)。這個(gè)應(yīng)用沒(méi)有什么實(shí)際功用,但只要我們能夠加密這個(gè)應(yīng)用,加密其他應(yīng)用也就不在話下。
步驟2:生成一個(gè)安全密匙。在命令行,利用GenerateKey工具(參見(jiàn)GenerateKey.java)把密匙寫(xiě)入一個(gè)文件: % java GenerateKey key.data
步驟3:加密應(yīng)用。在命令行,利用EncryptClasses工具(參見(jiàn)EncryptClasses.java)加密應(yīng)用的類: % java EncryptClasses key.data App.class Foo.class Bar.class
該命令把每一個(gè).class文件替換成它們各自的加密版本。
步驟4:運(yùn)行經(jīng)過(guò)加密的應(yīng)用。用戶通過(guò)一個(gè)DecryptStart程序運(yùn)行經(jīng)過(guò)加密的應(yīng)用。DecryptStart程序如Listing 6所示。 【Listing 6:DecryptStart.java,啟動(dòng)被加密應(yīng)用的程序】
| 以下為引用的內(nèi)容: import java.io.*; import java.security.*; import java.lang.reflect.*; import javax.crypto.*; import javax.crypto.spec.*; public class DecryptStart extends ClassLoader { // 這些對(duì)象在構(gòu)造函數(shù)中設(shè)置, // 以后loadClass()方法將利用它們解密類 private SecretKey key; private Cipher cipher; // 構(gòu)造函數(shù):設(shè)置解密所需要的對(duì)象 public DecryptStart( SecretKey key ) throws GeneralSecurityException, IOException { this.key = key; String algorithm = "DES"; SecureRandom sr = new SecureRandom(); System.err.println( "[DecryptStart: creating cipher]" ); cipher = Cipher.getInstance( algorithm ); cipher.init( Cipher.DECRYPT_MODE, key, sr ); } // main過(guò)程:我們要在這里讀入密匙,創(chuàng)建DecryptStart的 // 實(shí)例,它就是我們的定制ClassLoader。 // 設(shè)置好ClassLoader以后,我們用它裝入應(yīng)用實(shí)例, // 最后,我們通過(guò)Java Reflection API調(diào)用應(yīng)用實(shí)例的main方法 static public void main( String args[] ) throws Exception { String keyFilename = args[0]; String appName = args[1]; // 這些是傳遞給應(yīng)用本身的參數(shù) String realArgs[] = new String[args.length-2]; System.arraycopy( args, 2, realArgs, 0, args.length-2 ); // 讀取密匙 System.err.println( "[DecryptStart: reading key]" ); byte rawKey[] = Util.readFile( keyFilename ); DESKeySpec dks = new DESKeySpec( rawKey ); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance( "DES" ); SecretKey key = keyFactory.generateSecret( dks ); // 創(chuàng)建解密的ClassLoader DecryptStart dr = new DecryptStart( key ); // 創(chuàng)建應(yīng)用主類的一個(gè)實(shí)例 // 通過(guò)ClassLoader裝入它 System.err.println( "[DecryptStart: loading " appName "]" ); Class clasz = dr.loadClass( appName ); // 最后,通過(guò)Reflection API調(diào)用應(yīng)用實(shí)例 // 的main()方法 // 獲取一個(gè)對(duì)main()的引用 String proto[] = new String[1]; Class mainArgs[] = { (new String[1]).getClass() }; Method main = clasz.getMethod( "main", mainArgs ); // 創(chuàng)建一個(gè)包含main()方法參數(shù)的數(shù)組 Object argsArray[] = { realArgs }; System.err.println( "[DecryptStart: running " appName ".main()]" ); // 調(diào)用main() main.invoke( null, argsArray ); } public Class loadClass( String name, boolean resolve ) throws ClassNotFoundException { try { // 我們要?jiǎng)?chuàng)建的Class對(duì)象 Class clasz = null; // 必需的步驟1:如果類已經(jīng)在系統(tǒng)緩沖之中 // 我們不必再次裝入它 clasz = findLoadedClass( name ); if (clasz != null) return clasz; // 下面是定制部分 try { // 讀取經(jīng)過(guò)加密的類文件 byte classData[] = Util.readFile( name ".class" ); if (classData != null) { // 解密... byte decryptedClassData[] = cipher.doFinal( classData ); // ... 再把它轉(zhuǎn)換成一個(gè)類 clasz = defineClass( name, decryptedClassData, 0, decryptedClassData.length ); System.err.println( "[DecryptStart: decrypting class " name "]" ); } } catch( FileNotFoundException fnfe ) // 必需的步驟2:如果上面沒(méi)有成功 // 我們嘗試用默認(rèn)的ClassLoader裝入它 if (clasz == null) clasz = findSystemClass( name ); // 必需的步驟3:如有必要,則裝入相關(guān)的類 if (resolve && clasz != null) resolveClass( clasz ); // 把類返回給調(diào)用者 return clasz; } catch( IOException ie ) { throw new ClassNotFoundException( ie.toString() ); } catch( GeneralSecurityException gse ) { throw new ClassNotFoundException( gse.toString() ); } } } |
對(duì)于未經(jīng)加密的應(yīng)用,正常執(zhí)行方式如下: % java App arg0 arg1 arg2
對(duì)于經(jīng)過(guò)加密的應(yīng)用,則相應(yīng)的運(yùn)行方式為: % java DecryptStart key.data App arg0 arg1 arg2
DecryptStart有兩個(gè)目的。一個(gè)DecryptStart的實(shí)例就是一個(gè)實(shí)施即時(shí)解密操作的定制ClassLoader;同時(shí),DecryptStart還包含一個(gè)main過(guò)程,它創(chuàng)建解密器實(shí)例并用它裝入和運(yùn)行應(yīng)用。示例應(yīng)用App的代碼包含在App.java、Foo.java和Bar.java內(nèi)。Util.java是一個(gè)文件I/O工具,本文示例多處用到了它。完整的代碼請(qǐng)從本文最后下載。
五、注意事項(xiàng)
我們看到,要在不修改源代碼的情況下加密一個(gè)Java應(yīng)用是很容易的。不過(guò),世上沒(méi)有完全安全的系統(tǒng)。本文的加密方式提供了一定程度的源代碼保護(hù),但對(duì)某些攻擊來(lái)說(shuō)它是脆弱的。
雖然應(yīng)用本身經(jīng)過(guò)了加密,但啟動(dòng)程序DecryptStart沒(méi)有加密。攻擊者可以反編譯啟動(dòng)程序并修改它,把解密后的類文件保存到磁盤(pán)。降低這種風(fēng)險(xiǎn)的辦法之一是對(duì)啟動(dòng)程序進(jìn)行高質(zhì)量的模糊處理�;蛘撸瑔�(dòng)程序也可以采用直接編譯成機(jī)器語(yǔ)言的代碼,使得啟動(dòng)程序具有傳統(tǒng)執(zhí)行文件格式的安全性。
另外還要記住的是,大多數(shù)JVM本身并不安全。狡猾的黑客可能會(huì)修改JVM,從ClassLoader之外獲取解密后的代碼并保存到磁盤(pán),從而繞過(guò)本文的加密技術(shù)。Java沒(méi)有為此提供真正有效的補(bǔ)救措施。
不過(guò)應(yīng)該指出的是,所有這些可能的攻擊都有一個(gè)前提,這就是攻擊者可以得到密匙。如果沒(méi)有密匙,應(yīng)用的安全性就完全取決于加密算法的安全性。雖然這種保護(hù)代碼的方法稱不上十全十美,但它仍不失為一種保護(hù)知識(shí)產(chǎn)權(quán)和敏感用戶數(shù)據(jù)的有效方案。
分享:四個(gè)語(yǔ)句幫你提高 SQL Server 的伸縮性本文講解如何使用LEFT JOIN、CROSS JOIN以及IDENTITY值的檢索,這些技術(shù)來(lái)提高基于SQL Server的應(yīng)用程序的性能或改善其可伸縮性。 你將遇到的現(xiàn)象:應(yīng)用程序中的SQL 查詢不能按照您想要的方式
- sql 語(yǔ)句練習(xí)與答案
- 深入C++ string.find()函數(shù)的用法總結(jié)
- SQL Server中刪除重復(fù)數(shù)據(jù)的幾個(gè)方法
- sql刪除重復(fù)數(shù)據(jù)的詳細(xì)方法
- SQL SERVER 2000安裝教程圖文詳解
- 使用sql server management studio 2008 無(wú)法查看數(shù)據(jù)庫(kù),提示 無(wú)法為該請(qǐng)求檢索數(shù)據(jù) 錯(cuò)誤916解決方法
- SQLServer日志清空語(yǔ)句(sql2000,sql2005,sql2008)
- Sql Server 2008完全卸載方法(其他版本類似)
- sql server 2008 不允許保存更改,您所做的更改要求刪除并重新創(chuàng)建以下表
- SQL Server 2008 清空刪除日志文件(瞬間日志變幾M)
- Win7系統(tǒng)安裝MySQL5.5.21圖解教程
- 將DataTable作為存儲(chǔ)過(guò)程參數(shù)的用法實(shí)例詳解
Mssql數(shù)據(jù)庫(kù)教程Rss訂閱編程教程搜索
Mssql數(shù)據(jù)庫(kù)教程推薦
- 解讀優(yōu)化SQL Server數(shù)據(jù)庫(kù)查詢方法
- 如何查看并導(dǎo)出數(shù)據(jù)表中字段的注釋信息
- 查詢表里有N組相同記錄的SQL語(yǔ)句
- MSSQL2005在networkservice權(quán)限運(yùn)行附加數(shù)據(jù)庫(kù)報(bào)(Microsoft SQL Server,錯(cuò)誤: 5120)
- SQL Server 2005通用分頁(yè)存儲(chǔ)過(guò)程及多表聯(lián)接應(yīng)用
- SQL Server 數(shù)據(jù)庫(kù)清除日志的方法
- 解讀SQL Server 2008可用性
- SQL Server 2008存儲(chǔ)結(jié)構(gòu)之GAM、SGAM介紹
- 談數(shù)據(jù)庫(kù)手邊系列:SQL Server數(shù)據(jù)表信息
- 解讀4個(gè)編寫(xiě)SQL語(yǔ)句需要注意的常識(shí)
猜你也喜歡看這些
- 如何用命令行進(jìn)入mysql具體操作步驟
- 基于一致性hash算法(consistent hashing)的使用詳解
- mysql 按照時(shí)間段來(lái)獲取數(shù)據(jù)的方法
- 解析mysql中:單表distinct、多表group by查詢?nèi)コ貜?fù)記錄
- MySQL筆記之修改表的實(shí)現(xiàn)方法
- MySQL筆記之別名的使用
- 解析SQL語(yǔ)句中Replace INTO與INSERT INTO的不同之處
- Ubuntu Server下MySql數(shù)據(jù)庫(kù)備份腳本代碼
- mysql中text與varchar與char的區(qū)別
- Mysql,phpmyadmin密碼忘了怎么辦
- 相關(guān)鏈接:
- 教程說(shuō)明:
Mssql數(shù)據(jù)庫(kù)教程-如何有效防止Java程序源碼被人偷窺?(3)
。