一般来讲,在java上实现加密解密算法,有3种方式。
1)自行实现算法
2)使用java自带的crypto软件包
3)使用第三方库
本文讲述一下第二种使用方法。我最开始也是找了很多这方面的资料,但是总感觉还是缺乏一些细节。现将我的一些心得与大家分享。
本文给出的例子基于下面的blog中所给出的例子。
blog.csdn.net/wildandfly/article/details/21521857
首先,现代密码学算法大致可以分为3个大块。分别是对称加密symmetric,非对称加密asymmetric,消息摘要hash。
本文实现了下列的几种算法,其中每个package中的算法都非常类似。
不罗嗦,直接上代码
http://download.csdn.net/detail/watch_ch/9465641
1对称加密
以AES为例。注意其中keygenerator函数,其中keygenerator.getInstance()函数需要输入对应的密码方法,从而生成对应长度的key。
这里,我查了下doc。可以传入的参数如下图。
package java_crypto_symmetric;
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));
}
}
2非对称加密
以rsa为例,由于公钥加密体系需要2个key值,故产生key值的函数也发生了改变。
keypairgenerator.getInstance()函数同样需要传入加密的方法,产生对应的key值。
这里,我也查了下doc,如下。
package java_crypto_asymmetric;
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));
}
}
3hash函数
这个由于我没有用到,暂时就不写了,以后再补上。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
注意:
在1、2中除了keygenerator需要传递密码的方法,cipher在初始化时也需要指定其参数。如下所示。