<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    JAVA加密解密---自定義類加載器應用

    Posted on 2007-04-22 11:09 久城 閱讀(4983) 評論(5)  編輯  收藏 所屬分類: Java理解筆記
    最近在研究JAVA CLASS LOADING技術,已實現了一個自定義的加載器。對目前自定義加載器的應用,還在探討中。下面是自定義的CLASSLOADER在JAVA加密解密方面的一些研究。

    JAVA安全

    JAVA是解釋執行的語言,對于不同的操作平臺都有相應的JVM對字節碼文件進行解釋執行。而這個字節碼文件,也就是我們平時所看到的每一個.class文件。

    這是我們大家都知道的常識,也就是由.java文件,經過編譯器編譯,變成JVM所能解釋的.class文件。

    而這個過程,在現在公開的網絡技術中,利用一個反編譯器,任何人都可以很容易的獲取它的源文件。這對于很多人來說是不希望看到的。

    對于加密解密技術,我懂的不多,有些可以利用某種技術“模糊”JAVA類文件。這樣能夠使反編譯的難度增加。但估計反編譯器的技術水平也在不斷提升,導致這種方法層層受阻。另外還有很多其他的技術也可以實現對JAVA文件的加密解密。我現在所想要研究的,就是其中的一種。

    JAVA的靈活性使反編譯變得容易,同時,也讓我們的加密解密的方法變得靈活。

    利用自定義的CLASSLOADER

    參照:http://m.tkk7.com/realsmy/archive/2007/04/18/111582.html

    JAVA中的每一個類都是通過類加載器加載到內存中的。對于類加載器的工作流程如下表示:
    1.searchfile()
    找到我所要加載的類文件。(拋除JAR包的概念,現在只是要加載一個.class文件)
    2.loadDataClass()
    讀取這個類文件的字節碼。
    3.difineClass()
    加載類文件。(加載的過程其實很復雜,我們現在先不研究它。)

    從這個過程中我們能很清楚的發現,自定義的類加載能夠很輕松的控制每個類文件的加載過程。這樣在第二步(loadDataClass)和第三步(difineClass)之間,我們將會有自己的空間靈活的控制這個過程。

    我們加密解密的技術就應用到這里。

    加密解密

    JAVA加密解密的技術有很多。JAVA自己提供了良好的類庫對各種算法進行支持。對于采用哪種算法,網絡上說法不一,自己去GOOGLE一下吧。

    下面用DES對稱加密算法(設定一個密鑰,然后對所有的數據進行加密)來簡單舉個例子。

    首先,生成一個密鑰KEY。
    我把它保存到key.txt中。這個文件就象是一把鑰匙。誰擁有它,誰就能解開我們的類文件。代碼參考如下:
    package com.neusoft.jiami;

    import java.io.File;
    import java.io.FileOutputStream;
    import java.security.SecureRandom;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;

    class Key {

        
    private String keyName;

        
    public Key(String keyName) {
            
    this.keyName = keyName;
        }


        
    public void createKey(String keyName) throws Exception {

            
    // 創建一個可信任的隨機數源,DES算法需要
            SecureRandom sr = new SecureRandom();
            
    // 用DES算法創建一個KeyGenerator對象
            KeyGenerator kg = KeyGenerator.getInstance("DES");
            
    // 初始化此密鑰生成器,使其具有確定的密鑰長度
            kg.init(sr);
            
    // 生成密匙
            SecretKey key = kg.generateKey();
            
    // 獲取密鑰數據
            byte rawKeyData[] = key.getEncoded();
            
    // 將獲取到密鑰數據保存到文件中,待解密時使用
            FileOutputStream fo = new FileOutputStream(new File(keyName));
            fo.write(rawKeyData);
        }


        
    public static void main(String args[]) {
            
    try {
                
    new Key("key.txt");
            }
     catch (Exception e) {
                e.printStackTrace();
            }


        }

    }

    第二步,對我們所要進行加密的類文件進行加密。

    比如我有一個DigestPass類,已經被正常編譯好生成DigestPass.class文件。此時,這個類文件是任何人都可以用的。因為系統的類加載器可以自動的加載它。那么下一步,我們要做的就是把這個類文件加密。使系統的類加載器無法讀取到正確的字節碼文件。參考代碼如下:
    package com.neusoft.jiami;

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.security.SecureRandom;

    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.DESKeySpec;

    public class JiaMi {

        
    public static void main(String[] args) throws Exception {

            
    // DES算法要求有一個可信任的隨機數源
            SecureRandom sr = new SecureRandom();
            
    // 獲得密匙數據
            FileInputStream fi = new FileInputStream(new File("key.txt"));
            
    byte rawKeyData[] = new byte[fi.available()];
            fi.read(rawKeyData);
            fi.close();
            
    // 從原始密匙數據創建DESKeySpec對象
            DESKeySpec dks = new DESKeySpec(rawKeyData);
            
    // 創建一個密匙工廠,然后用它把DESKeySpec轉換成一個SecretKey對象
            SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(dks);
            
    // Cipher對象實際完成加密操作
            Cipher cipher = Cipher.getInstance("DES");
            
    // 用密匙初始化Cipher對象
            cipher.init(Cipher.ENCRYPT_MODE, key, sr);
            
    // 現在,獲取要加密的文件數據
            FileInputStream fi2 = new FileInputStream(new File("DigestPass.class"));
            
    byte data[] = new byte[fi2.available()];
            fi2.read(data);
            fi2.close();
            
    // 正式執行加密操作
            byte encryptedData[] = cipher.doFinal(data);
            
    // 用加密后的數據覆蓋原文件
            FileOutputStream fo = new FileOutputStream(new File("DigestPass.class"));
            fo.write(encryptedData);
            fo.close();
        }

    }


    第三步,用自定義的CLASSLOADER進行加載。參考代碼如下:
    package com.neusoft.jiami;

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.security.SecureRandom;

    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.DESKeySpec;
    import com.neusoft.classloader.MyClassLoader;

    public class JieMi {

        
    public static void main(String[] args) throws Exception {

            
    // DES算法要求有一個可信任的隨機數源
            SecureRandom sr = new SecureRandom();
            
    // 獲得密匙數據
            FileInputStream fi = new FileInputStream(new File("key.txt"));
            
    byte rawKeyData[] = new byte[fi.available()];// = new byte[5];
            fi.read(rawKeyData);
            fi.close();
            
    // 從原始密匙數據創建一個DESKeySpec對象
            DESKeySpec dks = new DESKeySpec(rawKeyData);
            
    // 創建一個密匙工廠,然后用它把DESKeySpec對象轉換成一個SecretKey對象
            SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(dks);
            
    // Cipher對象實際完成解密操作
            Cipher cipher = Cipher.getInstance("DES");
            
    // 用密匙初始化Cipher對象
            cipher.init(Cipher.DECRYPT_MODE, key, sr);
            
    // 現在,獲取數據并解密
            FileInputStream fi2 = new FileInputStream(new File("DigestPass.class"));
            
    byte encryptedData[] = new byte[fi2.available()];
            fi2.read(encryptedData);
            fi2.close();
            
    // 正式執行解密操作
            byte decryptedData[] = cipher.doFinal(encryptedData);
            
    // 這時把數據還原成原有的類文件
            
    // FileOutputStream fo = new FileOutputStream(new
            
    // File("DigestPass.class"));
            
    // fo.write(decryptedData);
            
    // 用解密后的數據加載類并應用
            MyClassloader mcl = new MyClassloader("E:/");
            Class cl 
    = mcl.loadClass(decryptedData, "com.neusoft.jiami.DigestPass");
            DigestPass dp 
    = cl.newInstance();
        }

    }

    這樣,我們就完成了類的加密解密。這個過程留給我們修改的空間還很多。我也在理解過程中。

    總結

    自定義的類加載器能夠靈活的控制類的加載過程。從而可以實現一些我們所要的功能。

    但是,即使是這樣的加密技術,對于某些高手來說,依然是脆弱的。我們所需要做的就是,理解這其中的過程,掌握這樣的技術,最終能夠應用到我們自己的實際項目中來。

    歡迎來訪!^.^!
    本BLOG僅用于個人學習交流!
    目的在于記錄個人成長.
    所有文字均屬于個人理解.
    如有錯誤,望多多指教!不勝感激!

    Feedback

    # re: JAVA加密解密---自定義類加載器應用  回復  更多評論   

    2007-04-22 13:06 by kurt
    DES是對稱加密算法不是公鑰加密算法

    # re: JAVA加密解密---自定義類加載器應用  回復  更多評論   

    2007-04-22 13:14 by 久城
    @kurt
    多謝指點,已經修改。

    # re: JAVA加密解密---自定義類加載器應用  回復  更多評論   

    2007-04-23 15:07 by 交口稱贊
    類加載器本身怎么辦


    別人反編譯你的類加載器,
    然后用你的類加載器去解密。。。

    你難道還弄個加載器的加載器?

    # re: JAVA加密解密---自定義類加載器應用  回復  更多評論   

    2007-04-23 18:37 by 久城
    @交口稱贊
    謝謝,我是這樣想的,這個方法可以使用于網絡加載類。密鑰文件保存在客戶端與服務器端,自定義的類加載器保存在客戶端。通過網絡傳輸的只有加密過的字節碼。類加載器只在本機上運行。這樣即使被網絡截取到字節碼文件,也很難被反編譯。
    但是如果攻擊者能夠訪問到我的客戶端,并且取得我的類加載器的話。那我這樣加密就無效了。
    至于如何對類加載器加密?嘿嘿,我在這方面是菜菜!學習。

    # re: JAVA加密解密---自定義類加載器應用  回復  更多評論   

    2007-04-25 18:08 by liji
    hello kitty! :D

    Copyright © 久城

    主站蜘蛛池模板: 午夜在线亚洲男人午在线| 久久美女网站免费| 在线观看免费人成视频色| 久久久亚洲欧洲日产国码是AV| 最近中文字幕免费大全| 久久久久亚洲AV成人网| 久久99久久成人免费播放| 在线A亚洲老鸭窝天堂| 久久久精品视频免费观看| 国产午夜亚洲精品国产成人小说| 免费国产在线精品一区| 在线亚洲人成电影网站色www| 女人隐私秘视频黄www免费| 久久亚洲国产视频| 国产片AV片永久免费观看| 久久亚洲AV成人无码| 日本成年免费网站| 亚洲国产精品无码中文lv| 波多野结衣免费视频观看| 一二三区免费视频| 亚洲AV无码精品色午夜在线观看| 久9热免费精品视频在线观看| 亚洲国产综合精品| 免费无码又爽又刺激高潮| 一级做性色a爰片久久毛片免费| 亚洲乳大丰满中文字幕| **一级毛片免费完整视| 自拍偷区亚洲国内自拍| 亚洲AV中文无码乱人伦在线视色| 青柠影视在线观看免费| 亚洲制服丝袜第一页| 免费A级毛片在线播放不收费| 免费无码一区二区三区蜜桃| 亚洲综合色丁香麻豆| 国产精品黄页在线播放免费| 中文字幕av免费专区| 亚洲午夜国产精品无卡| 亚洲日本在线观看视频| 0588影视手机免费看片| 亚洲国产人成在线观看69网站| 亚洲精品视频在线观看免费|