采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。
其核心思想是,加密和解密都是同一个秘钥
对称加密常用的算法有: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