摘要认证及实现HTTP digest authentication

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

  1. 第一次客户端请求
    GET/POST

  2. 服务器产生一个随机数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“算法。
    
  3. 客户端发现是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"
    
  4. 服务接受摘要,选择算法,获取数据库用户名密码,重新计算新的摘要跟客户端传输的摘要进行比较,验证是否匹配。
    200 OK

  5. MD5计算方式


    在这里插入图片描述
//解析客户端发送过来的请求报头中的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);
}
在这里插入图片描述
在这里插入图片描述

一,用摘要保护密码
摘要认证的一个改进之处是用摘要代替密码的传输,遵循的基本原则是“绝对不通过网络发送明文密码”,而是发送一个密码的摘要信息,并且这摘要信息是不可逆的,即无法通 过摘要信息反推出密码信息。而服务器本身是存储这个密码的(实际上,服务器只需知道密码的摘要即可),而客户端和服务器本身都知道这个密码。这样的话,服务器可以读取客户端的摘要和本身知道的密码进行同样计算得出的摘要进行比较,若匹配,则验证通过。
摘要是对信息主体的浓缩,摘要是一种单向函数,主要用于将无限的输入值转为有限的浓缩输出值,如MD5,则是将任意长度的字节系列转换为一个128位的摘要。MD5输出的128位的摘要通常会写出32个十六进制的字符,每个字符表示4个bit。

二,用随机数防止重放攻击
使用单向摘要就无需以明文形式发送密码了,可以只发送密码的摘要,并且可以确信,没有哪个恶意用户能轻易的从摘要中解码出原始密码。
但是,摘要被截获也可能跟密码一起好用,为了防止重放攻击的发送,服务器可以向客户端发送一个称为随机数nonce的特殊令牌,这个数会经常发生变化(可能是每毫秒,或者每次认证都发生变化,具体由服务器控制),客户端在计算摘要之前要先将这个随机数附加到密码上去。这样,在密码中加入随机数就会使得摘要随着随机数的每次变化而变化,记录下的密码摘要只对特定的随机数有效,而没有密码的话,攻击者就无法计算出正确的摘要,这样就可以防止重放攻击的发生。
摘要认证要求使用随机数,随机数是在WWW-Authenticate服务器质询响应中从服务器传输给客户端的。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352

推荐阅读更多精彩内容

  • 工作流程 一次HTTP操作称为一个事务,其工作过程可分为四步: 1)首先客户机与服务器需要建立连接。只要单击某个超...
    保川阅读 4,600评论 2 14
  • 前言:最近发现自己在网络相关这一块基础很是欠缺,所以准备花时间了解一下,本文主要是讲http协议的一些基础,和一些...
    justCode_阅读 2,094评论 0 23
  • 前面两篇文章中关于 HTTP 相关知识基本上介绍的差不多了,这篇文章是对 HTTP 协议的补充,主要介绍以下三点内...
    lijiankun24阅读 1,307评论 2 3
  • 基础认证(Basic) 说直白点,认证就是让访问服务的人提供用户名和密码,然后对用户名和密码做校验。 http的质...
    单纯的土豆阅读 2,214评论 0 1
  • 湖中垂柳,与湖相互映衬。 牡丹,洛阳之花。群植。 垂丝海棠,孤植。 石楠,孤植。 红枫,艳丽,高贵。孤植。 碧桃,...
    好名字呀阅读 497评论 0 1