Java加密解密之对称加密

采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。

其核心思想是,加密和解密都是同一个秘钥


对称加密常用的算法有:DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK、AES等。


对称加密算法的优点是算法公开、计算量小、加密速度快、加密效率高。


对称加密算法的缺点是在数据传送前,发送方和接收方必须商定好秘钥,然后使双方都能保存好秘钥。其次如果一方的秘钥被泄露,那么加密信息也就不安全了。另外,每对用户每次使用对称加密算法时,都需要使用其他人不知道的唯一秘钥,这会使得收、发双方所拥有的钥匙数量巨大,密钥管理成为双方的负担


下面演示一个Java(1.8.0_144)使用DES算法的对称加密

package com.security.cipher;

import java.security.Key;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;

/**
 * 这里面的API里面有很多是调用getInstance方法,这个方法的参数有algorithm或者transformation
 * 一:algorithm:算法
 * 
 * 二:transformation:有两种格式
 * 1:算法/模式/填充方式。如:DES/CBC/PKCS5Padding
 * 2:算法。                              如:DES
 * 
 * 其中,algorithm、transformation的值,不区分大小写
 * 
 * Java加密解密官方参考文档:
 * https://docs.oracle.com/javase/8/docs/technotes/guides/security/index.html
 * https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html
 */
public class CipherTest {
	
	/*
	 * 使用KeyGenerator生成key
	 * 
	 * 其中,algorithm支持的算法有:AES、DES、DESEDE、HMACMD5、HMACSHA1、HMACSHA256、RC2等
	 * 全部支持的算法见官方文档
	 * https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyGenerator
	 *  
	 */
	public static Key newKeyByKeyGenerator(String algorithm) throws NoSuchAlgorithmException {
		KeyGenerator kg = KeyGenerator.getInstance(algorithm);
		Key key = kg.generateKey();
		return key;
	}
	
	/**
	 * 使用SecretKeySpec生成key
	 * 一般是从一个文件中读取出key的byte数组,然后根据文件key的算法,构建出key对象
	 */
	public static Key newKeyBySecretKeySpec(byte[] key, String algorithm) throws NoSuchAlgorithmException {
		return new SecretKeySpec(key, algorithm);
	}
	
	/**
	 * 加密,对字符串进行加密,返回结果为byte数组
	 * 保存的时候,可以把byte数组进行base64编码成字符串,或者把byte数组转换成16进制的字符串
	 * 
	 * 其中,transformation支持的全部算法见官方文档:
	 * https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher
	 */
	public static byte[] encrypt(String transformation, Key key, String password) throws Exception {
		Cipher cipher = Cipher.getInstance(transformation);
		//加密模式
		cipher.init(Cipher.ENCRYPT_MODE, key);
		return cipher.doFinal(password.getBytes());
	}
	
	/**
	 * 解密,返回结果为原始字符串
	 * 
	 * 其中,transformation支持的全部算法见官方文档:
	 * https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Cipher
	 */
	public static String decrypt(String transformation, Key key, byte[] data) throws Exception {
		Cipher cipher = Cipher.getInstance(transformation);
		//解密模式
		cipher.init(Cipher.DECRYPT_MODE, key);
		byte[] result = cipher.doFinal(data);
		String password = new String(result);
		return password;
	}
	
	public static void main(String[] args) throws Exception {
		String password = "123456";
		
		String algorithm = "DES";
		String transformation = algorithm;
		
		//加密解密使用的都是同一个秘钥key
		Key key = newKeyByKeyGenerator(algorithm);
		
		//加密
		byte[] passData = encrypt(transformation, key, password);
		//解密
		String pass = decrypt(transformation, key, passData);
		
		System.out.println("解密后的密码 : " + pass);
	}
}

上面的,KeyGenerator.getInstance(algorithm)  参数algorithm可以支持的值除了参考官方文档,还可以通过如下代码得出

Security.getAlgorithms("KeyGenerator").forEach(System.out::println);

在Java8中,输出结果如下:

RC2
SUNTLSKEYMATERIAL
HMACSHA384
DESEDE
BLOWFISH
ARCFOUR
HMACSHA256
HMACSHA224
HMACMD5
AES
HMACSHA512
DES
SUNTLSRSAPREMASTERSECRET
SUNTLSPRF
SUNTLSMASTERSECRET
HMACSHA1
SUNTLS12PRF


Cipher.getInstance(transformation) 参数transformation可以支持的值,除了参考官方文档,还可以通过如下代码得出

Security.getAlgorithms("Cipher").forEach(System.out::println)

输出结果如下:

AES
AESWRAP
AESWRAP_128
AESWRAP_192
AESWRAP_256
AES_128/CBC/NOPADDING
AES_128/CFB/NOPADDING
AES_128/ECB/NOPADDING
AES_128/GCM/NOPADDING
AES_128/OFB/NOPADDING
AES_192/CBC/NOPADDING
AES_192/CFB/NOPADDING
AES_192/ECB/NOPADDING
AES_192/GCM/NOPADDING
AES_192/OFB/NOPADDING
AES_256/CBC/NOPADDING
AES_256/CFB/NOPADDING
AES_256/ECB/NOPADDING
AES_256/GCM/NOPADDING
AES_256/OFB/NOPADDING
ARCFOUR
BLOWFISH
DES
DESEDE
DESEDEWRAP
PBEWITHHMACSHA1ANDAES_128
PBEWITHHMACSHA1ANDAES_256
PBEWITHHMACSHA224ANDAES_128
PBEWITHHMACSHA224ANDAES_256
PBEWITHHMACSHA256ANDAES_128
PBEWITHHMACSHA256ANDAES_256
PBEWITHHMACSHA384ANDAES_128
PBEWITHHMACSHA384ANDAES_256
PBEWITHHMACSHA512ANDAES_128
PBEWITHHMACSHA512ANDAES_256
PBEWITHMD5ANDDES
PBEWITHMD5ANDTRIPLEDES
PBEWITHSHA1ANDDESEDE
PBEWITHSHA1ANDRC2_128
PBEWITHSHA1ANDRC2_40
PBEWITHSHA1ANDRC4_128
PBEWITHSHA1ANDRC4_40
RC2
RSA
RSA/ECB/PKCS1PADDING




你可能感兴趣的:(Java)