加密算法中BASE64、MD5、SHA、HMAC等之间的区别
MD5、SHA、HMAC这三种加密算法,可谓是非可逆加密,就是不可解密的加密方法,我们称之为单向加密算法。我们通常只把他们作为加密的基础。单纯的以上三种的加密并不可靠。
BASE64
按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.)
常见于邮件、http加密,截取http信息,你就会发现登录操作的用户名、密码字段通过BASE64加密的。
通过Java代码实现如下:
- /**
- * BASE64解密
- *
- * @param key
- * @return
- * @throws Exception
- */
- public static byte[] decryptBASE64(String key) throws Exception {
- return (new BASE64Decoder()).decodeBuffer(key);
- }
- /**
- * BASE64加密
- *
- * @param key
- * @return
- * @throws Exception
- */
- public static String encryptBASE64(byte[] key) throws Exception {
- return (new BASE64Encoder()).encodeBuffer(key);
- }
主要就是BASE64Encoder、BASE64Decoder两个类,我们只需要知道使用对应的方法即可。另,BASE加密后产生的字节位数是8的倍数,如果不够位数以=符号填充。
MD5
MD5 -- message-digest algorithm 5 (信息-摘要算法)缩写,广泛用于加密和解密技术,常用于文件校验。校验?不管文件多大,经过MD5后都能生成唯一的MD5值。好比现在的ISO校验,都是MD5校验。怎么用?当然是把ISO经过MD5后产生MD5的值。一般下载linux-ISO的朋友都见过下载链接旁边放着MD5的串。就是用来验证文件是否一致的。
通过java代码实现如下:
- /**
- * MD5加密
- *
- * @param data
- * @return
- * @throws Exception
- */
- public static byte[] encryptMD5(byte[] data) throws Exception {
- MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
- md5.update(data);
- return md5.digest();
- }
通常我们不直接使用上述MD5加密。通常将MD5产生的字节数组交给BASE64再加密一把,得到相应的字符串。
SHA
SHA(Secure Hash Algorithm,安全散列算法),数字签名等密码学应用中重要的工具,被广泛地应用于电子商务等信息安全领域。虽然,SHA与MD5通过碰撞法都被破解了, 但是SHA仍然是公认的安全加密算法,较之MD5更为安全。
通过java代码实现如下:
- /**
- * SHA加密
- *
- * @param data
- * @return
- * @throws Exception
- */
- public static byte[] encryptSHA(byte[] data) throws Exception {
- MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
- sha.update(data);
- return sha.digest();
- }
- }
HMAC
HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议。消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。
通过java代码实现如下:
- /**
- * 初始化HMAC密钥
- *
- * @return
- * @throws Exception
- */
- public static String initMacKey() throws Exception {
- KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);
- SecretKey secretKey = keyGenerator.generateKey();
- return encryptBASE64(secretKey.getEncoded());
- }
- /**
- * HMAC加密
- *
- * @param data
- * @param key
- * @return
- * @throws Exception
- */
- public static byte[] encryptHMAC(byte[] data, String key) throws Exception {
- SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);
- Mac mac = Mac.getInstance(secretKey.getAlgorithm());
- mac.init(secretKey);
- return mac.doFinal(data);
- }
给出一个完整类,如下:
- import java.security.MessageDigest;
- import javax.crypto.KeyGenerator;
- import javax.crypto.Mac;
- import javax.crypto.SecretKey;
- import sun.misc.BASE64Decoder;
- import sun.misc.BASE64Encoder;
- /**
- * 基础加密组件
- *
- * @author 梁栋
- * @version 1.0
- * @since 1.0
- */
- public abstract class Coder {
- public static final String KEY_SHA = "SHA";
- public static final String KEY_MD5 = "MD5";
- /**
- * MAC算法可选以下多种算法
- *
- * <pre>
- * HmacMD5
- * HmacSHA1
- * HmacSHA256
- * HmacSHA384
- * HmacSHA512
- * </pre>
- */
- public static final String KEY_MAC = "HmacMD5";
- /**
- * BASE64解密
- *
- * @param key
- * @return
- * @throws Exception
- */
- public static byte[] decryptBASE64(String key) throws Exception {
- return (new BASE64Decoder()).decodeBuffer(key);
- }
- /**
- * BASE64加密
- *
- * @param key
- * @return
- * @throws Exception
- */
- public static String encryptBASE64(byte[] key) throws Exception {
- return (new BASE64Encoder()).encodeBuffer(key);
- }
- /**
- * MD5加密
- *
- * @param data
- * @return
- * @throws Exception
- */
- public static byte[] encryptMD5(byte[] data) throws Exception {
- MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
- md5.update(data);
- return md5.digest();
- }
- /**
- * SHA加密
- *
- * @param data
- * @return
- * @throws Exception
- */
- public static byte[] encryptSHA(byte[] data) throws Exception {
- MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
- sha.update(data);
- return sha.digest();
- }
- /**
- * 初始化HMAC密钥
- *
- * @return
- * @throws Exception
- */
- public static String initMacKey() throws Exception {
- KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);
- SecretKey secretKey = keyGenerator.generateKey();
- return encryptBASE64(secretKey.getEncoded());
- }
- /**
- * HMAC加密
- *
- * @param data
- * @param key
- * @return
- * @throws Exception
- */
- public static byte[] encryptHMAC(byte[] data, String key) throws Exception {
- SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);
- Mac mac = Mac.getInstance(secretKey.getAlgorithm());
- mac.init(secretKey);
- return mac.doFinal(data);
- }
- }
再给出一个测试类:
- import static org.junit.Assert.*;
- import org.junit.Test;
- /**
- *
- * @author 梁栋
- * @version 1.0
- * @since 1.0
- */
- public class CoderTest {
- @Test
- public void test() throws Exception {
- String inputStr = "简单加密";
- System.err.println("原文:/n" + inputStr);
- byte[] inputData = inputStr.getBytes();
- String code = Coder.encryptBASE64(inputData);
- System.err.println("BASE64加密后:/n" + code);
- byte[] output = Coder.decryptBASE64(code);
- String outputStr = new String(output);
- System.err.println("BASE64解密后:/n" + outputStr);
- // 验证BASE64加密解密一致性
- assertEquals(inputStr, outputStr);
- // 验证MD5对于同一内容加密是否一致
- assertArrayEquals(Coder.encryptMD5(inputData), Coder
- .encryptMD5(inputData));
- // 验证SHA对于同一内容加密是否一致
- assertArrayEquals(Coder.encryptSHA(inputData), Coder
- .encryptSHA(inputData));
- String key = Coder.initMacKey();
- System.err.println("Mac密钥:/n" + key);
- // 验证HMAC对于同一内容,同一密钥加密是否一致
- assertArrayEquals(Coder.encryptHMAC(inputData, key), Coder.encryptHMAC(
- inputData, key));
- BigInteger md5 = new BigInteger(Coder.encryptMD5(inputData));
- System.err.println("MD5:/n" + md5.toString(16));
- BigInteger sha = new BigInteger(Coder.encryptSHA(inputData));
- System.err.println("SHA:/n" + sha.toString(32));
- BigInteger mac = new BigInteger(Coder.encryptHMAC(inputData, inputStr));
- System.err.println("HMAC:/n" + mac.toString(16));
- }
- }
控制台输出:
- 原文:
- 简单加密
- BASE64加密后:
- 566A5Y2V5Yqg5a+G
- BASE64解密后:
- 简单加密
- Mac密钥:
- uGxdHC+6ylRDaik++leFtGwiMbuYUJ6mqHWyhSgF4trVkVBBSQvY/a22xU8XT1RUemdCWW155Bke
- pBIpkd7QHg==
- MD5:
- -550b4d90349ad4629462113e7934de56
- SHA:
- 91k9vo7p400cjkgfhjh0ia9qthsjagfn
- HMAC:
- 2287d192387e95694bdbba2fa941009a
- 顶
- 0
- 踩
加密算法中BASE64、MD5、SHA、HMAC等之间的区别的更多相关文章
- BASE64,MD5,SHA,HMAC加密與解密算法(java)
package com.ice.webos.util.security; import java.io.UnsupportedEncodingException; import java.math.B ...
- Spring中Model、ModelMap及ModelAndView之间的区别
Spring中Model.ModelMap及ModelAndView之间的区别 1. Model(org.springframework.ui.Model)Model是一个接口,包含addAttr ...
- C#中string.Empty、""和null 之间的区别
1.C#中string.Empty.""和null 之间的区别 (http://blog.csdn.net/henulwj/article/details/7830615)
- mysql 中execute、executeQuery和executeUpdate之间的区别
在用纯JSP做一个页面报警功能的时候习惯性的用executeQuery来执行SQL语句,结果执行update时就遇到问题,语句能执行,但返回结果出现问题,另外还忽略了executeUpdate的返回值 ...
- C++中指针和引用、数组之间的区别
指针指向一块内存,它的内容是所指内存的地址:而引用则是某块内存的别名,引用初始化后不能改变指向.使用时,引用更加安全,指针更加灵活. 初始化.引用必须初始化,且初始化之后不能呢改变:指针可以不必初始化 ...
- Android中dip, dp, px,pt, sp之间的区别:
Android中dip.dp.sp.pt和px的区别 1.概述 过去,程序员通常以像素为单位设计计算机用户界面.例如:图片大小为80×32像素.这样处理的问题在于,如果在一个每英寸点数(dpi)更 ...
- iOS中assign,copy,retain之间的区别以及weak和strong的区别
@property (nonatomic, assign) NSString *title; 什么是assign,copy,retain之间的区别? assign: 简单赋值,不更改索引计数(Refe ...
- Java中Scanner类和BufferReader类之间的区别
java.util.Scanner类是一个简单的文本扫描类,它可以解析基本数据类型和字符串.它本质上是使用正则表达式去读取不同的数据类型. Java.io.BufferedReader类为了能够高效的 ...
- mysql中几个日期时间类型之间的区别和使用
MySQL中有如下几个时间类型:date.time.datetime.timestamp.year MySQL数据类型 含义 date 只存 ...
随机推荐
- 我的屌丝giser成长记-研三篇
进入研三以来,基本都是自己的自由时间了,从导师的项目抽离出来,慢慢的都交给师弟他们来负责.研三的核心任务就是找工作以及写毕业论文,因为有导师科研基金项目成果作为支撑,所以自己的论文没什么可担心,一切都 ...
- Atitit.日志系统slf4j的使用
Atitit.日志系统slf4j的使用 SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar ...
- Bundle包的制作与使用
一.清爽Bundle模式(在应用工程中创建Bundle的子文件夹,而非在Bundle项目中): 1.新建Bundle包 2.生成Bundle包,并拖入项目中,然后"右键显示包内容" ...
- ITIS-资料集合贴
ITIS-资料集合贴 说明:这个贴用于收集笔者能力范围内收集收藏并认为有用的资料,方便各方参考,免去到处找寻之苦,提升信息的交叉引用价值.另外,笔者就自己感悟做了部分评注,且可能尝试不断的优化分类和排 ...
- 关于Android中new Notification
目前 Android 已经不推荐使用下列方式创建 Notification实例: Notification notification = new Notification(R.drawable.ic_ ...
- python迭代器实现斐波拉契求值
斐波那契数列(Fibonacci sequence),又称黄金分割数列,也称为"兔子数列":F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*).例 ...
- php类中的魔术方法
1.构造函数 析构函数class pt{ function __construct($data) { echo "pt is start ..."; $this->pr($d ...
- 严重: Exception loading sessions from persistent storage Java.io.EOFException
tomcat启动时报此异常,但web页均能正常运行:对程序影响不大. /*具体原因时tomcat--work--(你当前运行的工程名)--session.ser*/删除即可解决 分析: EOFExce ...
- 阿里技术协会好文推荐:Android绘制流程http://click.aliyun.com/m/8719/
一.前言 1.1.C++界面库 MFC.WTL.DuiLib.QT.Skia.OpenGL.Android里面的画图分为2D和3D两种: 2D是由Skia 来实现的,3D部分是由OpenGL实现的. ...
- Resharper 检测所有NullReferenceExceptions(空指针)
需求分析 "null exception"很见的一种异常,但在某些情况下却会引起严重的bug! 本文目的就是对代码进行null 的检查,避免不应该出现的Error. 本文借助res ...