当前位置: 首页 > news >正文

摘要认证 java_摘要认证及实现HTTP digest authentication

最近工作需要做了摘要认证(digest authentication),下面就工作中遇到的问题及过程做一个总结。

第一次客户端请求

GET/POST

服务器产生一个随机数nonce,服务器将这个随机数放在WWW-Authenticate响应头,与服务器支持的认证算法列表,认证的域realm一起发送给客户端,如下例子:

HTTP /1.1 401 Unauthorized

WWW-Authenticate:Digest

realm= ”test realm”

qop=auth,auth-int”

nonce=”66C4EF58DA7CB956BD04233FBB64E0A4”

opaque="5ccc069c403ebaf9f0171e9517f40e41"

• realm的值是一个简单的字符串

• qop是认证的(校验)方式

• nonce是随机数, 可以用GUID

• opaque是个随机字符串,它只是透传而已,即客户端还会原样返回过来。

• algorithm 是个字符串,用来指示用来产生分类及校验和的算法对。如果该域没指定,则认为是“MD5“算法。

客户端发现是401响应,表示需要进行认证,则弹出让用户输入用户名和密码的认证窗口,客户端选择一个算法,计算出密码和其他数据的摘要(response),将摘要放到Authorization的请求头中发送给服务器,如果客户端要对服务器也进行认证,这个时候,可以发送客户端随机数cnonce。如下例子:

GET/cgi-bin/checkout?a=b HTTP/1.1

Authorization: Digest

username="Mufasa",

realm="realm",

nonce="dcd98b7102dd2f0e8b11d0f600bfb0c0", uri="/xxxx/System/Register",

qop=auth, nc=00000001, cnonce="0a4f113b",

response="6629fae49393a05397450978507c4ef1",

opaque="5ccc069c403ebaf9f0171e9517f40e41"

服务接受摘要,选择算法,获取数据库用户名密码,重新计算新的摘要跟客户端传输的摘要进行比较,验证是否匹配。

200 OK

MD5计算方式

cf5a900d4ef7

在这里插入图片描述

//解析客户端发送过来的请求报头中的Authorization

Stringauthorization=request.getHeader("Authorization");

//其参数不为空,利用参数值,和服务器上存储的口令,进行比对。

if(authorization!=null&&!"".equals(authorization)){

。。。

Stringusername=map.get("username");

Stringrealm=map.get("realm");

Stringpassword=userService.getPassword(username);

Stringmethod=request.getMethod();

Stringuri=map.get("uri");

Stringnonce=map.get("nonce");

Stringnc=map.get("nc");

Stringcnonce=map.get("cnonce");

Stringqop=map.get("qop");

//客户端传过来的摘要

StringresponseFromClient=map.get("response");

//MD5计算

Stringa1=username+":"+realm+":"+password;

Stringha1=MD5Utils.getMD5(a1);

Stringa2=method+":"+uri;

Stringha2=MD5Utils.getMD5(a2);

//服务器计算出的摘要

StringresponseBefore=ha1+":"+nonce+":"+nc+":"+cnonce+":"+qop+":"+ha2;

StringresponseMD5=MD5Utils.getMD5(responseBefore);

//两者摘要相同,即验证成功

if(responseMD5!=null&&responseMD5.equals(responseFromClient)){

业务逻辑。。。

//两者摘要不相同,验证失败

}else{

业务逻辑。。。

}

//其参数为空,返回参数到客户端,并发起质询。

}else{

//拼接AuthorizationHeader,格式如Digestusername="admin",realm="Restrictedarea",nonce="554a3304805fe",qop=auth,opaque="cdce8a5c95a1427d74df7acbf41c9ce0",nc=00000001,response="391bee80324349ea1be02552608c0b10",cnonce="0a4f113b",uri="/MyBlog/home/Response/response_last_modified"

StringBuildersb=newStringBuilder();

sb.append("Digest");

sb.append("realm").append("=\"realm\",");

sb.append("qop").append("=\"auth,auth-int\",");

sb.append("nonce").append("=\"").append(getUUID()).append("\",");

sb.append("opaque").append("=\"").append(getUUID()).append("\"");

response.setHeader("WWW-Authenticate",sb.toString());

log.info("authorization:"+sb);

response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

}

