Topic: 请问这种加密有什么实际意义?

  Print this page

1.请问这种加密有什么实际意义? Copy to clipboard
Posted by: focus
Posted on: 2006-08-03 15:21


package security;

/**
*安全程序 DESede/DES测试
*/
import java.security.*;
import javax.crypto.*;

public class Testdes {

public static void main(String[] args){

Testdes my=new Testdes();
my.run();
}

public void run() {

//添加新安全算法,如果用JCE就要把它添加进去
Security.addProvider(new com.sun.crypto.provider.SunJCE());
String Algorithm="DES"; //定义 加密算法,可用 DES,DESede,Blowfish
String myinfo="要加密的信息";

try {

//生成密钥
KeyGenerator keygen = KeyGenerator.getInstance(Algorithm);
SecretKey deskey = keygen.generateKey();

//加密
System.out.println("加密前的二进串:"+byte2hex(myinfo.getBytes()));
System.out.println("加密前的信息:"+myinfo);

Cipher c1 = Cipher.getInstance(Algorithm);

//用密钥来加密,方式:加密模式
c1.init(Cipher.ENCRYPT_MODE,deskey);

byte[] cipherByte=c1.doFinal(myinfo.getBytes());

System.out.println("加密后的二进串:"+byte2hex(cipherByte));

//解密
c1 = Cipher.getInstance(Algorithm);

//用密钥来解密,方式:解密模式
c1.init(Cipher.DECRYPT_MODE,deskey);

byte[] clearByte=c1.doFinal(cipherByte);

System.out.println("解密后的二进串:"+byte2hex(clearByte));
System.out.println("解密后的信息:"+(new String(clearByte)));

} catch (java.security.NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (javax.crypto.NoSuchPaddingException e2) {
e2.printStackTrace();
} catch (java.lang.Exception e3) {
e3.printStackTrace();
}

}

//二进制转字符串
//把二进制数组转换成十六进制串,用:号隔开
//一个字节(8位)对应于一个两位的十六进制数
public String byte2hex(byte[] b) {

String hs="";
String stmp="";

for (int n=0;n<b.length;n++) {

stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));

if (stmp.length()==1) hs=hs+"0"+stmp;
else hs=hs+stmp;

if (n<b.length-1) hs=hs+":";

}

return hs.toUpperCase();

}

}

运行结果:
加密前的二进串Big Smile2:AA:BCBig Smile3:C3Big SmileC:B5:C4Big Smile0:C5:CF:A2
加密前的信息:要加密的信息
加密后的二进串:88:78:8A:6E:EB:38:7A:37:CE:EDBig SmileA:39:B0:43:A4:6E
解密后的二进串Big Smile2:AA:BCBig Smile3:C3Big SmileC:B5:C4Big Smile0:C5:CF:A2
解密后的信息:要加密的信息
问题:
用的是密钥加密,解密.
而密钥的生成方法如下:
//生成密钥
KeyGenerator keygen = KeyGenerator.getInstance(Algorithm);
SecretKey deskey = keygen.generateKey();
关于这个方法誰都可以用,因此誰都可以把通过该密钥加密过的文件解密.
那这个程序还有什么意义呢?
小弟初识security,也是头一次听说密钥,问题肤浅,请大虾们别见笑.

2.Re:请问这种加密有什么实际意义? [Re: focus] Copy to clipboard
Posted by: menzy
Posted on: 2006-08-04 09:06

关键在这里:

SecretKey deskey = keygen.generateKey();

仔细看看手册

3.Re:请问这种加密有什么实际意义? [Re: focus] Copy to clipboard
Posted by: focus
Posted on: 2006-08-04 20:16

我改的代码:

package security;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import javax.crypto.*;

