加密是指对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为“密文”,通过这样的途径来达到保护数据不被非法人窃取、阅读的目的。 该过程的逆过程为解密,即将该编码信息转化为其原来数据的过程。大体上分为双向加密和单向加密,而双向加密又分为对称加密和非对称加密。
一、双向加密
(一)、对称加密
采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。需要对加密和解密使用相同密钥的加密算法。由于其速度,对称性加密通常在消息发送方需要加密大量数据时使用。对称性加密也称为密钥加密。所谓对称,就是采用这种加密方法的双方使用方式用同样的密钥进行加密和解密。密钥是控制加密及解密过程的指令。
对称加密先在java类中定义相关成员
//KeyGenerator 提供对称密钥生成器的功能,支持各种算法
private KeyGenerator keygen;
//SecretKey 负责保存对称密钥
private SecretKey deskey;
//Cipher负责完成加密或解密工作
private Cipher c;
//该字节数组负责保存加密的结果
private byte[] cipherByte;
再在构造方法中对其初始化
Security.addProvider(new com.sun.crypto.provider.SunJCE());
//实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常)
keygen = KeyGenerator.getInstance("DES");
//生成密钥
deskey = keygen.generateKey();
//生成Cipher对象,指定其支持的DES算法
c = Cipher.getInstance("DES");
常用的对称加密算法
- DES算法
- 3DES算法
- AES算法
import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.Security; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; public class DESdemo { //KeyGenerator 提供对称密钥生成器的功能,支持各种算法 private KeyGenerator keygen; //SecretKey 负责保存对称密钥 private SecretKey deskey; //Cipher负责完成加密或解密工作 private Cipher c; //该字节数组负责保存加密的结果 private byte[] cipherByte; public DESdemo() throws NoSuchAlgorithmException, NoSuchPaddingException{ Security.addProvider(new com.sun.crypto.provider.SunJCE()); //实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常) keygen = KeyGenerator.getInstance("DES"); //生成密钥 deskey = keygen.generateKey(); //生成Cipher对象,指定其支持的DES算法 c = Cipher.getInstance("DES"); } /** * 对字符串加密 * * @param str * @return * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte[] Encrytor(String str) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式 c.init(Cipher.ENCRYPT_MODE, deskey); byte[] src = str.getBytes(); // 加密,结果保存进cipherByte cipherByte = c.doFinal(src); return cipherByte; } /** * 对字符串解密 * * @param buff * @return * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte[] Decryptor(byte[] buff) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式 c.init(Cipher.DECRYPT_MODE, deskey); cipherByte = c.doFinal(buff); return cipherByte; } /** * @param args * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws InvalidKeyException */ public static void main(String[] args) throws Exception { EncrypDES de1 = new EncrypDES(); String msg ="www.suning.com/index.jsp"; byte[] encontent = de1.Encrytor(msg); byte[] decontent = de1.Decryptor(encontent); System.out.println("明文是:" + msg); System.out.println("加密后:" + new String(encontent)); System.out.println("解密后:" + new String(decontent)); } }
import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.Security; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; public class DES3demo { // KeyGenerator 提供对称密钥生成器的功能,支持各种算法 private KeyGenerator keygen; // SecretKey 负责保存对称密钥 private SecretKey deskey; // Cipher负责完成加密或解密工作 private Cipher c; // 该字节数组负责保存加密的结果 private byte[] cipherByte; public DES3demo() throws NoSuchAlgorithmException, NoSuchPaddingException { Security.addProvider(new com.sun.crypto.provider.SunJCE()); // 实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常) keygen = KeyGenerator.getInstance("DESede"); // 生成密钥 deskey = keygen.generateKey(); // 生成Cipher对象,指定其支持的DES算法 c = Cipher.getInstance("DESede"); } /** * 对字符串加密 * * @param str * @return * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte[] Encrytor(String str) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式 c.init(Cipher.ENCRYPT_MODE, deskey); byte[] src = str.getBytes(); // 加密,结果保存进cipherByte cipherByte = c.doFinal(src); return cipherByte; } /** * 对字符串解密 * * @param buff * @return * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte[] Decryptor(byte[] buff) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式 c.init(Cipher.DECRYPT_MODE, deskey); cipherByte = c.doFinal(buff); return cipherByte; } /** * @param args * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws InvalidKeyException */ public static void main(String[] args) throws Exception { DES3demo des = new DES3demo(); String msg ="www.suning.com/index.jsp"; byte[] encontent = des.Encrytor(msg); byte[] decontent = des.Decryptor(encontent); System.out.println("明文是:" + msg); System.out.println("加密后:" + new String(encontent)); System.out.println("解密后:" + new String(decontent)); } }
import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.Security; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; public class AESdemo { //KeyGenerator 提供对称密钥生成器的功能,支持各种算法 private KeyGenerator keygen; //SecretKey 负责保存对称密钥 private SecretKey deskey; //Cipher负责完成加密或解密工作 private Cipher c; //该字节数组负责保存加密的结果 private byte[] cipherByte; public AESdemo() throws NoSuchAlgorithmException, NoSuchPaddingException{ Security.addProvider(new com.sun.crypto.provider.SunJCE()); //实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常) keygen = KeyGenerator.getInstance("AES"); //生成密钥 deskey = keygen.generateKey(); //生成Cipher对象,指定其支持的DES算法 c = Cipher.getInstance("AES"); } /** * 对字符串加密 * * @param str * @return * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte[] Encrytor(String str) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式 c.init(Cipher.ENCRYPT_MODE, deskey); byte[] src = str.getBytes(); // 加密,结果保存进cipherByte cipherByte = c.doFinal(src); return cipherByte; } /** * 对字符串解密 * * @param buff * @return * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte[] Decryptor(byte[] buff) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式 c.init(Cipher.DECRYPT_MODE, deskey); cipherByte = c.doFinal(buff); return cipherByte; } /** * @param args * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws InvalidKeyException */ public static void main(String[] args) throws Exception { AESdemo de1 = new AESdemo(); String msg ="www.suning.com/index.jsp"; byte[] encontent = de1.Encrytor(msg); byte[] decontent = de1.Decryptor(encontent); System.out.println("明文是:" + msg); System.out.println("加密后:" + new String(encontent)); System.out.println("解密后:" + new String(decontent)); } }
(二)、非对称加密
与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥 。公开密钥与私有密钥是一对,如果用公开密钥对数据
进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的
密钥,所以这种算法叫作非对称加密算法。
常用的非对称加密算法
- RSA 公钥加密算法
- DSA算法
关于RSA算法的demo如下
import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; public class RSAdemo { /** * 加密 * @param publicKey * @param srcBytes * @return * @throws NoSuchAlgorithmException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ protected byte[] encrypt(RSAPublicKey publicKey,byte[] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{ if(publicKey!=null){ //Cipher负责完成加密或解密工作,基于RSA Cipher cipher = Cipher.getInstance("RSA"); //根据公钥,对Cipher对象进行初始化 cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] resultBytes = cipher.doFinal(srcBytes); return resultBytes; } return null; } /** * 解密 * @param privateKey * @param srcBytes * @return * @throws NoSuchAlgorithmException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ protected byte[] decrypt(RSAPrivateKey privateKey,byte[] srcBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{ if(privateKey!=null){ //Cipher负责完成加密或解密工作,基于RSA Cipher cipher = Cipher.getInstance("RSA"); //根据公钥,对Cipher对象进行初始化 cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] resultBytes = cipher.doFinal(srcBytes); return resultBytes; } return null; } /** * @param args * @throws NoSuchAlgorithmException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws NoSuchPaddingException * @throws InvalidKeyException */ public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { RSAdemo rsa = new RSAdemo(); String msg = "www.suning.com/index.jsp"; //KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); //初始化密钥对生成器,密钥大小为1024位 keyPairGen.initialize(1024); //生成一个密钥对,保存在keyPair中 KeyPair keyPair = keyPairGen.generateKeyPair(); //得到私钥 RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate(); //得到公钥 RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic(); //用公钥加密 byte[] srcBytes = msg.getBytes(); byte[] resultBytes = rsa.encrypt(publicKey, srcBytes); //用私钥解密 byte[] decBytes = rsa.decrypt(privateKey, resultBytes); System.out.println("明文是:" + msg); System.out.println("加密后是:" + new String(resultBytes)); System.out.println("解密后是:" + new String(decBytes)); } }
二、单向加密(信息摘要) MD5、SHA、HMAC这三种加密算法,可谓是非可逆加密,就是不可解密的加密方法,我们称之为单向加密算法。
MD5 -- message-digest algorithm 5 (信息-摘要算法)缩写,广泛用于加密和解密技术,常用于文件校验。校验?不管文件多大,经过MD5后都能生成唯一的MD5值。实现如下图所示:
代码实现:
public static byte[] encryptMD5(byte[] data) throws Exception {
MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
md5.update(data);return md5.digest();
}
SHA(Secure Hash Algorithm,安全散列算法),数字签名等密码学应用中重要的工具,被广泛地应用于电子商务等信息安全领域。虽然,SHA与MD5通过碰撞法都被破解了,但是SHA仍然是公认的安全加密算法,较之MD5更为安全。实现如下图所示:
代码实现:
public static byte[] encryptSHA(byte[] data) throws Exception {
MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
sha.update(data);return sha.digest();
}
}
HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议。消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。 实现如下图所示:
代码实现:
/**
* 初始化HMAC密钥
*/
public static String initMacKey() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);SecretKey secretKey = keyGenerator.generateKey();
return encryptBASE64(secretKey.getEncoded());
}/**
* HMAC加密
*/
public static byte[] encryptHMAC(byte[] data, String key) throws Exception {SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);return mac.doFinal(data);
}
参考资料:
http://security.group.iteye.com/group/wiki/1710-one-way-encryption-algorithm
《Java加密与解密的艺术》