⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 肖俊.java.txt

📁 ava加密扩展即Java Cryptography Extension
💻 TXT
字号:
                                     加密与解密
Java加密扩展即Java Cryptography Extension,简称JCE。它是Sun的加密服务软件,包含了加密和密匙生成功能。JCE是JCA(Java Cryptography Architecture)的一种扩展。 

JCE没有规定具体的加密算法,但提供了一个框架,加密算法的具体实现可以作为服务提供者加入。除了JCE框架之外,JCE软件包还包含了SunJCE服务提供者,其中包括许多有用的加密算法,比如DES(Data Encryption Standard)和Blowfish。 

为简单计,在本文中我们将用DES算法加密和解密字节码。下面是用JCE加密和解密数据必须遵循的基本步骤: 

步骤1:生成一个安全密匙。在加密或解密任何数据之前需要有一个密匙。密匙是随同被加密的应用一起发布的一小段数据,Listing 3显示了如何生成一个密匙。 【Listing 3:生成一个密匙】 

  // DES算法要求有一个可信任的随机数源 
  SecureRandom sr = new SecureRandom(); 

  // 为我们选择的DES算法生成一个KeyGenerator对象 
  KeyGenerator kg = KeyGenerator.getInstance( "DES" ); 
  kg.init( sr ); 

  // 生成密匙 
  SecretKey key = kg.generateKey(); 

  // 获取密匙数据 
  byte rawKeyData[] = key.getEncoded(); 

  /* 接下来就可以用密匙进行加密或解密,或者把它保存 
     为文件供以后使用 */ 
  doSomething( rawKeyData ); 


  

步骤2:加密数据。得到密匙之后,接下来就可以用它加密数据。除了解密的ClassLoader之外,一般还要有一个加密待发布应用的独立程序(见Listing 4)。 【Listing 4:用密匙加密原始数据】 

    // DES算法要求有一个可信任的随机数源 
    SecureRandom sr = new SecureRandom(); 

    byte rawKeyData[] = /* 用某种方法获得密匙数据 */; 

    // 从原始密匙数据创建DESKeySpec对象 
    DESKeySpec dks = new DESKeySpec( rawKeyData ); 

    // 创建一个密匙工厂,然后用它把DESKeySpec转换成 
    // 一个SecretKey对象 
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance( "DES" ); 
    SecretKey key = keyFactory.generateSecret( dks ); 

    // Cipher对象实际完成加密操作 
    Cipher cipher = Cipher.getInstance( "DES" ); 

    // 用密匙初始化Cipher对象 
    cipher.init( Cipher.ENCRYPT_MODE, key, sr ); 

    // 现在,获取数据并加密 
    byte data[] = /* 用某种方法获取数据 */ 

    // 正式执行加密操作 
    byte encryptedData[] = cipher.doFinal( data ); 

    // 进一步处理加密后的数据 
    doSomething( encryptedData ); 

  

步骤3:解密数据。运行经过加密的应用时,ClassLoader分析并解密类文件。操作步骤如Listing 5所示。 【Listing 5:用密匙解密数据】 

    // DES算法要求有一个可信任的随机数源 
    SecureRandom sr = new SecureRandom(); 

    byte rawKeyData[] = /* 用某种方法获取原始密匙数据 */; 

    // 从原始密匙数据创建一个DESKeySpec对象 
    DESKeySpec dks = new DESKeySpec( rawKeyData ); 

    // 创建一个密匙工厂,然后用它把DESKeySpec对象转换成 
    // 一个SecretKey对象 
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance( "DES" ); 
    SecretKey key = keyFactory.generateSecret( dks ); 

    // Cipher对象实际完成解密操作 
    Cipher cipher = Cipher.getInstance( "DES" ); 

    // 用密匙初始化Cipher对象 
    cipher.init( Cipher.DECRYPT_MODE, key, sr ); 

    // 现在,获取数据并解密 
    byte encryptedData[] = /* 获得经过加密的数据 */ 

    // 正式执行解密操作 
    byte decryptedData[] = cipher.doFinal( encryptedData ); 

    // 进一步处理解密后的数据 
    doSomething( decryptedData ); 

  