public class SecretData {

/**
* 加密函数
* */
public String encrypt(SecretKey deskey, String myinfo) {

try {

//测试用
System.out.println("加密前的信息:"+myinfo);
//加密 测试用
System.out.println("加密前的二进串:"+byte2hex(myinfo.getBytes()));

Cipher c1 = Cipher.getInstance("DES");

//用密钥来加密,方式:加密模式
c1.init(Cipher.ENCRYPT_MODE,deskey);

byte[] cipherByte = c1.doFinal(myinfo.getBytes());

String strAfterEncrypted = byte2hex(cipherByte);

//测试用
System.out.println("加密后的二进串:" + strAfterEncrypted);

return strAfterEncrypted;

} catch (java.security.NoSuchAlgorithmException e1) {
e1.printStackTrace();
return "加密出错";
} catch (javax.crypto.NoSuchPaddingException e2) {
e2.printStackTrace();
return "加密出错";
} catch (java.lang.Exception e3) {
e3.printStackTrace();
return "加密出错";
}

}

/**
* 解密函数
* */
public String decrypt(SecretKey deskey, String secretInfo) {

try {
//解密
Cipher c1 = Cipher.getInstance("DES");

//用密钥来解密,方式:解密模式
c1.init(Cipher.DECRYPT_MODE,deskey);

byte[] clearByte=c1.doFinal(hexToByte(secretInfo));
String strAfterDecrypt = byte2hex(clearByte);

//测试用
System.out.println("解密后的二进串:" + strAfterDecrypt);

String strAfterInfo = new String(clearByte);

//测试用
//System.out.println("解密后的信息:" + strAfterInfo);

return strAfterInfo;

} catch (java.security.NoSuchAlgorithmException e1) {
e1.printStackTrace();
return "解密出错";
} catch (javax.crypto.NoSuchPaddingException e2) {
e2.printStackTrace();
return "解密出错";
} catch (java.lang.Exception e3) {
e3.printStackTrace();
return "解密出错";
}

}

/**
*二进制转字符串
*把二进制数组转换成十六进制串,用:号隔开
*一个字节(8位)对应于一个两位的十六进制数
*/
public String byte2hex(byte[] b) {

String hs="";
String stmp="";

for (int n=0;n<b.length;n++) {

stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));

if (stmp.length()==1) hs=hs+"0"+stmp;
else hs=hs+stmp;

if (n<b.length-1) hs=hs+":";

}

return hs.toUpperCase();

}

/**
* 将十六进制字符串转换成二进制数组
* */
public byte[] hexToByte(String c) {

String strTemp[] = c.split(":");

byte[] results = new byte[strTemp.length];

for (int i = 0; i < strTemp.length; i++) {
results[i] = (byte)(Integer.parseInt(strTemp[i].toLowerCase(), 16));
}

return results;

}

/**
* 生成密钥并存入文件OR从文件取出密钥
* */
public SecretKey getDeskey() {

try {

if ((new File("mykey.dat")).exists() == true) {

ObjectInputStream in = new ObjectInputStream(new FileInputStream("mykey.dat"));
SecretKey deskey = (SecretKey)in.readObject();
in.close();
return deskey;
}

//生成密钥
KeyGenerator keygen = KeyGenerator.getInstance("DES");
SecretKey deskey = keygen.generateKey();

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("mykey.dat"));

out.writeObject(deskey);
out.close();

System.out.println("写入对象 deskey ok");

return deskey;
} catch (java.lang.Exception e) {

e.printStackTrace();
System.out.println("生成密钥失败");
return null;
}

}

/**
* 该方法测试用
* */
public static void main(String[] args) {

try {

SecretData my = new SecretData();

//生成OR取出密钥
SecretKey deskey = my.getDeskey();

//加密
String strForDecrypt = my.encrypt(deskey, "这是加密的信息!");

System.out.println("deskey is: " + deskey.toString());

//将strForDecrypt 存到数据库

System.out.println("从数据库取出来的信息是: " + strForDecrypt);

//将取出来的deskey 及 strForDecrypt作为参数 来解密
String strAfterDecryptInfo = my.decrypt(deskey, strForDecrypt);

System.out.println("解密后的信息是: " + strAfterDecryptInfo);

} catch (java.lang.Exception e3) {
e3.printStackTrace();
}

}

}

运行结果如下:

