http协议之digest认证实现

参考

http://blog.csdn.net/jszj/article/details/8918967

https://wenku.baidu.com/view/22be2dcf83d049649b6658ff.html

http://blog.csdn.net/i_lovefish/article/details/9816783

md5.h

#ifndef MD5_H

#define MD5_H

typedef struct

{

unsigned int count[2];

unsigned int state[4];

unsigned char buffer[64];

}MD5_CTX;

#define F(x,y,z) ((x & y) | (~x & z))

#define G(x,y,z) ((x & z) | (y & ~z))

#define H(x,y,z) (x^y^z)

#define I(x,y,z) (y ^ (x | ~z))

#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))

#define FF(a,b,c,d,x,s,ac) \

{ \

a += F(b,c,d) + x + ac; \

a = ROTATE_LEFT(a,s); \

a += b; \

}

#define GG(a,b,c,d,x,s,ac) \

{ \

a += G(b,c,d) + x + ac; \

a = ROTATE_LEFT(a,s); \

a += b; \

}

#define HH(a,b,c,d,x,s,ac) \

{ \

a += H(b,c,d) + x + ac; \

a = ROTATE_LEFT(a,s); \

a += b; \

}

#define II(a,b,c,d,x,s,ac) \

{ \

a += I(b,c,d) + x + ac; \

a = ROTATE_LEFT(a,s); \

a += b; \

}

void MD5Init(MD5_CTX *context);

void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen);

void MD5Final(MD5_CTX *context, unsigned char digest[16]);

void MD5Transform(unsigned int state[4], unsigned char block[64]);

void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len);

void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len);

#endif

md5.cpp

#include <memory.h>

#include "md5.h"

unsigned char PADDING[] = { 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };

void MD5Init(MD5_CTX *context)

{

context->count[0] = 0;

context->count[1] = 0;

context->state[0] = 0x67452301;

context->state[1] = 0xEFCDAB89;

context->state[2] = 0x98BADCFE;

context->state[3] = 0x10325476;

}

void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen)

{

unsigned int i = 0, index = 0, partlen = 0;

index = (context->count[0] >> 3) & 0x3F;

partlen = 64 - index;

context->count[0] += inputlen << 3;

if (context->count[0] < (inputlen << 3))

context->count[1]++;

context->count[1] += inputlen >> 29;

if (inputlen >= partlen)

{

memcpy(&context->buffer[index], input, partlen);

MD5Transform(context->state, context->buffer);

for (i = partlen; i + 64 <= inputlen; i += 64)

MD5Transform(context->state, &input[i]);

index = 0;

}

else

{

i = 0;

}

memcpy(&context->buffer[index], &input[i], inputlen - i);

}

void MD5Final(MD5_CTX *context, unsigned char digest[16])

{

unsigned int index = 0, padlen = 0;

unsigned char bits[8];

index = (context->count[0] >> 3) & 0x3F;

padlen = (index < 56) ? (56 - index) : (120 - index);

MD5Encode(bits, context->count, 8);

MD5Update(context, PADDING, padlen);

MD5Update(context, bits, 8);

MD5Encode(digest, context->state, 16);

}

void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len)

{

unsigned int i = 0, j = 0;

while (j < len)

{

output[j] = input[i] & 0xFF;

output[j + 1] = (input[i] >> 8) & 0xFF;

output[j + 2] = (input[i] >> 16) & 0xFF;

output[j + 3] = (input[i] >> 24) & 0xFF;

i++;

j += 4;

}

}

void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len)

{

unsigned int i = 0, j = 0;

while (j < len)

{

output[i] = (input[j]) |

(input[j + 1] << 8) |

(input[j + 2] << 16) |

(input[j + 3] << 24);

i++;

j += 4;

}

}

void MD5Transform(unsigned int state[4], unsigned char block[64])

