.NET Core 使用HMAC算法
一. HMAC 简介
通过哈希算法,我们可以验证一段数据是否有效,方法就是对比该数据的哈希值,例如,判断用户口令是否正确,我们用保存在数据库中的password_md5
对比计算md5(password)
的结果,如果一致,用户输入的口令就是正确的。
为了防止黑客通过彩虹表根据哈希值反推原始口令,在计算哈希的时候,不能仅针对原始输入计算,需要增加一个salt来使得相同的输入也能得到不同的哈希,这样,大大增加了黑客破解的难度。
如果salt是我们自己随机生成的,通常我们计算MD5时采用md5(message + salt)
。但实际上,把salt看做一个“口令”,加salt的哈希就是:计算一段message的哈希时,根据不通口令计算出不同的哈希。要验证哈希值,必须同时提供正确的口令。
这实际上就是Hmac算法:Keyed-Hashing for Message Authentication。它通过一个标准算法,在计算哈希的过程中,把key混入计算过程中。
和我们自定义的加salt算法不同,Hmac算法针对所有哈希算法都通用,无论是MD5还是SHA-1。采用Hmac替代我们自己的salt算法,可以使程序算法更标准化,也更安全。
使用hmac和普通hash算法非常类似。hmac输出的长度和原始哈希算法的长度一致。
HMAC算法简介摘自廖雪峰py教程 原文
二. .NET Core 中的使用
.NET Core 中已经由现成的类,可以直接使用,非常方便。主要有五种类型:HMACMD5、HMACSHA1、HMACSHA256、HMACSHA384、HMACSHA512。其使用方法均为一样,输出内容主要有两种,一种是原始字符串,一种是Base64字符串。
以HMACSHA256为例:
Base64
/// <summary>
/// Base64 SHA256
/// </summary>
/// <param name="data">待加密数据</param>
/// <param name="secret">密钥</param>
/// <returns></returns>
public static string EncryptWithSHA256(string data, string secret)
{
secret = secret ?? "";
var encoding = Encoding.UTF8;
byte[] keyByte = encoding.GetBytes(secret);
byte[] dataBytes = encoding.GetBytes(data);
using (var hmac256 = new HMACSHA256(keyByte))
{
byte[] hashData = hmac256.ComputeHash(dataBytes);
return Convert.ToBase64String(hashData);
}
}
原始字符串:
/// <summary>
/// 原始64位 SHA256
/// </summary>
/// <param name="data">待加密数据</param>
/// <param name="secret">密钥</param>
/// <returns></returns>
public static string EncryptWithSHA256Original(string data, string secret)
{
secret = secret ?? "";
var encoding = Encoding.UTF8;
byte[] keyByte = encoding.GetBytes(secret);
byte[] dataBytes = encoding.GetBytes(data);
using (var hmac256 = new HMACSHA256(keyByte))
{
byte[] hashData = hmac256.ComputeHash(dataBytes);
return BitConverter.ToString(hashData).Replace("-", "").ToLower();
}
}
原文地址:https://www.cnblogs.com/stulzq/p/11840783.html
- TensorFlow实例: 手写汉字识别
- iOS引入JavaScriptCore引擎框架(一)
- Spring+SpringMVC+MyBatis+easyUI整合基础篇(三)搭建步骤
- iOS引入JavaScriptCore引擎框架(二)
- Java基础-03(01).总结运算符、键盘录入、if语句
- 使用git恢复未提交的误删数据
- Java web图片上传和文件上传
- 通过java程序模拟实现地铁票价2+2=12(r3笔记第94天)
- 由objC运行时所想到的。。。
- tensorflow系列笔记:流程,概念和代码解析
- node实现watcher的困境
- Java基础-03(02).总结运算符、键盘录入、if语句
- Spring+SpringMVC+MyBatis+easyUI整合优化篇(十一)数据层优化-druid监控及慢sql记录
- python数据分析师面试题选
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- scp命令
- osgEarth使用笔记4——加载矢量数据
- Pots(POJ - 3414)【BFS 寻找最短路+路径输出】
- Vue路由Hash模式分析
- Flutter基础widgets教程-CupertinoButton篇
- 利用TfidfVectorizer进行中文文本分类(数据集是复旦中文语料)
- 组合模式
- Js中数组空位问题
- 反转字符串
- Prime Path(POJ - 3126)【BFS+筛素数】
- (leetcode每日打卡)秋叶收藏集【动态规划】
- 设计模式~调停者模式(Mediator)
- Sequential Nim(CodeForces - 1382B)【博弈】
- Less Coin Tosses(Gym - 102346L)【打表+找规律】
- leetcode1558题解【贪心】