对称加密算法
加密密钥=解密密钥
常用对称加密算法DES,由于DES长度限制,又衍生出3DES, 三重DES
取代DES 有AES
PBE
IDEA
DES 数据加密标准,98年之后被破解,DES已经不安全了
DES 总结:
实例:jdk方式des加解密
package com.example.encryption; import org.apache.commons.codec.binary.Hex; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; /** * @author xuanyouwu * @email [email protected] * @time 2016-05-16 09:31 */ public class DesTest { private static String SrcData = "xuanyouwu"; public static void log(String s) { System.out.println("------>" + s); } public static void main(String[] args) throws Exception { jdkDes(SrcData); } private static void jdkDes(String src) { try { //生成key KeyGenerator des = KeyGenerator.getInstance("DES"); des.init(56);//56或者64位 默认长度56 //产生密钥 SecretKey secretKey = des.generateKey(); //获取密钥 byte[] encoded = secretKey.getEncoded(); //key的转换 DESKeySpec desKeySpec = new DESKeySpec(encoded); SecretKeyFactory des1 = SecretKeyFactory.getInstance("DES"); SecretKey convertKey = des1.generateSecret(desKeySpec); //加密 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, convertKey); byte[] bytes = cipher.doFinal(src.getBytes()); log("des encode:" + Hex.encodeHexString(bytes)); cipher.init(Cipher.DECRYPT_MODE, convertKey); byte[] decodeBytes = cipher.doFinal(bytes); log("des decode:" + new String(decodeBytes)); } catch (Exception e) { e.printStackTrace(); } } }
运行结果:
------>des encode:0c4ded77e2db4b98e65ea0aaf1bf7a55
------>des decode:xuanyouwu
bouncy castle架包下载地址
实例2:BC方式DES加解密
<pre name="code" class="java">package com.example.encryption; import org.apache.commons.codec.binary.Hex; import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; /** * @author xuanyouwu * @email [email protected] * @time 2016-05-16 09:31 */ public class DesTest { private static String SrcData = "xuanyouwu"; public static void log(String s) { System.out.println("------>" + s); } public static void main(String[] args) throws Exception { bcDes(SrcData); } //这里采用 bc补充jdk方式 private static void bcDes(String src) { try { KeyGenerator des = KeyGenerator.getInstance("DES"); log("user provider:" + des.getProvider()); des = KeyGenerator.getInstance("DES", new BouncyCastleProvider()); log("user provider2:" + des.getProvider()); des.init(56); SecretKey secretKey = des.generateKey(); byte[] encoded = secretKey.getEncoded(); //key转换 DESKeySpec desKeySpec = new DESKeySpec(encoded); SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES"); SecretKey secretKey1 = secretKeyFactory.generateSecret(desKeySpec); //加密 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey1); byte[] bytes = cipher.doFinal(src.getBytes()); log("bc des encode1:" + Hex.encodeHexString(bytes)); //解密 cipher.init(Cipher.DECRYPT_MODE, secretKey1); byte[] decodeBytes = cipher.doFinal(bytes); log("bc des decode1:" + new String(decodeBytes)); } catch (Exception e) { e.printStackTrace(); } } }
可以看到bc方式与jdk方式产生的密钥16进制 不一致,但是都能解密出原字符串
Security.addProvider(new BouncyCastleProvider());(直接扩充Jdk)以jdk原生方式使用,或者 KeyGenerator.getInstance("DES",newBouncyCastleProvider());
与Bc的原始方式等同(需要去找某个具体的类)
三重DES的好处:
1:密钥长度增强
2:迭代次数提高
3DES总结:
实例:JDK 3DES加解密
package com.example.encryption; import org.apache.commons.codec.binary.Hex; import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; /** * @author xuanyouwu * @email [email protected] * @time 2016-05-16 10:18 * <p/> * 三重des */ public class Des3Test { private static String SrcData = "xuanyouwu"; public static void log(String s) { System.out.println("------>" + s); } public static void main(String[] args) throws Exception { jdk3des(SrcData); } private static void jdk3des(String src) { try { KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede"); keyGenerator.init(168); SecretKey secretKey = keyGenerator.generateKey(); byte[] encoded = secretKey.getEncoded(); //转换key DESedeKeySpec deSedeKeySpec = new DESedeKeySpec(encoded); SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DESede"); SecretKey secretKey1 = secretKeyFactory.generateSecret(deSedeKeySpec); //加密 Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey1); byte[] bytes = cipher.doFinal(src.getBytes()); log("3des encode:" + Hex.encodeHexString(bytes)); //解密 cipher.init(Cipher.DECRYPT_MODE, secretKey1); byte[] bytes1 = cipher.doFinal(bytes); log("3des decode:" + new String(bytes1)); } catch (Exception e) { e.printStackTrace(); } } }运行结果:
------>3des encode:317ecbf6634aff55f18a1527db114453
------>3des decode:xuanyouwu
实例4:BC 3DES实现
package com.example.encryption; import org.apache.commons.codec.binary.Hex; import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; /** * @author xuanyouwu * @email [email protected] * @time 2016-05-16 10:18 * <p/> * 三重des */ public class Des3Test { private static String SrcData = "xuanyouwu"; public static void log(String s) { System.out.println("------>" + s); } public static void main(String[] args) throws Exception { bc3des(SrcData); } private static void bc3des(String src) { try { Security.addProvider(new BouncyCastleProvider()); KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede"); log("user provider1:" + keyGenerator.getProvider()); keyGenerator = KeyGenerator.getInstance("DESede", "BC");//指定以BC方式处理 log("user provider2:" + keyGenerator.getProvider()); keyGenerator.init(168);//keyGenerator.init(new SecureRandom()); SecretKey secretKey = keyGenerator.generateKey(); byte[] encoded = secretKey.getEncoded(); //转换key DESedeKeySpec deSedeKeySpec = new DESedeKeySpec(encoded); SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DESede"); SecretKey secretKey1 = secretKeyFactory.generateSecret(deSedeKeySpec); //加密 Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey1); byte[] bytes = cipher.doFinal(src.getBytes()); log("bc 3des encode:" + Hex.encodeHexString(bytes)); //解密 cipher.init(Cipher.DECRYPT_MODE, secretKey1); byte[] bytes1 = cipher.doFinal(bytes); log("bc 3des decode:" + new String(bytes1)); } catch (Exception e) { e.printStackTrace(); } } }
------>user provider1:SunJCE version 1.8
------>user provider2:BC version 1.54
------>bc 3des encode:23253e57b3d15a2baba35801cc88ad40
------>bc 3des decode:xuanyouwu
对称加密算法AES
DES算法有一些漏洞,3DES 速度稍微有点慢,所以出现了AES
AES是目前使用最多的对称加密算法
AES的优势之一是至今尚未被破解
AES通常用于移动通信系统加密以及基于SSH协议的软件,比如SSH Client,secureCRT
AES总结:
无政策限制文件是指,因为某些国家的进口限制,Java的发布的运行环境包中的加解密有一定的限制
实例5:JDK 实现AES加解密
package com.example.encryption; import org.apache.commons.codec.binary.Hex; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; /** * @author xuanyouwu * @email [email protected] * @time 2016-05-16 10:39 */ public class AesTest { private static String SrcData = "xuanyouwu"; public static void log(String s) { System.out.println("------>" + s); } public static void main(String[] args) throws Exception { jdkAES(SrcData); } private static void jdkAES(String src) { try { //生成key KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(128); //产生密钥 SecretKey secretKey = keyGenerator.generateKey(); //获取密钥 byte[] keyBytes = secretKey.getEncoded(); //转换key SecretKeySpec key = new SecretKeySpec(keyBytes, "AES"); //加密 Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] bytes = cipher.doFinal(src.getBytes()); log("jdk AES encode:" + Hex.encodeHexString(bytes)); //解密 cipher.init(Cipher.DECRYPT_MODE, key); byte[] bytes1 = cipher.doFinal(bytes); log("jdk AES decode:" + new String(bytes1)); } catch (Exception e) { e.printStackTrace(); } } }
------>jdk AES encode:0e7ce8fe9e9d1b6df3390e89a5a36e2f
------>jdk AES decode:xuanyouwu
实例6:BC方式 实现AES加解密
package com.example.encryption; import org.apache.commons.codec.binary.Hex; import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; /** * @author xuanyouwu * @email [email protected] * @time 2016-05-16 10:39 */ public class AesTest { private static String SrcData = "xuanyouwu"; public static void log(String s) { System.out.println("------>" + s); } public static void main(String[] args) throws Exception { bcAes(SrcData); } private static void bcAes(String src) { try { //生成key KeyGenerator keyGenerator = KeyGenerator.getInstance("AES", new BouncyCastleProvider()); keyGenerator.init(128); //产生密钥 SecretKey secretKey = keyGenerator.generateKey(); //获取密钥 byte[] keyBytes = secretKey.getEncoded(); //转换key SecretKeySpec key = new SecretKeySpec(keyBytes, "AES"); //加密 Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] bytes = cipher.doFinal(src.getBytes()); log("bc AES encode:" + Hex.encodeHexString(bytes)); //解密 cipher.init(Cipher.DECRYPT_MODE, key); byte[] bytes1 = cipher.doFinal(bytes); log("bc AES decode:" + new String(bytes1)); } catch (Exception e) { e.printStackTrace(); } } }
------>bc AES encode:c6eb6aff30fca5f08320e996f23b8f2d
------>bc AES decode:xuanyouwu
对称加密算法-PBE
PBE算法结合了消息摘要算法和对称加密算法的优点
PBC(Password Based Encription)基于口令加密
加盐的目的,也就是扰码
对已有算法的包装
实现方式JDK,BC
实例7:jdk方式实现PBE 加解密
package com.example.encryption; import org.apache.commons.codec.binary.Hex; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; /** * @author xuanyouwu * @email [email protected] * @time 2016-05-16 11:04 */ public class PbeTest { private static String SrcData = "xuanyouwu"; public static void log(String s) { System.out.println("------>" + s); } public static void main(String[] args) throws Exception { jdkPBE(SrcData); } private static void jdkPBE(String src) { try { //初始化盐 SecureRandom random = new SecureRandom(); byte[] salt = random.generateSeed(8); //口令与密钥 String password = "xyw"; PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray()); SecretKeyFactory pbewithmd5andDES = SecretKeyFactory.getInstance("PBEWITHMD5andDES"); SecretKey secretKey = pbewithmd5andDES.generateSecret(pbeKeySpec); //加密 PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, 100); Cipher cipher = Cipher.getInstance("PBEWITHMD5andDES"); cipher.init(Cipher.ENCRYPT_MODE, secretKey, pbeParameterSpec); byte[] encodeBytes = cipher.doFinal(src.getBytes()); log("jdk PBE encode:" + Hex.encodeHexString(encodeBytes)); //解密 cipher.init(Cipher.DECRYPT_MODE, secretKey, pbeParameterSpec); byte[] decodeBytes = cipher.doFinal(encodeBytes); log("jdk PBE decode:" + new String((decodeBytes))); } catch (Exception e) { e.printStackTrace(); } } }
------>jdk PBE encode:8b2cded61e8d30be1150cc079840d757
------>jdk PBE decode:xuanyouwu