{

unsigned int a = state[0];

unsigned int b = state[1];

unsigned int c = state[2];

unsigned int d = state[3];

unsigned int x[64];

MD5Decode(x, block, 64);

FF(a, b, c, d, x[0], 7, 0xd76aa478); /* 1 */

FF(d, a, b, c, x[1], 12, 0xe8c7b756); /* 2 */

FF(c, d, a, b, x[2], 17, 0x242070db); /* 3 */

FF(b, c, d, a, x[3], 22, 0xc1bdceee); /* 4 */

FF(a, b, c, d, x[4], 7, 0xf57c0faf); /* 5 */

FF(d, a, b, c, x[5], 12, 0x4787c62a); /* 6 */

FF(c, d, a, b, x[6], 17, 0xa8304613); /* 7 */

FF(b, c, d, a, x[7], 22, 0xfd469501); /* 8 */

FF(a, b, c, d, x[8], 7, 0x698098d8); /* 9 */

FF(d, a, b, c, x[9], 12, 0x8b44f7af); /* 10 */

FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */

FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */

FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */

FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */

FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */

FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */

/* Round 2 */

GG(a, b, c, d, x[1], 5, 0xf61e2562); /* 17 */

GG(d, a, b, c, x[6], 9, 0xc040b340); /* 18 */

GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */

GG(b, c, d, a, x[0], 20, 0xe9b6c7aa); /* 20 */

GG(a, b, c, d, x[5], 5, 0xd62f105d); /* 21 */

GG(d, a, b, c, x[10], 9, 0x2441453); /* 22 */

GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */

GG(b, c, d, a, x[4], 20, 0xe7d3fbc8); /* 24 */

GG(a, b, c, d, x[9], 5, 0x21e1cde6); /* 25 */

GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */

GG(c, d, a, b, x[3], 14, 0xf4d50d87); /* 27 */

GG(b, c, d, a, x[8], 20, 0x455a14ed); /* 28 */

GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */

GG(d, a, b, c, x[2], 9, 0xfcefa3f8); /* 30 */

GG(c, d, a, b, x[7], 14, 0x676f02d9); /* 31 */

GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */

/* Round 3 */

HH(a, b, c, d, x[5], 4, 0xfffa3942); /* 33 */

HH(d, a, b, c, x[8], 11, 0x8771f681); /* 34 */

HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */

HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */

HH(a, b, c, d, x[1], 4, 0xa4beea44); /* 37 */

HH(d, a, b, c, x[4], 11, 0x4bdecfa9); /* 38 */

HH(c, d, a, b, x[7], 16, 0xf6bb4b60); /* 39 */

HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */

HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */

HH(d, a, b, c, x[0], 11, 0xeaa127fa); /* 42 */

HH(c, d, a, b, x[3], 16, 0xd4ef3085); /* 43 */

HH(b, c, d, a, x[6], 23, 0x4881d05); /* 44 */

HH(a, b, c, d, x[9], 4, 0xd9d4d039); /* 45 */

HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */

HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */

HH(b, c, d, a, x[2], 23, 0xc4ac5665); /* 48 */

/* Round 4 */

II(a, b, c, d, x[0], 6, 0xf4292244); /* 49 */

II(d, a, b, c, x[7], 10, 0x432aff97); /* 50 */

II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */

II(b, c, d, a, x[5], 21, 0xfc93a039); /* 52 */

II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */

II(d, a, b, c, x[3], 10, 0x8f0ccc92); /* 54 */

II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */

II(b, c, d, a, x[1], 21, 0x85845dd1); /* 56 */

II(a, b, c, d, x[8], 6, 0x6fa87e4f); /* 57 */

II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */

II(c, d, a, b, x[6], 15, 0xa3014314); /* 59 */

II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */

II(a, b, c, d, x[4], 6, 0xf7537e82); /* 61 */

II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */

II(c, d, a, b, x[2], 15, 0x2ad7d2bb); /* 63 */

II(b, c, d, a, x[9], 21, 0xeb86d391); /* 64 */

state[0] += a;

state[1] += b;

state[2] += c;

state[3] += d;

}

digcalc.h

#pragma once

#define HASHLEN 16

typedef char HASH[HASHLEN];

