最近工作中遇到需要对接1400协议,网上搜索不到c/c++的实现,所以记录一下自己的实现。
第一步注册:
1400是在http摘要认证的基础上做的,所以要去了解http摘要认证的流程
说明:
1.视图库通过用户分配,手动分配username,password给三方对接程序
2.三方对接程序第一次请求由于不知道Authorization请求头填写信息,所以视图库接收到未带Authorization请
求头信息的请求时会相应401,并附带请求头WWW-Authenticate请求头信息
3.三方根据视图库响应的WWW-Authenticate信息进行RFC2617 digest(下文)加密生成秘钥放入请求头Authorization中,重新发送请求
4.视图库解析Authorization请求头中的秘钥,将解析出的用户名和密码进行匹配,匹配成功,则注册成功,否
则注册失败
参数说明:
username是要认证的用户名
WWW-Authenticate是httpd的一个标头
realm的值是一个简单的字符串
qop是认证的(校验)方式,这个比较重要,对后面md5的加密过程有影响,值就按照上面的那样写就行了
nonce的值也是一个字符串,如果不严格,可以随机生成一个就行,注意它是个GUID,即唯一的、不重复的。如果严格,则需要包含时间信息、客户端IP信息和其它信息,因为认证过程的时间很短,所以如果服务器收到认证信息后发现这个时间和服务器的时间相去甚远,那说明不正常,直接拒绝,以防止攻击,还有客户端IP,如果这个IP一直这样攻击,则可以在一定时间内发现是该IP的连接则直接断掉。这些严格的做法主要是为了防止攻击。在rfc2617上有狭路为详细的描述。我这里没有考虑这些,只是使用了个简单的字符串
url是本次请求的资源位置,比如“/public/userinfo.htm”
cnonce是客户端产生的一个GUID,一般是32字节,而且是16个字节字符串的16进制形式表示,所以其中的内容是0~9和a~f之间的那些字符。其实nonce也是一样,但我没有特意这样做,比如我直接生成一个数字,然后以16进制输出,而没有特殊追求16个字节。
nc是认证的次数,因为如果认证失败,则仍然可以重新发送认证信息继续认证,第一次是1,第二次是2,第三次是3,...。但我这里没有这样弄,只允许一次,如果认证不过就关闭了连接,所以我只处理了1的情况,即00000001,这个值总是固定的8个字节,而且不加引号,和其它域的格式不一样
response的值就很重要了,是根据以上信息,再加上密码通过一定的顺序计算出的一个md5码,固定为16字节的16进制表示形式。服务器在收到所有这些信息后,也通过相同的方式计算出这个值,而密码则是保存在服务器端,即服务器要通过用户名去找到对应的密码,然后和计算出md5值,再和客户端传过来的response值对比,如果一样,则认证通过,否则通不过。
RFC2617 digest加密:
MD5((MD5)HA1:HD:(MD5)HA2)
如果algorithm的值是“md5-sess”,则
HA1=username:realm:password:nonce:cnonce
否则
HA1=username:realm:password
HD=nonce:noncecount:cnonce:qop
HA2=method:uri
method是指“GET”/"POST",即http头中指定的获取资源的方式
以下是c/c++代码
#ifndef __CAT1400_H
#define __CAT1400_H
#include "CCurlManager.h"
#include "CTgSSL.h"
#define CAT1400IP "*******"
#define CAT1400PORT ****
#define CATDE