cf5a900d4ef7

在这里插入图片描述

cf5a900d4ef7

在这里插入图片描述

一,用摘要保护密码

摘要认证的一个改进之处是用摘要代替密码的传输,遵循的基本原则是“绝对不通过网络发送明文密码”,而是发送一个密码的摘要信息,并且这摘要信息是不可逆的,即无法通 过摘要信息反推出密码信息。而服务器本身是存储这个密码的(实际上,服务器只需知道密码的摘要即可),而客户端和服务器本身都知道这个密码。这样的话,服务器可以读取客户端的摘要和本身知道的密码进行同样计算得出的摘要进行比较,若匹配,则验证通过。

摘要是对信息主体的浓缩,摘要是一种单向函数,主要用于将无限的输入值转为有限的浓缩输出值,如MD5,则是将任意长度的字节系列转换为一个128位的摘要。MD5输出的128位的摘要通常会写出32个十六进制的字符,每个字符表示4个bit。

二,用随机数防止重放攻击

使用单向摘要就无需以明文形式发送密码了,可以只发送密码的摘要,并且可以确信,没有哪个恶意用户能轻易的从摘要中解码出原始密码。

但是,摘要被截获也可能跟密码一起好用,为了防止重放攻击的发送,服务器可以向客户端发送一个称为随机数nonce的特殊令牌,这个数会经常发生变化(可能是每毫秒,或者每次认证都发生变化,具体由服务器控制),客户端在计算摘要之前要先将这个随机数附加到密码上去。这样,在密码中加入随机数就会使得摘要随着随机数的每次变化而变化,记录下的密码摘要只对特定的随机数有效,而没有密码的话,攻击者就无法计算出正确的摘要,这样就可以防止重放攻击的发生。

摘要认证要求使用随机数,随机数是在WWW-Authenticate服务器质询响应中从服务器传输给客户端的。

相关文章:

  • ssdp java_SSDP 简单服务发现协议
  • suse tomcat mysql_suse 安装jdk和tomcat工作记录
  • javascript java 语法_JavaScript
  • java.lang.nullpointerexception:group_为什么会出现java.lang.nullpointerexception错误
  • java数组查找指定元素_Java在数组中查找指定元素的方法
  • k8s mysql volume_k8s实践(七):存储卷和数据持久化(Volumes and Persistent Storage)
  • java 能够完成多个http请求并回应_Java Web请求与响应实例详解
  • mysql 交叉查询_MySQL连接查询,内连接,外连接,全连接,交叉连接
  • java中 springurl_基于SpringMVC中的路径参数和URL参数实例
  • java句子倒序_Java实现英文句子中的单词顺序逆序输出的方法
  • JAVA边学边练答案_Struts2边学边练(1)-HelloWorld
  • php gzip css 乱码,php使用gzip压缩传输js和css文件的方法
  • php静态检测工具,PHP静态代码分析工具,可以检测未捕获的异常?
  • php 挂起一个请求一直执行,在后台运行进程挂起PHP pag
  • php设置cookie路径,php 设置cookie路径例子总结
  • crontab执行失败的多种原因
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • 闭包,sync使用细节
  • 从tcpdump抓包看TCP/IP协议
  • 从重复到重用
  • 和 || 运算
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 前端面试之CSS3新特性
  • 前端设计模式
  • 小程序 setData 学问多
  • 再谈express与koa的对比
  • 中文输入法与React文本输入框的问题与解决方案
  • Java性能优化之JVM GC(垃圾回收机制)
  • k8s使用glusterfs实现动态持久化存储
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTr
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (AngularJS)Angular 控制器之间通信初探
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (篇九)MySQL常用内置函数
  • (十三)Flask之特殊装饰器详解
  • (四)c52学习之旅-流水LED灯
  • (五)Python 垃圾回收机制
  • (学习日记)2024.02.29:UCOSIII第二节
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • (转)Android学习笔记 --- android任务栈和启动模式
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • .describe() python_Python-Win32com-Excel
  • .htaccess配置常用技巧
  • .Net - 类的介绍
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • .NET导入Excel数据
  • .net中应用SQL缓存(实例使用)
  • @modelattribute注解用postman测试怎么传参_接口测试之问题挖掘