#define HASHHEXLEN 32

typedef char HASHHEX[HASHHEXLEN+1];

#define IN

#define OUT  /* calculate H(A1) as per HTTP Digest spec */

void DigestCalcHA1( IN char * pszAlg, IN char * pszUserName, IN char * pszRealm, IN char * pszPassword, IN char * pszNonce, IN char * pszCNonce, OUT HASHHEX SessionKey);

/* calculate request-digest/response-digest as per HTTP Digest spec */

void DigestCalcResponse(IN HASHHEX HA1, /* H(A1) */  IN char * pszNonce, /* nonce from server */ IN char * pszNonceCount, /* 8 hex digits */ IN char * pszCNonce, /* client nonce */  IN char * pszQop, /* qop-value: "", "auth", "auth-int" */ IN char * pszMethod, /* method from the request */ IN char * pszDigestUri, /* requested URL */  IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */ OUT HASHHEX Response /* request-digest or response-digest */);

digcalc.cpp代码

#include "md5.h"

#include <string.h>

#include "digcalc.h"

void CvtHex(IN HASH Bin, OUT HASHHEX Hex)

{

unsigned short i;

unsigned char j;

for (i = 0; i < HASHLEN; i++)

{

j = (Bin[i] >> 4) & 0xf;

if (j <= 9)  Hex[i * 2] = (j + ‘0‘);

else  Hex[i * 2] = (j + ‘a‘ - 10);

j = Bin[i] & 0xf;

if (j <= 9)  Hex[i * 2 + 1] = (j + ‘0‘);

else  Hex[i * 2 + 1] = (j + ‘a‘ - 10);

};

Hex[HASHHEXLEN] = ‘\0‘;

};

/* calculate H(A1) as per spec */

void DigestCalcHA1(

IN char * pszAlg,

IN char * pszUserName,

IN char * pszRealm,

IN char * pszPassword,

IN char * pszNonce,

IN char * pszCNonce,

OUT HASHHEX SessionKey

)

{

MD5_CTX Md5Ctx;

HASH HA1;

MD5Init(&Md5Ctx);

MD5Update(&Md5Ctx, (unsigned char*)pszUserName, strlen(pszUserName));

MD5Update(&Md5Ctx, (unsigned char*)":", 1);

MD5Update(&Md5Ctx, (unsigned char*)pszRealm, strlen(pszRealm));

MD5Update(&Md5Ctx, (unsigned char*)":", 1);

MD5Update(&Md5Ctx, (unsigned char*)pszPassword, strlen(pszPassword));

MD5Final(&Md5Ctx,(unsigned char*)HA1);

if (strcmp(pszAlg, "md5-sess") == 0) {

MD5Init(&Md5Ctx);

MD5Update(&Md5Ctx, (unsigned char*)HA1, HASHLEN);

MD5Update(&Md5Ctx, (unsigned char*)":", 1);

MD5Update(&Md5Ctx, (unsigned char*)pszNonce, strlen(pszNonce));

MD5Update(&Md5Ctx, (unsigned char*)":", 1);

MD5Update(&Md5Ctx, (unsigned char*)pszCNonce, strlen(pszCNonce));

MD5Final(&Md5Ctx, (unsigned char*)HA1);

};

CvtHex(HA1, SessionKey);

};

/* calculate request-digest/response-digest as per HTTP Digest spec */

void DigestCalcResponse(

IN HASHHEX HA1, /* H(A1) */

IN char * pszNonce, /* nonce from server */

IN char * pszNonceCount, /* 8 hex digits */

IN char * pszCNonce, /* client nonce */

IN char * pszQop, /* qop-value: "", "auth", "auth-int" */

IN char * pszMethod, /* method from the request */

IN char * pszDigestUri, /* requested URL */

IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */

OUT HASHHEX Response /* request-digest or response-digest */

)

