赞
踩
对称加密算法是指加密和解密采用相同的密钥,是可逆的(即可解密)。
AES加密算法是密码学中的高级加密标准,采用的是对称分组密码体制,密钥长度的最少支持为128。AES加密算法是美国联邦政府采用的区块加密标准,这个标准用来替代原先的DES,已经被多方分析且广为全世界使用。
AES数学原理详解:AES加密 - block2016 - 博客园
优点:加密速度快
缺点:密钥的传递和保存是一个问题,参与加密和解密的双方使用的密钥是一样的,这样密钥就很容易泄露。
非对称加密算法是指加密和解密采用不同的密钥(公钥和私钥),因此非对称加密也叫公钥加密,是可逆的(即可解密)。公钥密码体制根据其所依据的难题一般分为三类:大素数分解问题类、离散对数问题类、椭圆曲线类。
RSA加密算法是基于一个十分简单的数论事实:将两个大素数(也就是质数:质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数,例如:17、19、23、29、31、37、41等)相乘十分容易,但是想要对其乘积进行因式分解极其困难,因此可以将乘积公开作为加密密钥。虽然RSA的安全性一直未能得到理论上的证明,但它经历了各种攻击至今未被完全攻破。
RSA公私钥生成流程
随机找两个素数P和Q,P与Q越大,越安全。(例如:61和53)
计算p和q的乘积n。(n=61×53=3233,n的长度就是密钥长度。3233写成二进制是110010100001,一共有12位,所以这个密钥就是12位。)
计算 n 的欧拉函数φ(n)。(根据公式φ(n)=(p-1)(q-1)算出φ(3233)等于60×52,即3120)
随机选择一个整数e,条件是1<e<φ(n),且e与φ(n) 互质。(条件是1<e<φ(n),且e与φ(n) 互质。1到3120之间,随机选择了17。)
有一个整数d,可以使得ed 除以φ(n) 的余数为 1。(ed ≡ 1 (mod φ(n)),即17*2753 mode 3120=1)
将n和e封装成公钥,n和d封装成私钥。(n=3233,e=17,d=2753,所以公钥就是:3233,17,私钥就是:3233, 2753。)
RSA加密
首先对明文进行比特串分组,使得每个分组对应的十进制数小于n,然后依次对每个分组m做一次加密,所有分组的密文构成的序列就是原始消息的加密结果,即m满足0<=m<n,则加密算法为:c=m^e mod n; c为密文,且0<=c<n。
欧拉函数
一.什么是欧拉函数
欧拉函数就是指:对于一个正整数n,小于或等于n的正整数中与n互质的正整数个数(包括1)的个数,记作 φ ( n )所以其通式为: φ ( n ) = n * (1 - 1/p1) * (1 - 1/p2) * …… * (1 - 1/pn),其中p1,p2……pn为n的所有质因数,例如:φ ( 10 ) 的质因数为2,5,所有φ ( 10 ) = 10 * (1 - 1/2) * (1 - 1/5) = 4(1,3,7,9这四个数)
同时φ ( 1 ) = 1;二.欧拉函数的一些性质
若n为质数,则φ ( n ) = n - 1;
若m与n互质,则φ ( n*m ) = φ ( n ) * φ ( m );
若正整数n与a互质,那么就有
若n为奇数时,φ ( 2n ) = φ ( n );
若n = pk且p是质数,那么φ ( n ) = (p - 1) * pk-1 = pk - pk-1
优点:512位(或是1024位)秘钥,计算量极大,难破解。加密和解密的密钥不一致,公钥是可以公开的,只需保证私钥不被泄露即可,这样就密钥的传递变的简单很多,从而降低了被破解的几率。
缺点:加密速度慢
RSA加密算法既可以用来做数据加密,也可以用来数字签名。
数据加密过程:甲方用乙方的公钥加密,乙方用自己的私钥解密(甲方为发送者,乙方为接受者,乙方事先提供自己的公钥给甲方,简称:公钥加密,私钥解密)
数字签名过程:甲方用甲方的私钥加密,乙方用甲方的公钥解密(甲方为发送者,乙方为接受者,乙方解密成功说明就是甲方加的密,甲方就不可以抵赖,乙方解密需要甲方提供的公钥,简称:私钥签名,公钥验签)
详细数学原理见 【来龙去脉系列】RSA算法原理
ECC加密算法是基于椭圆曲线上离散对数计算问题(ECDLP)的ECC算法。ECC算法的数学理论非常深奥和复杂,在工程应用中比较难于实现,但它的单位安全强度相对较高。
用国际上公认的对于ECC算法最有效的攻击方法--Pollard rho方法去破译和攻击ECC算法,它的破译或求解难度基本上是指数级的。正是由于RSA算法和ECC算法这一明显不同,使得ECC算法的单位安全强度高于RSA算法,也就是说,要达到同样的安全强度,ECC算法所需的密钥长度远比RSA算法低。有研究表示160位的椭圆密钥与1024位的RSA密钥安全性相同。在私钥的加密解密速度上,ECC算法比RSA、DSA速度更快。存储空间占用更小。
MD5全称是Message-Digest Algorithm 5(信息摘要算法5),单向的算法不可逆(被MD5加密的数据不能被解密)。MD5加密后的数据长度要比加密数据小的多,且长度固定,且加密后的串是唯一的,MD5散列值长度位128位。
适用场景:常用在不可还原的密码存储、信息完整性校验等。
信息完整性校验:典型的应用是对一段信息产生信息摘要,以防止被篡改。如果再有一个第三方的认证机构,用MD5还可以防止文件作者的“抵赖”,这就是所谓的数字签名应用。
SHA-1 与 MD5 的比较
SHA-1摘要比MD5摘要长32 位,散列值长度160位,所以SHA-1对强行攻击有更大的强度,比MD5更安全。使用强行技术,产生任何一个报文使其摘要等于给定报摘要的难度对MD5是2^128数量级的操作,而对SHA-1则是2^160数量级的操作。
在相同的硬件上,SHA-1 的运行速度比 MD5 慢。
由于以上加密算法都有各自的缺点(RSA加密速度慢、AES密钥存储问题、MD5加密不可逆),因此实际应用时常将几种加密算法混合使用。
例如:RSA+DES,RSA+AES:
采用DES对数据进行加密,而RSA对DES的密钥加密,这样集成了两种加密算法的优点,既保证了数据加密的速度,又实现了安全方便的密钥管理。
那么,采用多少位的密钥合适呢?一般来讲密钥长度越长,安全性越高,但是加密速度越慢。所以密钥长度也要合理的选择,一般RSA建议采用1024位的数字,AES建议采用128位即可。
混合加密代码案例:RSA+DES
- /**
- * RSA加密
- * @param data 待加密数据
- * @param publicKey 公钥
- */
- public static String rsaEncrypt(String data, PublicKey publicKey) throws Exception {
- Cipher cipher = Cipher.getInstance(ALGORITHM_NAME);
- cipher.init(Cipher.ENCRYPT_MODE, publicKey);
- int inputLen = data.getBytes().length;
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- int offset = 0;
- byte[] cache;
- int i = 0;
- // 对数据分段加密
- while (inputLen - offset > 0) {
- if (inputLen - offset > MAX_ENCRYPT_BLOCK) {
- cache = cipher.doFinal(data.getBytes(), offset, MAX_ENCRYPT_BLOCK);
- } else {
- cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset);
- }
- out.write(cache, 0, cache.length);
- i++;
- offset = i * MAX_ENCRYPT_BLOCK;
- }
- byte[] encryptedData = out.toByteArray();
- out.close();
- return Base64.encodeBase64String(encryptedData);
- }
-
- /**
- * RSA解密
- * @param secretData 待解密数据
- * @param privateKey 私钥
- */
- public static String rsaDecrypt(String secretData, PrivateKey privateKey) throws Exception {
- Cipher cipher = Cipher.getInstance(ALGORITHM_NAME);
- cipher.init(Cipher.DECRYPT_MODE, privateKey);
- byte[] dataBytes = Base64.decodeBase64(secretData);
- int inputLen = dataBytes.length;
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- int offset = 0;
- byte[] cache;
- int i = 0;
- // 对数据分段解密
- while (inputLen - offset > 0) {
- if (inputLen - offset > MAX_DECRYPT_BLOCK) {
- cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK);
- } else {
- cache = cipher.doFinal(dataBytes, offset, inputLen - offset);
- }
- out.write(cache, 0, cache.length);
- i++;
- offset = i * MAX_DECRYPT_BLOCK;
- }
- byte[] decryptedData = out.toByteArray();
- out.close();
- return new String(decryptedData, StandardCharsets.UTF_8);// 解密后的内容
- }
-
-
- /**
- * DES加密
- * @param data 待加密数据
- * @param desKey 长度要是8的倍数且不能小于8位
- * @return String
- */
- public static String desEncrypt(String data, String desKey) {
- try{
- if (desKey== null || desKey.length() < 8) {
- throw new RuntimeException("加密失败,desKey不能小于8位");
- }
- SecureRandom random = new SecureRandom();
- DESKeySpec desKeySpec = new DESKeySpec(desKey.getBytes());
- //创建一个密匙工厂,然后用它把DESKeySpec转换成
- SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
- SecretKey securekey = keyFactory.generateSecret(desKeySpec);
- //Cipher对象实际完成加密操作
- Cipher cipher = Cipher.getInstance("DES");
- //用密匙初始化Cipher对象
- cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
- //现在,获取数据并加密
- //正式执行加密操作
- byte[] encryptedData = cipher.doFinal(data.getBytes());
- return Base64.encodeBase64String(encryptedData);
- }catch(Throwable e){
- e.printStackTrace();
- }
- return null;
- }
-
- /**
- * DES解密
- * @param secretData base64编码得解密数据
- * @param desKey
- * @return byte[]
- * @throws Exception
- */
- public static String desDecrypt(String secretData, String desKey) throws Exception {
- // DES算法要求有一个可信任的随机数源
- SecureRandom random = new SecureRandom();
- // 创建一个DESKeySpec对象
- DESKeySpec desKeySpec = new DESKeySpec(desKey.getBytes(StandardCharsets.UTF_8));
- // 创建一个密匙工厂
- SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
- // 将DESKeySpec对象转换成SecretKey对象
- SecretKey securekey = keyFactory.generateSecret(desKeySpec);
- // Cipher对象实际完成解密操作
- Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
- // 用密匙初始化Cipher对象
- cipher.init(Cipher.DECRYPT_MODE, securekey, random);
- // 真正开始解密操作
- byte[] decryptedData = cipher.doFinal(Base64.decodeBase64(secretData));
- return new String(decryptedData,StandardCharsets.UTF_8);
- }
-
- /**
- * RSA和DES混合加密
- * @param data 待加密数据
- * @param publicKey RSA公钥
- * @return
- */
- public static Map<String,Object> encrypt(String data, String publicKey) throws Exception {
- String desKey = getRandomKey();//随机生成密钥
- String encryptData = desEncrypt(data,desKey);//用des加密原数据
- String encryptDESKey = rsaEncrypt(desKey,getPublicKey(publicKey));//用RSA加密deskey
- Map dataMap = new HashMap();
- dataMap.put("secretData",encryptData);
- dataMap.put("desKey",encryptDESKey);
- log.info("待加密随机DES秘钥->desKey:"+desKey);
- return dataMap;
- }
-
- /**
- * RSA和DES混合解密
- * @param secretData 待解密数据
- * @param desKey 通过Rsa加密的DESKey
- * @param privateKey RSA私钥
- * @return
- */
- public static String decrypt(String secretData, String desKey, String privateKey) throws Exception {
- //使用Rsa解密DESKey,用到私钥privateKey
- String decryptDESKey = rsaDecrypt(desKey,getPrivateKey(privateKey));
- log.info("已解密随机DES秘钥->desKey:"+decryptDESKey);
- //再使用des解密数据,用到已解密出的DESKey
- return desDecrypt(secretData,decryptDESKey);
- }
-
- public static void main(String[] args) throws Exception {
- String str = "你好啊,JAVA!";
- log.info("待加密数据:"+str.trim());
- Map keyMap = getKeyPairMap();//RSA生成秘钥对
- String publicKey = keyMap.get("publicKey").toString();//Rsa公钥
- String privateKey = keyMap.get("privateKey").toString();//Rsa私钥
- log.info("RSA秘钥对->publicKey:"+publicKey);
- log.info("RSA秘钥对->privateKey:"+privateKey);
- Map<String,Object> dataMap = encrypt(str.trim(), publicKey);
- log.info("已加密数据:" + JSONObject.toJSONString(dataMap));
- String desKey = dataMap.get("desKey").toString();//已加密的desKey
- log.info("已加密的DES秘钥->desKey:"+desKey);
- String secretData = dataMap.get("secretData").toString();//待解密数据
- String data = decrypt(secretData, desKey, privateKey);
- log.info("已解密数据:" + data.trim());
- }

严格意义讲,Base64并不能算是一种加密算法,而是一种编码格式,是网络上最常见的用于传输8bid字节代码的编码方式之一。
Base64编码可用于在HTTP环境下传递较长的标识信息,Base编码不仅不仅比较简单,同时也据有不可读性
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。