Java中的对称加密详解
采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。
常见的对称加密方法
DES : Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。
AES : Advanced Encryption Standard, 高级加密标准 .在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。
代码案例
byte[] 和16进制字符串相互转换
private byte[] hexStringToBytes(String hexString) { if (hexString.length() % 2 != 0) throw new IllegalArgumentException("hexString length not valid"); int length = hexString.length() / 2; byte[] resultBytes = new byte[length]; for (int index = 0; index < length; index++) { String result = hexString.substring(index * 2, index * 2 + 2); resultBytes[index] = Integer.valueOf(Integer.parseInt(result, 16)).byteValue(); } return resultBytes; } private String bytesToHexString(byte[] sources) { if (sources == null) return null; StringBuilder stringBuffer = new StringBuilder(); for (byte source : sources) { String result = Integer.toHexString(source& 0xff); if (result.length() < 2) { result = "0" + result; } stringBuffer.append(result); } return stringBuffer.toString(); }
DES 加密和解密
private String encryptByDES(String input,String key) throws Exception { // 算法 String algorithm = "DES"; String transformation = "DES"; // Cipher:密码,获取加密对象 // transformation:参数表示使用什么类型加密 Cipher cipher = Cipher.getInstance(transformation); // 指定秘钥规则 // 第一个参数表示:密钥,key的字节数组 长度必须是8位 // 第二个参数表示:算法 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); // 对加密进行初始化 // 第一个参数:表示模式,有加密模式和解密模式 // 第二个参数:表示秘钥规则 cipher.init(Cipher.ENCRYPT_MODE,sks); // 进行加密 byte[] bytes = cipher.doFinal(input.getBytes()); return bytesToHexString(bytes); } private String decryptByDES(String input,String key)throws Exception{ // 算法 String algorithm = "DES"; String transformation = "DES"; // Cipher:密码,获取加密对象 // transformation:参数表示使用什么类型加密 Cipher cipher = Cipher.getInstance(transformation); // 指定秘钥规则 // 第一个参数表示:密钥,key的字节数组 长度必须是8位 // 第二个参数表示:算法 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); // 对加密进行初始化 // 第一个参数:表示模式,有加密模式和解密模式 // 第二个参数:表示秘钥规则 cipher.init(Cipher.DECRYPT_MODE,sks); // 进行解密 byte [] inputBytes = hexStringToBytes(input); byte[] bytes = cipher.doFinal(inputBytes); return new String(bytes); }
AES 加密和解密
private String encryptByAES(String input,String key) throws Exception { // 算法 String algorithm = "AES"; String transformation = "AES"; // Cipher:密码,获取加密对象 // transformation:参数表示使用什么类型加密 Cipher cipher = Cipher.getInstance(transformation); // 指定秘钥规则 // 第一个参数表示:密钥,key的字节数组 长度必须是16位 // 第二个参数表示:算法 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); // 对加密进行初始化 // 第一个参数:表示模式,有加密模式和解密模式 // 第二个参数:表示秘钥规则 cipher.init(Cipher.ENCRYPT_MODE,sks); // 进行加密 byte[] bytes = cipher.doFinal(input.getBytes()); return bytesToHexString(bytes); } private String decryptByAES(String input,String key)throws Exception{ // 算法 String algorithm = "AES"; String transformation = "AES"; // Cipher:密码,获取加密对象 // transformation:参数表示使用什么类型加密 Cipher cipher = Cipher.getInstance(transformation); // 指定秘钥规则 // 第一个参数表示:密钥,key的字节数组 长度必须是16位 // 第二个参数表示:算法 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); // 对加密进行初始化 // 第一个参数:表示模式,有加密模式和解密模式 // 第二个参数:表示秘钥规则 cipher.init(Cipher.DECRYPT_MODE,sks); // 进行解密 byte [] inputBytes = hexStringToBytes(input); byte[] bytes = cipher.doFinal(inputBytes); return new String(bytes); }
加密模式
ECB
Electronic codebook, 电子密码本. 需要加密的消息按照块密码的块大小被分为数个块,并对每个块进行独立加密
优点:并行加密,速度快
缺点:同样的明文,加密成同样的密文,容易被破解,不利于安全保护CBC
优点:同样的原文生成不同的密文
缺点:串行处理,速度慢
注意: 需要一个初始的向量值IV
填充模式
当需要按块处理的数据, 数据长度不符合块处理需求时, 按照一定的方法填充满块长的规则
NoPadding
不填充.
在DES加密算法下, 要求原文长度必须是8byte的整数倍
在AES加密算法下, 要求原文长度必须是16byte的整数倍PKCS5Padding
数据块的大小为8位, 不够就补足
注意
默认情况下, 加密模式和填充模式为 : ECB/PKCS5Padding
如果使用CBC模式, 在初始化Cipher对象时, 需要增加参数, 初始化向量IV : IvParameterSpec iv = new IvParameterSpec(key.getBytes());
加密模式和填充模式
AES/CBC/NoPadding (128) AES/CBC/PKCS5Padding (128) AES/ECB/NoPadding (128) AES/ECB/PKCS5Padding (128) DES/CBC/NoPadding (56) DES/CBC/PKCS5Padding (56) DES/ECB/NoPadding (56) DES/ECB/PKCS5Padding (56) DESede/CBC/NoPadding (168) DESede/CBC/PKCS5Padding (168) DESede/ECB/NoPadding (168) DESede/ECB/PKCS5Padding (168) RSA/ECB/PKCS1Padding (1024, 2048) RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048) RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)
使用加密模式和填充模式的案例
private String encryptByAES(String input,String key) throws Exception { // 算法 String algorithm = "AES"; String transformation = "AES/CBC/PKCS5Padding"; // Cipher:密码,获取加密对象 // transformation:参数表示使用什么类型加密 Cipher cipher = Cipher.getInstance(transformation); // 指定秘钥规则 // 第一个参数表示:密钥,key的字节数组 长度必须是16位 // 第二个参数表示:算法 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); // 初始向量值长度必须是16位 String ivStr = "2222222222222221"; IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes()); // 对加密进行初始化 // 第一个参数:表示模式,有加密模式和解密模式 // 第二个参数:表示秘钥规则 cipher.init(Cipher.ENCRYPT_MODE,sks,iv); // 进行加密 byte[] bytes = cipher.doFinal(input.getBytes()); return bytesToHexString(bytes); } private String decryptByAES(String input,String key)throws Exception{ // 算法 String algorithm = "AES"; String transformation = "AES/CBC/PKCS5Padding"; // Cipher:密码,获取加密对象 // transformation:参数表示使用什么类型加密 Cipher cipher = Cipher.getInstance(transformation); // 指定秘钥规则 // 第一个参数表示:密钥,key的字节数组 长度必须是16位 // 第二个参数表示:算法 SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm); // 初始向量值长度必须是16位 String ivStr = "2222222222222221"; IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes()); // 对加密进行初始化 // 第一个参数:表示模式,有加密模式和解密模式 // 第二个参数:表示秘钥规则 cipher.init(Cipher.DECRYPT_MODE,sks,iv); // 进行解密 byte [] inputBytes = hexStringToBytes(input); byte[] bytes = cipher.doFinal(inputBytes); return new String(bytes); }
总结
上一篇:springboot配置Jackson返回统一默认值的实现示例
栏 目:JAVA代码
本文标题:Java中的对称加密详解
本文地址:http://www.codeinn.net/misctech/217567.html