Java中4大基本加密算法解析
发布日期:2021-09-18 10:05:46 浏览次数:4 分类:技术文章

本文共 9859 字,大约阅读时间需要 32 分钟。

一、前言

人生处世如行路,常有山水阻身前。只有品味了痛苦,才能珍视曾经忽略的快乐;人在路上走,沿途中总会有风雨不定时来袭击,不可能因为有风雨而止步或退缩。迎上风雨,勇敢面对,相信走过风雨后,彩虹的美丽就在前方的风景处等你。

简单的java加密算法有:

  1. BASE64 严格地说,属于编码格式,而非加密算法
  2. MD5(Message Digest algorithm 5,信息摘要算法)
  3. SHA(Secure Hash Algorithm,安全散列算法)
  4. HMAC(Hash Message Authentication Code,散列消息鉴别码)

1. BASE64

1.1 BASE64简介

Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码具有不可读性,即所编码的数据不会被人用肉眼所直接看到。(来源百度百科)

1.2 应用场景

1、服务器给客户端在JSON中传递二进制数据

2、客户端给服务器传递参数时,通过Base64传递二进制内容

1.3 java实现代码

package com.encryptionAlgorithm;import java.io.IOException;import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;/** *  *@类描述 base64加密解密算法 *1.标准base64只有64个字符(英文大小写、数字和+、/)以及用作后缀等号; *2.base64是把3个字节变成4个可打印字符,所以base64编码后的字符串一定能被4整除(不算用作后缀的等号); *3.等号一定用作后缀,且数目一定是0个、1个或2个。这是因为如果原文长度不能被3整除,base64要在后面添加\0凑齐3n位。为了正确还原,添加了几个\0就加上几个等号。显然添加等号的数目只能是0、1或2; *4.严格来说base64不能算是一种加密,只能说是编码转换。使用base64的初衷。是为了方便把含有不可见字符串的信息用可见字符串表示出来,以便复制粘贴; *@author 曾小辉 *@创建时间 2017年1月15日下午9:21:38 */public class Baes64 {
/** * *@方法描述 base64解密 *@作者 爬行的蜗牛 *@创建时间 2017年1月15日下午9:08:44 * @param str * @return * @throws Exception */ public static byte[] decryptBASE64(String str) throws Exception{ //实例一个解密器 BASE64Decoder base64Decoder=new BASE64Decoder(); //解密 byte[] decryptStr=base64Decoder.decodeBuffer(str); return decryptStr; } /** * *@方法描述 base64加密 *@作者 爬行的蜗牛 *@创建时间 2017年1月15日下午9:13:39 * @param str * @return */ public static String encryptBASE64(byte[] str){ //实例一个加密器 BASE64Encoder base64Encoder=new BASE64Encoder(); String encryptStr=base64Encoder.encode(str); return encryptStr; } public static void main(String[] args) { String str="i love java"; String encryptResult=encryptBASE64(str.getBytes()); System.out.println("BASE64加密后: "+encryptResult); try { byte[] decryptResult=decryptBASE64(encryptResult); String decryptStr=new String(decryptResult); System.out.println("BASE64解密后: "+decryptStr); } catch (Exception e) { e.printStackTrace(); } }}

2. MD5

2.1、MD5简介

MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。

MD5算法具有以下特点:
1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。
2、容易计算:从原数据计算出MD5值很容易。
3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被”压缩”成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。

2.2、MD5应用

1、一致性验证

2、数字签名

MD5的典型应用是对一段Message(字节串)产生fingerprint(指纹),以防止被“篡改”。举个例子,你将一段话写在一个叫 readme.txt文件中,并对这个readme.txt产生一个MD5的值并记录在案,然后你可以传播这个文件给别人,别人如果修改了文件中的任何内容,你对这个文件重新计算MD5时就会发现(两个MD5值不相同)。如果再有一个第三方的认证机构,用MD5还可以防止文件作者的“抵赖”,这就是所谓的数字签名应用。

3、安全访问认证

MD5还广泛用于操作系统的登陆认证上,如Unix、各类BSD系统登录密码、数字签名等诸多方面。如在Unix系统中用户的密码是以MD5(或其它类似的算法)经Hash运算后存储在文件系统中。当用户登录的时候,系统把用户输入的密码进行MD5 Hash运算,然后再去和保存在文件系统中的MD5值进行比较,进而确定输入的密码是否正确。通过这样的步骤,系统在并不知道用户密码的明码的情况下就可以确定用户登录系统的合法性。这可以避免用户的密码被具有系统管理员权限的用户知道。MD5将任意长度的“字节串”映射为一个128bit的大整数,并且是通过该128bit反推原始字符串是困难的,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。所以,要遇到了md5密码的问题,比较好的办法是:你可以用这个系统中的md5()函数重新设一个密码,如admin,把生成的一串密码的Hash值覆盖原来的Hash值就行了。

2.3、java实现:

package com.encryptionAlgorithm;import java.math.BigInteger;import java.security.MessageDigest;public class MD5 {
public static final String KEY_MD5 = "MD5"; /** * *@方法描述 MD5加密 *@作者 爬行的蜗牛 *@创建时间 2017年1月15日下午9:59:59 * @param str * @return */ public static String encryptMD5(String str){ BigInteger bigInteger=null; try { MessageDigest md = MessageDigest.getInstance(KEY_MD5); byte[] inputData = str.getBytes(); md.update(inputData); bigInteger = new BigInteger(md.digest()); } catch (Exception e) { e.printStackTrace(); } return bigInteger.toString(16); } public static void main(String[] args) { // TODO Auto-generated method stub String str="I LOVE JAVA"; String result= encryptMD5(str); System.out.println(result); }}

3.SHA

3.1、SHA简介

安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。该算法经过加密专家多年来的发展和改进已日益完善,并被广泛使用。该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。散列函数值可以说是对明文的一种“指纹”或是“摘要”所以对散列值的数字签名就可以视为对此明文的数字签名。

3.2、java实现

package com.encryptionAlgorithm;import java.math.BigInteger;import java.security.MessageDigest;public class SHA {
public static final String KEY_SHA = "SHA"; /** * *@方法描述 SHA加密算法 *@作者 爬行的蜗牛 *@创建时间 2017年1月15日下午10:24:08 * @param str * @return */ public static String encryptSHA(String str){ BigInteger sha =null; byte[] inputData = str.getBytes(); try { MessageDigest messageDigest = MessageDigest.getInstance(KEY_SHA); messageDigest.update(inputData); sha = new BigInteger(messageDigest.digest()); } catch (Exception e) { e.printStackTrace(); } return sha.toString(32); } public static void main(String[] args) { String str="I LOVE JAVA"; String reStr=encryptSHA(str); System.out.println(reStr); }}

SHA-1与MD5的比较

因为二者均由MD4导出,SHA-1和MD5彼此很相似。相应的,他们的强度和其他特性也是相似,但还有以下几点不同:

1、 对强行攻击的安全性:最显著和最重要的区别是SHA-1摘要比MD5摘要长32 位。使用强行技术,产生任何一个报文使其摘要等于给定报摘要的难度对MD5是2^128数量级的操作,而对SHA-1则是2^160数量级的操作。这样,SHA-1对强行攻击有更大的强度。
2、 对密码分析的安全性:由于MD5的设计,易受密码分析的攻击,SHA-1显得不易受这样的攻击。
3、 速度:在相同的硬件上,SHA-1的运行速度比MD5慢。

4.HMAC

4.1、HMAC简介

HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议。消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。

4.2、HMAC应用

1、认证流程

(1) 先由客户端向服务器发出一个验证请求。

(2) 服务器接到此请求后生成一个随机数并通过网络传输给客户端(此为质疑)。
(3) 客户端将收到的随机数提供给ePass,由ePass使用该随机数与存储在ePass中的密钥进行HMAC-MD5运算并得到一个结果作为认证证据传给服务器(此为响应)。
(4) 与此同时,服务器也使用该随机数与存储在服务器数据库中的该客户密钥进行HMAC-MD5运算,如果服务器的运算结果与客户端传回的响应结果相同,则认为客户端是一个合法用户

2、安全性浅析

由上面的介绍,我们可以看出,HMAC算法更象是一种加密算法,它引入了密钥,其安全性已经不完全依赖于所使用的HASH算法,安全性主要有以下几点保证:

(1) 使用的密钥是双方事先约定的,第三方不可能知道。由3.2介绍的应用流程可以看出,作为非法截获信息的第三方,能够得到的信息只有作为“挑战”的随机数和作为“响应”的HMAC结果,无法根据这两个数据推算出密钥。由于不知道密钥,所以无法仿造出一致的响应。

4.3、java实现代码

package com.encryptionAlgorithm;import java.security.NoSuchAlgorithmException;import javax.crypto.KeyGenerator;import javax.crypto.Mac;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;public class HMAC {
private final static String KEY_MAC = "HmacMD5"; /** * 全局数组 */ private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; /** * 初始化HMAC密钥 * @return */ /** * *@方法描述 初始化HMAC密钥,采用BASE64加密解密 *@作者 爬行的蜗牛 *@创建时间 2017年1月15日下午10:41:51 * @return */ public static String init() { SecretKey key; String str = ""; try { KeyGenerator generator = KeyGenerator.getInstance(KEY_MAC); key = generator.generateKey(); str = (new BASE64Encoder()).encodeBuffer(key.getEncoded()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return str; } /** * *@方法描述 HMAC对数组加密 *@作者 爬行的蜗牛 *@创建时间 2017年1月15日下午10:50:09 * @param data * @param key * @return */ public static byte[] encryptHMAC(byte[] data, String key) { SecretKey secretKey; byte[] bytes = null; try { secretKey = new SecretKeySpec((new BASE64Decoder()).decodeBuffer(key), KEY_MAC); Mac mac = Mac.getInstance(secretKey.getAlgorithm()); mac.init(secretKey); bytes = mac.doFinal(data); } catch (Exception e) { e.printStackTrace(); } return bytes; } /** * HMAC加密 * @param data 需要加密的字符串 * @param key 密钥 * @return 字符串 */ /** * *@方法描述 HMAC对字符串加密 *@作者 爬行的蜗牛 *@创建时间 2017年1月15日下午10:47:50 * @param data * @param key * @return */ public static String encryptHMAC(String data, String key) { if (data.isEmpty() && data!=null) { return null; } byte[] bytes = encryptHMAC(data.getBytes(), key); return ByteArrayToHexString(bytes); } /** * *@方法描述 将一个字节转化成十六进制形式的字符串 *@作者 爬行的蜗牛 *@创建时间 2017年1月15日下午10:48:28 * @param b * @return */ private static String byteToHexString(byte b) { int ret = b; if (ret < 0) { ret += 256; } int m = ret / 16; int n = ret % 16; return hexDigits[m] + hexDigits[n]; } /** * *@方法描述 转换字节数组为十六进制字符串 *@作者 爬行的蜗牛 *@创建时间 2017年1月15日下午10:49:30 * @param bytes * @return */ private static String ByteArrayToHexString(byte[] bytes) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < bytes.length; i++) { sb.append(byteToHexString(bytes[i])); } return sb.toString(); } public static void main(String[] args) { String key = HMAC.init(); System.out.println("Mac密钥:\n" + key); String word = "I LOVE JAVA"; System.out.println(encryptHMAC(word, key)); }}

转载地址:https://blog.csdn.net/z694644032/article/details/54171297 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:list遍历方式效率分析
下一篇:linux命令

发表评论

最新留言

不错!
[***.144.177.141]2024年04月02日 08时28分17秒