根据密钥类型不同将现代密码技术分为两类:对称加密算法(秘密钥匙加密)和非对称加密算法(公开密钥加密)。
对称钥匙加密系统是加密和解密均采用同一把秘密钥匙,而且通信双方都必须获得这把钥匙,并保持钥匙的秘密。
非对称密钥加密系统采用的加密钥匙(公钥)和解密钥匙(私钥)是不同的。
对称加密算法用来对敏感数据等信息进行加密,常用的算法包括:
DES(Data Encryption Standard):数据加密标准,速度较快,适用于加密大量数据的场合。
3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高。
AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高;
常见的非对称加密算法如下:
RSA:由 RSA 公司发明,是一个支持变长密钥的公共密钥算法,需要加密的文件块的长度也是可变的;
DSA(Digital Signature Algorithm):数字签名算法,是一种标准的 DSS(数字签名标准);
ECC(Elliptic Curves Cryptography):椭圆曲线密码编码学。
前面简单介绍了各种对称和非对称加密算法,那我们在实际使用的过程中究竟该使用哪一种比较好呢?
我们应该根据自己的使用特点来确定,由于非对称加密算法的运行速度比对称加密算法的速度慢很多,当我们需要加密大量的数据时,建议采用对称加密算法,提高加解密速度。
对称加密算法不能实现签名,因此签名只能非对称算法。
由于对称加密算法的密钥管理是一个复杂的过程,密钥的管理直接决定着他的安全性,因此当数据量很小时,我们可以考虑采用非对称加密算法。
在实际的操作过程中,我们通常采用的方式是:采用非对称加密算法管理对称算法的密钥,然后用对称加密算法加密数据,这样我们就集成了两类加密算法的优点,既实现了加密速度快的优点,又实现了安全方便管理密钥的优点。
如果在选定了加密算法后,那采用多少位的密钥呢?一般来说,密钥越长,运行的速度就越慢,应该根据的我们实际需要的安全级别来选择,一般来说,RSA建议采用1024位的数字,ECC建议采用160位,AES采用128为即可。
更多见:数据加密标准
saveDesKey生成密钥,存放在DesKey.xml中
encrypt和decrypt根据DesKey.xml中的密钥,来加密和解密文件
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.security.Key; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.KeyGenerator; public class DesUtil { private static String keyfileName = "DesKey.xml"; /** * <p> DES解密文件 * @param file 需要解密的文件 * @param dest 解密后的文件 * @throws Exception */ public static void decrypt(String file, String dest) throws Exception { Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.DECRYPT_MODE, getKey()); InputStream is = new FileInputStream(file); OutputStream out = new FileOutputStream(dest); CipherOutputStream cos = new CipherOutputStream(out, cipher); byte[] buffer = new byte[1024]; int r; while ((r = is.read(buffer)) >= 0) { cos.write(buffer, 0, r); } cos.close(); out.close(); is.close(); } /** * <p>DES加密文件 * @param file 源文件 * @param destFile 加密后的文件 * @throws Exception */ public static void encrypt(String file, String destFile) throws Exception { Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, getKey()); InputStream is = new FileInputStream(file); OutputStream out = new FileOutputStream(destFile); CipherInputStream cis = new CipherInputStream(is, cipher); byte[] buffer = new byte[1024]; int r; while ((r = cis.read(buffer)) > 0) { out.write(buffer, 0, r); } cis.close(); is.close(); out.close(); } private static Key getKey() { Key kp = null; try { String fileName = keyfileName; InputStream is = new FileInputStream(fileName); ObjectInputStream oos = new ObjectInputStream(is); kp = (Key) oos.readObject(); oos.close(); } catch (Exception e) { e.printStackTrace(); } return kp; } public static void main(String[] args) throws Exception { DesUtil.saveDesKey(); DesUtil.encrypt("desinput.txt", "desoutput.txt"); DesUtil.decrypt("desoutput.txt","desinput2.txt"); //desinput.txt 经过加密和解密后生成的 desinput2.txt 应该与源文件一样 } /** * <p> 生成KEY,并保存 */ public static void saveDesKey(){ try { SecureRandom sr = new SecureRandom(); //为我们选择的DES算法生成一个KeyGenerator对象 KeyGenerator kg = KeyGenerator.getInstance ("DES" ); kg.init (sr); FileOutputStream fos = new FileOutputStream(keyfileName); ObjectOutputStream oos = new ObjectOutputStream(fos); //生成密钥 Key key = kg.generateKey(); oos.writeObject(key); oos.close(); } catch (Exception e) { e.printStackTrace(); } } }