加密前的信息:这是加密的信息!
加密前的二进串Big Smile5:E2:CA:C7:BCBig Smile3:C3Big SmileC:B5:C4Big Smile0:C5:CF:A2:A3:A1
加密后的二进串:0B:8B:2B:ED:3B:78:8B:0C:82:77:F7:65Big SmileE:E6:C3:75Big SmileA:EB:0E:B8:AA:6B:27:09
deskey is: com.sun.crypto.provider.DESKey@fffe7ba6
从数据库取出来的信息是: 0B:8B:2B:ED:3B:78:8B:0C:82:77:F7:65Big SmileE:E6:C3:75Big SmileA:EB:0E:B8:AA:6B:27:09
解密后的二进串Big Smile5:E2:CA:C7:BCBig Smile3:C3Big SmileC:B5:C4Big Smile0:C5:CF:A2:A3:A1
解密后的信息是: 这是加密的信息!

有个问题:
我现在是把密钥存到文件中去了,但不知道怎么把密钥存到ORACLE,
Oracle中对应字段要设成什么类型?插入SQL语句应该怎么写?又如何取?

4.Re:请问这种加密有什么实际意义? [Re: focus] Copy to clipboard
Posted by: menzy
Posted on: 2006-08-07 09:30

二进制的东西你打算用什么存储?
如果不想做hex2byte, 你没有什么选择的。

5.Re:请问这种加密有什么实际意义? [Re: focus] Copy to clipboard
Posted by: focus
Posted on: 2006-08-08 12:08

方法 getDeskey() 被我改成如下所示:
实现了,将密钥存入数据库的功能,虽然用流可以实现存入java object 到 DB(即,可以直接把密钥存入数据库,具体的代码还不会,誰告诉我下?)但该方法没有对密钥加密,所以我采用了下面的方法,将密钥拆分后并打乱顺序再存入数据库,我们再只要保证该CLASS文件不被反编译,那么这个加密就比较安全了.
我没读过什么书,所以一开始以为密钥的长度不固定,所以代码有些庸余,但实际运行却发现每次生成的密钥都是8字节.