{

MD5_CTX Md5Ctx;

HASH HA2;

HASH RespHash;

HASHHEX HA2Hex;

// calculate H(A2)

MD5Init(&Md5Ctx);

MD5Update(&Md5Ctx, (unsigned char*)pszMethod, strlen(pszMethod));

MD5Update(&Md5Ctx, (unsigned char*)":", 1);

MD5Update(&Md5Ctx, (unsigned char*)pszDigestUri, strlen(pszDigestUri));

if (strcmp(pszQop, "auth-int") == 0) {

MD5Update(&Md5Ctx, (unsigned char*)":", 1);

MD5Update(&Md5Ctx, (unsigned char*)HEntity, HASHHEXLEN);

};

MD5Final(&Md5Ctx, (unsigned char*)HA2);

CvtHex(HA2, HA2Hex);

// calculate response

MD5Init(&Md5Ctx);

MD5Update(&Md5Ctx, (unsigned char*)HA1, HASHHEXLEN);

MD5Update(&Md5Ctx, (unsigned char*)":", 1);

MD5Update(&Md5Ctx, (unsigned char*)pszNonce, strlen(pszNonce));

MD5Update(&Md5Ctx, (unsigned char*)":", 1);

if (*pszQop) {

MD5Update(&Md5Ctx, (unsigned char*)pszNonceCount, strlen(pszNonceCount));

MD5Update(&Md5Ctx, (unsigned char*)":", 1);

MD5Update(&Md5Ctx, (unsigned char*)pszCNonce, strlen(pszCNonce));

MD5Update(&Md5Ctx, (unsigned char*)":", 1);

MD5Update(&Md5Ctx, (unsigned char*)pszQop, strlen(pszQop));

MD5Update(&Md5Ctx, (unsigned char*)":", 1);

};

MD5Update(&Md5Ctx, (unsigned char*)HA2Hex, HASHHEXLEN);

MD5Final(&Md5Ctx, (unsigned char*)RespHash);

CvtHex(RespHash, Response);

};

测试例子

#include <string>

#include <iostream>

#include "digcalc.h"

using namespace std;

int main()

{

char * pszNonce = "6a0b8f835608eea4f39550723102660b:1503972485455";

char * pszCNonce = "bda3fcdddabaeb5ae9dd14b45fba9adb";

char * pszUser = "admin";

char * pszRealm = "test1.1.2";

char * pszPass = "admin12345";

char * pszAlg = "md5";

char szNonceCount[9] = "00000001";

char * pszMethod = "GET";

char * pszQop = "auth";

char * pszURI = "/ISAPI/Security/userCheck";

HASHHEX HA1;

HASHHEX HA2 = "";

HASHHEX Response;

DigestCalcHA1(pszAlg, pszUser, pszRealm, pszPass, pszNonce,

pszCNonce, HA1);

DigestCalcResponse(HA1, pszNonce, szNonceCount, pszCNonce, pszQop,

pszMethod, pszURI, HA2, Response);

printf("Response = %s\n", Response);

}

时间: 2024-10-25 00:37:26

http协议之digest认证实现的相关文章

HTTP协议 (二) --基本认证

HTTP协议 (二) 基本认证 http协议是无状态的, 浏览器和web服务器之间可以通过cookie来身份识别. 桌面应用程序(比如新浪桌面客户端, skydrive客户端)跟Web服务器之间是如何身份识别呢? 什么是HTTP基本认证 桌面应用程序也通过HTTP协议跟Web服务器交互, 桌面应用程序一般不会使用cookie, 而是把 "用户名+冒号+密码"用BASE64编码的字符串放在http request 中的header Authorization中发送给服务端, 这种方式叫H

http 登录Digest认证相关知识

Digest access authentication https://en.wikipedia.org/wiki/Digest_access_authentication Digest access authentication is one of the agreed-upon methods a web server can use to negotiate credentials, such as username or password, with a user's web brow

检查HTTP 的 Digest 认证代码示例-JSP

检查HTTP 的 Digest  认证. since http1.1 代码如下所示:(此代码还不完善, RFC2617算法未实现). <%@ page pageEncoding="UTF-8" contentType="text/html;charset=UTF-8" %> <%@ page import="sun.misc.BASE64Decoder" %> <%@ page import="java.i

