Dict.CN 在线词典, 英语学习, 在线翻译

都市淘沙者

荔枝FM Everyone can be host

统计

留言簿(23)

积分与排名

优秀学习网站

友情连接

阅读排行榜

评论排行榜

电子商务使用数据加密来保护数据库 (二)

电子商务使用数据加密来保护数据库 (二)
上篇讲解了一些理论上的内容,这次我们详细介绍一下例子:

例如,我们创建一个类DESUtil.java

按照上次讲的,我要首先要创建一个密钥,所以先增加一个方法,用来创建DES密钥。为了使用方便,我们暂时把所有的方法写成静态方法。
//filename是要保存的文件路径
public static void createKey(String filename) throws Exception{
//生成一个可信任的随机数源
SecureRandom sr = new SecureRandom();
//为我们选择的DES算法生成一个KeyGenerator对象
KeyGenerator kg = KeyGenerator.getInstance("DES");
kg.init(sr);
//生成密钥
Key key = kg.generateKey();
//将密钥数据保存为文件供以后使用
writeFile(key,filename); //稍候讲解
}

好了,我们可以通过上面的方法生成密钥了。
因为我们可能会在不同的地方调用加密或者解密的方法,所以我们必须把生成密钥的存储在一个文件中,推荐存储到应用的/WEB-INF/的某个目录下,因为那个目录只由自己的程序调用,不能通过URL访问,所以更安全。接下来我们要写两个方法,一个将密钥存储到文件,另一个则是在加密或者解密的方法中读出密钥进行加密或者解密。

//filename是密钥存储的路径,msg是我们用第一个方法生成的密钥
public static void writeFile(Key msg, String filePath) {
try {
File file = new File(filePath);
if (file.exists()) {
file.delete();
}
FileOutputStream wf = new FileOutputStream(file);
ObjectOutputStream out = new ObjectOutputStream(wf);
out.writeObject(msg);
out.close();
file = null;
wf = null;
} catch (IOException e) {
debug(e.getMessage());
}
}
//filename是密钥存储的路径
public static Key readFile(String filePath) {
Key key = null;
try {
File f = new File(filePath);
if (f.exists()) {
FileInputStream bw = new FileInputStream(f);
ObjectInputStream in = new ObjectInputStream(bw);
key = (Key)in.readObject();
in.close();
bw = null;
}
f = null;
} catch (Exception e) {
debug(e.getMessage());
}
return key;
}

这里我们直接把密钥对象整个存到了文件中,当然也可以用字节的方式存储,但是中间可以会有些小麻烦噢!

好了,现在密钥的问题也解决了,我们接下来的工作就是写加密和解决的方法了。

//str 要加密的字节数组
public static byte[] DataEncrypt(byte[] str,String filename) throws Exception{
//
SecretKey key = (SecretKey)readFile(filename);
//Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance("DES");
//用密钥初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, key);
//执行加密操作
byte[] encryptedData = cipher.doFinal(str);
//
return encryptedData;
}
//str 要解密的字节数组
public static byte[] DataDecrypt(byte[] str,String filename) throws Exception{
//
SecretKey key = (SecretKey)readFile(filename);
//Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance("DES");
//用密钥初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, key);
//执行加密操作
byte[] encryptedData = cipher.doFinal(str);
//
return encryptedData;
}


简单吧,我们已经成功的创建了DES加密,解密的类了。测试一下吧!

public static void main(String[] args) {
String filename = "c:/des.key";
String str = "0109103746028";
System.out.print("source="+str);
try {
DESUtil.createKey(filename);
//
byte[] enstr = DESUtil.DataEncrypt(str.getBytes(),filename);
str = new String(enstr);//加密后的字串
System.out.print("encrypt=" + str);
//
byte[] destr = DESUtil.DataDecrypt(str.getBytes(),filename);
str = new String(destr);//解密后的字串
System.out.print("decrypt=" + str);
} catch (Exception e) {
e.printStackTrace();
}
debug("ok");
}

如果没有定错的话,一定报错了: javax.crypto.BadPaddingException: Given final block not properly padded
怎么回事,都是按照你的写的,怎么会不对呢?仔细分析一下,不难发现,该异常是在解密的时候抛出的,加密的方法没有问题。

但是两个方法的唯一差别是Cipher对象的模式不一样,这就排除了程序写错的可能性。再看一下异常的揭示信息,大概的意思是:提供的字块不符合填补的。什么意思???原来在用DES加密的时候,最后一位长度不足64的,它会自动填补到64,那么在我们进行字节数组到字串的转化过程中,可以把它填补的不可见字符改变了,所以引发系统抛出异常。问题找到,怎么解决呢?大家还记得邮件传输通常会把一些信息编码保存,对了,就是Base64,那样保证了信息的完整性,所以我们就是利用一下下了。为了方便使用,我们再写一个新的方法封装一下原来的方法:
//
public static String DataEncrypt(String str){
String encrypt = null;
try{
byte[] ret = DataEncrypt(str.getBytes("UTF-8"),filename);
encrypt = new String(Base64.encode(ret),"UTF-8");
}catch(Exception e){
System.out.print(e);
encrypt = str;
}
return encrypt;
}
//
public static String DataDecrypt(String str){
String decrypt = null;
try{
byte[] ret =  DataDecrypt(Base64.decode(str.getBytes("UTF-8")),filename);
decrypt =  new String(ret,"UTF-8");
}catch(Exception e){
System.out.print(e);
decrypt = str;
}
return decrypt;
}

我们把方法的参数改成了字串,但是为什么要用UTF-8呢?不指定它的字节格式不行吗?大家知道,UTF-8是国际通用的字符编码,用它传输任何字串都不会有问题,通过它也可以很完美的解决J2EE的中文问题!所以我们最好用UTF-8编码,以减少不必要的麻烦。

注意,上面方法中当加密或者解密过程中,程序抛出异常,将返回原值,使得在调用方法失败时更方便的找出错误。

大家也可以利用其它的密钥,进行不同地方的加密解埽?

总结:DES是一个相对比较老的加密算法,对于现在也不是最安全的,所以大家也可以利用别的加密算法进行加密解密,以得到更安全的系统。

附:
DESUtil.java及Base64.java的源文件

posted on 2006-12-16 12:07 都市淘沙者 阅读(323) 评论(0)  编辑  收藏 所属分类: 加密解密/其他分类


只有注册用户登录后才能发表评论。


网站导航: