Java中的加密与解密主要对数据的安全性提供保障,分为对称和非对称的,对称表示加密密钥和解密密钥是同一个密钥,因此也常常称作私密密钥或秘密密钥,非对称密钥表示加密密钥和解密为两个不同的密钥,一个为公共密钥,另一个则为私密密钥。对称加密解密算法有DES、AES等,非对称加密解密算法有RSA、DH等。对于数据的加密与解密我们通常通过生成密钥,然后通过加密与解密操作类利用密钥对数据进行加密与解密,接下来我们看看Java中如何实现对称、非对称加密与解密。
对称加密与解密:通过KeyGenerator(密钥生成器)生成Key(密钥),然后通过Cipher(加密解密操作类)进行对数据的加密与解密。
例子:
KeyGenerator kg=KeyGenerator.getInstance("DES");//获得指定算法的密钥生成器
kg.init(56);//密钥生成器初始化,指定生成密钥的长度
Key key=kg.generateKey();//获得密钥
Cipher cp=Cipher.getInstance("DES");//获得指定算法的加密解密操作类
cp.init(Cipher.ENCRYPT_MODE, key);//通过密钥对其进行初始化,初始化为加密操作类
byte[] b=cp.doFinal("hello".getBytes());//对数据进行加密
System.out.println(new String(b));
cp.init(Cipher.DECRYPT_MODE, key);//通过密钥对其进行初始化,初始化为解密操作类
System.out.println(new String(cp.doFinal(b)));//对数据进行解密
非对称加密与解密:通过KeyPairGenerator(密钥生成器)生成KeyPair(密钥),然后通过KeyPair得到公共密钥和私密密钥,最后通过Cipher(加密解密操作类)利用公共密钥和私密密钥对数据的加密与解密。
KeyPairGenerator kpg=KeyPairGenerator.getInstance("RSA");
kpg.initialize(512);
KeyPair kp=kpg.generateKeyPair();
Cipher c=Cipher.getInstance("RSA");
c.init(Cipher.ENCRYPT_MODE, kp.getPrivate());
byte[] b=c.doFinal("zhangsan".getBytes());
System.out.println(new String(b));
c.init(Cipher.DECRYPT_MODE, kp.getPublic());
System.out.println(new String(c.doFinal(b)));
数据安全性得到保障但是对于数据的完整性又是如何保障的呢?对于提供了消息摘要和数字签名两种方式来保障。消息摘要就是通过信息生成的散列值,例如A将数据发送给B,A会将信息和消息摘要一起发送过去,B接受到信息之后,利用信息生成消息摘要,然后与接受到的消息摘要相比是否一致。数字签名既保证了信息的完整性,也保证了数据的不可伪造性,同样是利用消息生成签名,与消息一起发送过去,收到消息与签名之后,利用消息来验证签名。
消息摘要:
MessageDigest md=MessageDigest.getInstance("MD5");
md.update("zhangsan".getBytes());
System.out.println(new String(md.digest()));//生成消息摘要
md.reset();//用于重置MessageDigest,其实当我们调用digest()方法之后就重置了Messagedigest
System.out.println(new String(md.digest("zhangsan".getBytes())));
/**
* MessageDigest用于产生消息摘要,也称为哈希值、散列值,用于产生该摘要的算法称为哈希函数、散列函数,主要用于保证
* 数据的完整性,在同一个哈希函数情况下,只有相同的消息才能产生相同的摘要,发送发将消息和摘要发送个接收方,接受者接受
* 到消息后使用发送发相同的哈希函数产生消息摘要,并且与接收到的消息摘要相比,对比是否相同。
*/
数字签名:与消息摘要不同,数字签名通过公共密钥生成和验证
byte[] message="hello".getBytes();
KeyPairGenerator kpg=KeyPairGenerator.getInstance("DSA");
kpg.initialize(1024);
KeyPair kp=kpg.generateKeyPair();
Signature sign=Signature.getInstance(kpg.getAlgorithm());
//通过私密密钥生成签名
sign.initSign(kp.getPrivate());
sign.update(message);
byte[] s=sign.sign(); //生成签名
//通过公共密钥验证签名
sign.initVerify(kp.getPublic());
sign.update(message);
System.out.println(sign.verify(s));//验证签名
我们在使用的过程中可能还会接触到Provider(安全机制提供者),简单的来理解就是提供加密解密算法方,在生成私密密钥生成器和公共密钥生成器的时候可能会用到,Provider继承Properties,因此可以向Properties一样使用。Security(对提供者的操作类),用于对提供者进行管理(查找、删除、增加)。JDK内置很多提供者,通过以下的方法可以查找出来
Provider[] ps=Security.getProviders();
System.out.println(ps.length);
for(Provider p:ps)
{
Set<Entry<Object, Object>> entry=p.entrySet();
for(Entry<Object,Object> e:entry)
System.out.println(e.getKey()+" "+e.getValue());
}