/**
* 生成密钥并存入数据库OR从数据库取出密钥
* */
public SecretKey getDeskey() {

try {

SecretKey deskey = null;

String orclURL = null;

//读XML配置文件,取得ORACLE的URL
SAXReader reader = new SAXReader();

try {
Document doc = reader.read(new File("E:\\SWECTool\\bea\\user_projects\\domains\\default\\config.xml"));
Element connPoolEle = (Element) doc.selectSingleNode("/Domain/JDBCConnectionPool");
orclURL = connPoolEle.attributeValue("URL");
//System.out.println(orclURL);
} catch (DocumentException e) {

e.printStackTrace();
}

try {

//Oracle的连接
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();

String user = "smile";
String password = "smile";

Connection conn = DriverManager.getConnection(orclURL,user,password);

if(conn != null){

System.out.println("Connection Success "+conn);
}else{

System.out.println("Connection failed "+conn);
}

Statement stmt = conn.createStatement();

try {

//SQL文,从表DESKEY中检索出deskey的被拆分的各部分
StringBuffer statement3 = new StringBuffer();

statement3.append("SELECT B.*, A.COUNT ");
statement3.append("FROM (SELECT COUNTStart AS COUNT FROM USER_TAB_COLUMNS ");
statement3.append("WHERE TABLE_NAME='DESKEY') A, DESKEY B");

//执行,从表DESKEY中检索出deskey的被拆分的各部分
ResultSet resultKey = stmt.executeQuery(statement3.toString());

if (resultKey.next()) {

int fieldNumber2 = Integer.parseInt(resultKey.getString("COUNT"));

String[] strdeskeyArray2 = new String[fieldNumber2];

for (int i = 1; i <= fieldNumber2; i++) {
strdeskeyArray2[i-1] = resultKey.getStringLight Bulb;
}

//还原顺序
if (fieldNumber2 > 2) {
String strTemp1 = resultKey.getString(1);
String strTemp2 = resultKey.getString(fieldNumber2 - 1);
strdeskeyArray2[0] = strdeskeyArray2[fieldNumber2 - 1];
strdeskeyArray2[fieldNumber2 - 2] = strTemp1;
strdeskeyArray2[fieldNumber2 - 1] = strTemp2;
}

//测试用
StringBuffer aa = new StringBuffer();
for (int i = 0; i < fieldNumber2; i++) {
if (i < fieldNumber2 - 1) {
aa.append(strdeskeyArray2[i] + ":");
} else {
aa.append(strdeskeyArray2[i]);
}
}
System.out.println("密钥数组顺序被整理成: " +aa.toString());

StringBuffer str = new StringBuffer();
for (int i = 1; i <= fieldNumber2; i++) {
if (i < fieldNumber2) {
str.append(strdeskeyArray2[i - 1] + ":");
} else {
str.append(strdeskeyArray2[i - 1]);
}
}

//The bytes can be converted back to a SecretKey
SecretKey deskey2 = new SecretKeySpec(hexToByte(str.toString()), "DES");
//测试用
System.out.println("这次取得的密钥是从数据库中取出来地!");
return deskey2;
}
} catch (Exception e) {

//e.printStackTrace();

//生成密钥
KeyGenerator keygen = KeyGenerator.getInstance("DES");
deskey = keygen.generateKey();

//测试用
System.out.println("首次获得的密钥是: " + deskey.toString());

//Get the bytes of the key
byte[] deskeyBytes = deskey.getEncoded();

String strdeskey = byte2hex(deskeyBytes);

//测试用
System.out.println("密钥被转换成字符串: " + strdeskey);

String strdeskeyArray[] = strdeskey.split(":");

int fieldNumber = strdeskeyArray.length;

//打乱顺序后再存入数据库
if (fieldNumber > 2) {
String strTemp1 = strdeskeyArray[0];
String strTemp2 = strdeskeyArray[fieldNumber - 2];
strdeskeyArray[fieldNumber - 2] = strdeskeyArray[fieldNumber - 1];
strdeskeyArray[fieldNumber - 1] = strTemp1;
strdeskeyArray[0] = strTemp2;
}

//测试用
StringBuffer bb = new StringBuffer();
for (int i = 0; i < fieldNumber; i++) {
if (i < fieldNumber - 1) {
bb.append(strdeskeyArray[i] + ":");
} else {
bb.append(strdeskeyArray[i]);
}
}
System.out.println("打乱顺序后的密钥数组为: " +bb.toString());

//SQL文,建立存放密钥的表
StringBuffer statement = new StringBuffer();

statement.append("CREATE TABLE DESKEY ");
statement.append("( ");
for (int i = 0; i < fieldNumber; i++) {
statement.append("KEY_" + i);

if (i < fieldNumber -1) {
statement.append(" CHAR(2), ");
} else {
statement.append(" CHAR(2) ");
}

}
statement.append(")");

//SQL文插入语句,把deskey拆开分别插入不同的字段中
StringBuffer statement2 = new StringBuffer();

statement2.append("INSERT INTO DESKEY ");

statement2.append("( ");

for (int i = 0; i < fieldNumber; i++) {

if (i < fieldNumber -1) {
statement2.append("KEY_" + i + ", ");
} else {
statement2.append("KEY_" + i);
}

}

statement2.append(" ) ");

statement2.append(" VALUES( ");

for (int i = 0; i < fieldNumber; i++) {

if (i < fieldNumber -1) {
statement2.append("'" + strdeskeyArray[i] + "', ");
} else {
statement2.append("'" + strdeskeyArray[i] + "'");
}

}

statement2.append(" )");

//DESKEY表的建立
stmt.executeUpdate(statement.toString());

//提交
conn.commit();

//deskey的插入
int result = stmt.executeUpdate(statement2.toString());

//提交
conn.commit();

//测试用
if (result > 0) {
System.out.println("密钥已被成功插入到数据库,result = " + result);
}

}

} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//测试用
System.out.println("这次取得的密钥是首次生成的!");
return deskey;
} catch (Exception e) {

e.printStackTrace();
System.out.println("生成密钥失败");
return null;
}

}

6.Re:请问这种加密有什么实际意义? [Re: focus] Copy to clipboard
Posted by: menzy
Posted on: 2006-08-09 10:04

楼上的有研究精神,加1分

7.Re:请问这种加密有什么实际意义? [Re: focus] Copy to clipboard
Posted by: focus
Posted on: 2006-08-10 17:35

呵呵,谢谢~~!


   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923