批量检测GoAhead系列服务器中Digest认证方式的服务器弱口令

最近在学习用python写爬虫工具,某天偶然发现GoAhead系列服务器的登录方式跟大多数网站不一样,不是采用POST等方法,通过查找资料发现GoAhead是一个开源(商业许可).简单.轻巧.功能强大.可以在多个平台运行的嵌入式Web Server.大多数GoAhead服务器采用了HTTP Digest认证方式,并且部分服务器采用了默认账号密码,于是萌生了针对GoAhead编写爬虫的想法,通过近8个小时的编程与调试,勉强写出了个简陋的脚本,现在拿出来分享,给刚接触python的新手参考下,也请求

HTTP协议之基本认证

http协议是无状态的, 浏览器和web服务器之间可以通过cookie来身份识别. 桌面应用程序(比如新浪桌面客户端, skydrive客户端)跟Web服务器之间是如何身份识别呢? 阅读目录 什么是HTTP基本认证 HTTP基本认证的过程 HTTP基本认证的优点 每次都要进行认证 HTTP基本认证和HTTPS一起使用就很安全 HTTP OAuth认证 其他认证 客户端的使用 什么是HTTP基本认证 桌面应用程序也通过HTTP协议跟Web服务器交互, 桌面应用程序一般不会使用cookie, 而是把

基于X.509证书和SSL协议的身份认证过程实现(OpenSSL可以自己产生证书,有TCP通过SSL进行实际安全通讯的实际编程代码)good

上周帮一个童鞋做一个数字认证的实验,要求是编程实现一个基于X.509证书认证的过程,唉!可怜我那点薄弱的计算机网络安全的知识啊!只得恶补一下了. 首先来看看什么是X.509.所谓X.509其实是一种非常通用的证书,什么是证书?唉!这么说吧!当两个人需要进行远程通信而又不想让第三个人知道时就必须建立一种安全措施,因为看不到对方的脸,又不能通过电话直接询问对方,就得想点别的办法,比如我设计一个密码,让后发短信告诉你,这样当我们在网上交流之前就可以对一下密码,暗号之类的.确认后就可以证明你的身份了.这

asp.net MVC 使用wifidog 协议实现wifi认证

在网上看到的很多实现的wifidog 协议一般都是PHP 的,了解一下PHP 但是比较喜欢.net ,所以实现了简单的一个进行登录认证的功能 (好多协议中的功能目前没有实现) 1. 开发环境(vs2010 ) 2. 路由(支持wifidog协议的 ddwrt ) 3. 环境的配置 主要是进行路由的配置 截图如下: 注意红圈的部分这个我按照php 的配置 asp.net MVC 的配置如下: 端口 9999  authserver path  /login/ 4. MVC 项目布局: loginC

Https握手协议以及证书认证

1. 什么是https Https = http + 加密 + 认证 https是对http的安全强化,在http的基础上引入了加密和认证过程.通过加密和认证构建一条安全的传输通道.所以https可以看成是:在安全通道内,对数据进行对称加密后传输.这样即使黑客打破了安全通道,还有一层数据加密.极大的保障了数据通信的安全性. 2. https的演化 我们将从http的不安全方面着手,通过三个场景的阐述,来说明https是怎么来的以及其基本原理 Round 1: 正常交流: “客户”->“服务器”:

Linux下基于HTTP协议带用户认证的GIT开发环境设置

Git 的访问可以采用 HTTP 或 SSH 协议安全的访问,通常我们使用 gitlib 进行 Web 管理,但是在 Linux 命令行开发环境下,基本都是使用 SSH 协议,只需要在 gitlib 里面配置好相应的 SSH Key 就可以. 由于现在开发环境的特殊情况,我们需要在 Linux 命令行开发环境下,不能使用 SSH 方式,而只能使用 HTTP 协议进行安全访问,并且需要对开发者进行认证,并且开发者在本地开发环境中的用户名和密码需要加密存储. 接下来我就简单介绍我们的开发团队是如何在