四、应用实例 
前面介绍了如何加密和解密数据。要部署一个经过加密的应用,步骤如下: 

步骤1:创建应用。我们的例子包含一个App主类,两个辅助类(分别称为Foo和Bar)。这个应用没有什么实际功用,但只要我们能够加密这个应用,加密其他应用也就不在话下。  
步骤2:生成一个安全密匙。在命令行,利用GenerateKey工具(参见GenerateKey.java)把密匙写入一个文件: % java GenerateKey key.data 

  

步骤3:加密应用。在命令行,利用EncryptClasses工具(参见EncryptClasses.java)加密应用的类: % java EncryptClasses key.data App.class Foo.class Bar.class 

  
该命令把每一个.class文件替换成它们各自的加密版本。  
步骤4:运行经过加密的应用。用户通过一个DecryptStart程序运行经过加密的应用。DecryptStart程序如Listing 6所示。 【Listing 6:DecryptStart.java,启动被加密应用的程序】 

import java.io.*; 
import java.security.*; 
import java.lang.reflect.*; 
import javax.crypto.*; 
import javax.crypto.spec.*; 

public class DecryptStart extends ClassLoader 
{ 
  // 这些对象在构造函数中设置, 
  // 以后loadClass()方法将利用它们解密类 
  private SecretKey key; 
  private Cipher cipher; 

  // 构造函数:设置解密所需要的对象 
  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过程:我们要在这里读入密匙,创建DecryptStart的 
  // 实例,它就是我们的定制ClassLoader。 
  // 设置好ClassLoader以后,我们用它装入应用实例, 
  // 最后,我们通过Java Reflection API调用应用实例的main方法 
  static public void main( String args[] ) throws Exception { 
    String keyFilename = args[0]; 
    String appName = args[1]; 

     // 这些是传递给应用本身的参数 
    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 ); 

    // 创建解密的ClassLoader 
    DecryptStart dr = new DecryptStart( key ); 

    // 创建应用主类的一个实例 
    // 通过ClassLoader装入它 
    System.err.println( "[DecryptStart: loading "+appName+"]" ); 
    Class clasz = dr.loadClass( appName ); 

    // 最后,通过Reflection API调用应用实例 
    // 的main()方法 

    // 获取一个对main()的引用 
    String proto[] = new String[1]; 
    Class mainArgs[] = { (new String[1]).getClass() }; 
    Method main = clasz.getMethod( "main", mainArgs ); 

    // 创建一个包含main()方法参数的数组 
    Object argsArray[] = { realArgs }; 
    System.err.println( "[DecryptStart: running "+appName+".main()]" ); 

    // 调用main() 
    main.invoke( null, argsArray ); 
  } 

  public Class loadClass( String name, boolean resolve ) 
      throws ClassNotFoundException { 
    try { 
      // 我们要创建的Class对象 
      Class clasz = null; 

      // 必需的步骤1:如果类已经在系统缓冲之中 
      // 我们不必再次装入它 
      clasz = findLoadedClass( name ); 

      if (clasz != null) 
        return clasz; 

      // 下面是定制部分 
      try { 
        // 读取经过加密的类文件 
        byte classData[] = Util.readFile( name+".class" ); 

        if (classData != null) { 
          // 解密... 
          byte decryptedClassData[] = cipher.doFinal( classData ); 

          // ... 再把它转换成一个类 
          clasz = defineClass( name, decryptedClassData, 
            0, decryptedClassData.length ); 
          System.err.println( "[DecryptStart: decrypting class "+name+"]" ); 
        } 
      } catch( FileNotFoundException fnfe ) { 
      } 

      // 必需的步骤2:如果上面没有成功 
      // 我们尝试用默认的ClassLoader装入它 
      if (clasz == null) 
        clasz = findSystemClass( name ); 

      // 必需的步骤3:如有必要,则装入相关的类 
      if (resolve && clasz != null) 
        resolveClass( clasz ); 

      // 把类返回给调用者 
      return clasz; 
    } catch( IOException ie ) { 
      throw new ClassNotFoundException( ie.toString() 
); 
    } catch( GeneralSecurityException gse ) { 
      throw new ClassNotFoundException( gse.toString() 
); 
    } 
  } 
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -