DES加密问题

huxiuliang 2008-04-02 10:36:31
源代码为
package DES;

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 {

args = new String[] { "key.data", "DES.test.App" };
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());
}
}
}

////////////////////////////////////////////////////////////////////////////////////
package DES;

//Util.java

import java.io.*;

public class Util
{
// 把文件读入byte数组
static public byte[] readFile( String filename ) throws IOException {
File file = new File( filename );
long len = file.length();
byte data[] = new byte[(int)len];
FileInputStream fin = new FileInputStream( file );
int r = fin.read( data );
if (r != len)
throw new IOException( "Only read "+r+" of "+len+" for "+file );
fin.close();
return data;
}

// 把byte数组写出到文件
static public void writeFile( String filename, byte data[] )
throws IOException {
FileOutputStream fout = new FileOutputStream( filename );
fout.write( data );
fout.close();
}


}


////////////////////////////////////


运行DecryptStart.class是就会抛出异常
请教解决方法
[DecryptStart: creating cipher]
Exception in thread "main" java.lang.ClassFormatError: Incompatible magic value -1320247599 in class file DES/test/App
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.findSystemClass(Unknown Source)
at DES.DecryptStart.loadClass(DecryptStart.java:103)
at java.lang.ClassLoader.loadClass(Unknown Source)
at DES.DecryptStart.main(DecryptStart.java:54)

...全文
261 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
bforget 2011-08-05
  • 打赏
  • 举报
回复
学习了...
以梦为马 2008-10-18
  • 打赏
  • 举报
回复
mark
bzzhy 2008-10-10
  • 打赏
  • 举报
回复
Util.readFile 方法在什么那个类中,我找了好长时间了也找不见
zjhlht 2008-04-03
  • 打赏
  • 举报
回复
研究~~~~~
Cspider588 2008-04-03
  • 打赏
  • 举报
回复
楼主的错误在于:
byte classData[] = Util.readFile(name + ".class");

因为name的格式是DES.test.App,在Util.readFile中(FileInputStream fin = new FileInputStream(file);)会抛出异常FileNotFoundException,
楼主你在外层捕获了FileNotFoundException,但是没有任何处理,于是代码继续执行,到clasz = findSystemClass(name);这一步的时候,就会抛出楼主打出的异常,因为此时的class文件是经过加密的,系统并不认识这样子的class。

这个异常是由于代码有多处不够严谨造成的,导致我们不能一下子找出真正出问题的地方。

实际上楼主你只要把byte classData[] = Util.readFile(name + ".class");这句话改成下面:
byte classData[] = Util.readFile(name.replaceAll("[.]", "/") + ".class");
就可以了。
贝壳鱼 2008-04-03
  • 打赏
  • 举报
回复
类格式错误:不兼容的不可思议的值 -1320247599 在类文件 DES/test/App

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