老版本的摄像头使用海康的协议http://user:password@192.168.1.64/ISAPI/Streaming/channels/33/picture
就可以取得图片。
然后新型号的摄像头http需要Digest authorization认证。没有认证的话只会返回401unauthorized错误:

<!DOCTYPE html>
<html><head><title>Document Error: Unauthorized</title>
</head><body><h2>Access Error: 401 -- Unauthorized</h2><p>Authentication Error</p>
</body></html>

curl 命令行解决401 unauthorized问题

在https://blog.csdn.net/bobchill/article/details/83302177 里博主用curl 命令行解决401 unauthorized问题,没想到真的可以用。我对应我的应用修改了命令:

 curl --insecure --anyauth -u admin:password -X GET http://admin:password@192.168.1.64/ISAPI/Streaming/channels/33/picture >b.jpeg

将接收结果直接输出成b.jpeg文件,确实是一张图片。
但是在openwrt中作用该命令却仍然返回401错误。也许是两个curl版本不同吧。因为最终我还是要通过libcurl编程来实现auth认证的,所以就不深究命令了。

HTTP Digest authentication的机制

是server收到client的HTTP request(INVITE),如果server需要客户端摘要认证,就需要生成一个摘要盘问(digest challenge),通过Response给client一个401 Unauthorized状态发送给用户
摘要盘问如 图二 中的WWW-Authenticate header所示:

摘要盘问中的各个参数意义如下:

realm(领域):必须的,在所有的盘问中都必须有。它是目的是鉴别SIP消息中的机密。在实际应用中,它通常设置为server所负责的域名。

nonce (现时):必须的,这是由服务器规定的数据字符串,在服务器每次产生一个摘要盘问时,这个参数都是不一样的(与前面所产生的不会雷同)。nonce 通常是由一些数据通过md5杂凑运算构造的。这样的数据通常包括时间标识和服务器的机密短语。确保每个nonce 都有一个有限的生命期(也就是过了一些时间后会失效,并且以后再也不会使用),而且是独一无二的(即任何其它的服务器都不能产生一个相同的nonce )。

Stale:不必须,一个标志,用来指示客户端先前的请求因其nonce值过期而被拒绝。如果stale是TRUE(大小写敏感),客户端可能希望用新的加密回应重新进行请求,而不用麻烦用户提供新的用户名和口令。服务器端只有在收到的请求nonce值不合法,而该nonce对应的摘要(digest)是合法的情况下(即客户端知道正确的用户名/口令),才能将stale置成TRUE值。如果stale是FALSE或其它非TRUE值,或者其stale域不存在,说明用户名、口令非法,要求输入新的值。

opaque(不透明体):必须的,这是一个不透明的(不让外人知道其意义)数据字符串,在盘问中发送给用户。

algorithm(算法):不必须,这是用来计算杂凑的算法。当前只支持MD5算法。

qop(保护的质量):必须的,这个参数规定服务器支持哪种保护方案。客户端可以从列表中选择一个。值 “auth”表示只进行身份查验, “auth-int”表示进行查验外,还有一些完整性保护。需要看更详细的描述,请参阅RFC2617。

客户端反馈用户身份
client 生成 生成摘要响应(digest response),然后再次通过 http request (INVITE (Withink digest))发给 server。

摘要响应如 图三 中的Authenticate header所示:

摘要响应中的各个参数意义如下:

username: 不用再说明了
realm: 需要和 server 盘问的realm保持一致
nonce:客户端使用这个“现时”来产生摘要响应(digest response),需要和server 盘问中携带的nonce保持一致,这样服务器也会在一个摘要响应中收到“现时”的内容。服务器先要检查了“现时”的有效性后,才会检查摘要响应的其它部分。

因而,nonce 在本质上是一种标识符,确保收到的摘要机密,是从某个特定的摘要盘问产生的。还限制了摘要盘问的生命期,防止未来的重播攻击。

qop:客户端选择的保护方式。

nc (现时计数器):这是一个16进制的数值,即客户端发送出请求的数量(包括当前这个请求),这些请求都使用了当前请求中这个“现时”值。例如,对一个给定的“现时”值,在响应的第一个请求中,客户端将发送“nc=00000001”。这个指示值的目的,是让服务器保持这个计数器的一个副本,以便检测重复的请求。如果这个相同的值看到了两次,则这个请求是重复的。

response:这是由用户代理软件计算出的一个字符串,以证明用户知道口令。比如可以通过 username、password、http method、uri、以及nonce、qop等使用MD5加密生成。

cnonce:这也是一个不透明的字符串值,由客户端提供,并且客户端和服务器都会使用,以避免用明文文本。这使得双方都可以查验对方的身份,并对消息的完整性提供一些保护。

uri:这个参数包含了客户端想要访问的URI。

server 确认用户
确认用户主要由两部分构成:
检查nonce的有效性
检查摘要响应中的其他信息, 比如server可以按照和客户端同样的算法生成一个response值,和client传递的response进行对比。
————————————————
以上出自原文链接:https://blog.csdn.net/andrewpj/article/details/45727853

费话不多说,开干吧,如何通过c语言的libcurl实现呢

c语言的libcurl实现HTTP Digest authentication

先写一个HTTP request(INVITE)请求:

int DigestAuthenticate(void)
{char *buffer,*pb;buffer=(char*)calloc(1024,sizeof(char));memset(buffer,0,1024);pb=buffer;CURL *hnd = curl_easy_init();curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "GET");curl_easy_setopt(hnd, CURLOPT_URL, "http://192.168.1.64/ISAPI/Streaming/channels/33/picture");curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, false);curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, false);//curl_easy_setopt(hnd, CURLOPT_RETURNTRANSFER, 1);curl_easy_setopt(hnd, CURLOPT_FOLLOWLOCATION, false);curl_easy_setopt(hnd, CURLOPT_TIMEOUT, 30);curl_easy_setopt(hnd, CURLOPT_CONNECTTIMEOUT, 30);curl_easy_setopt(hnd, CURLOPT_HEADER, 1);curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, read_data_curl);curl_easy_setopt(hnd, CURLOPT_WRITEDATA, buffer);CURLcode ret = curl_easy_perform(hnd);if(CURLE_OK == ret) {printf("\n%s\n",buffer);}else{curl_easy_cleanup(hnd);free(pb);printf("ret:%d\n",ret);return -1;}curl_easy_cleanup(hnd);printf("---------------------end----------------------\n");free(pb);return 1;
}

输出结果:

HTTP/1.1 401 Unauthorized
Date: Thu, 31 Oct 2019 12:46:06 GMT
Server: webserver
X-Frame-Options: SAMEORIGIN
Content-Length: 178
Content-Type: text/html
Connection: close
WWW-Authenticate: Digest qop="auth", realm="IP Camera(D6153)", nonce="597a553359574d334e546f794d5752684d44526c5a673d3d", stale="FALSE"<!DOCTYPE html>
<html><head><title>Document Error: Unauthorized</title></head>
<body><h2>Access Error: 401 -- Unauthorized</h2>
<p>Authentication Error</p>
</body>
</html>

WWW-Authenticate就是我们需要的东西,接着用它来计算出其它参数。

//这里实现Digest Auth逻辑
String A1 = null; //A1 = MD5("usarname:realm:password");
String A2 = null; //A2 = MD5("httpmethod:uri");
String response = null; //response = MD5("A1:nonce:nc:cnonce:qop:A2");

计算response是个难道。用一个方法可以验证response算得对不对。首先看一下Postman测试中获取的过程,其它的不要,我们看Authorization: Digest 后的字符串,就是这次auth的各个参数:


在https://www.cnblogs.com/johnw/p/5487447.html介绍使用lLinux下使用openss的MD5加密BASE64加密方法。好东西呀,这一下不需要等编程就可以验证计算MD5对不对了。

可以看到结果和上面Postman的response是一样的,证明上面说的Digest Auth逻辑是对的。

海康摄像头http抓图相关推荐

  1. 海康摄像头二次开发详解,包含海康摄像头登录、海康云台控制、视频下载等功能

    海康摄像头二次开发详解 准备 海康摄像头SDK开发下载路径: 开发过程中遇到的问题记录: 添加maven依赖 下面代码中会出现的实体类 CameraManage实体类: ControlDto实体类: ...

  2. vue2集成海康摄像头

    vue2hkCamera 介绍 用vue结合element,借助海康最新web3.2无插件demo写的拍照系统 功能:预览,上下左右放大缩小,拍照及保存 注:预览里,需求是看到全身照,所以整个场景仅展 ...

  3. Java对接海康摄像头坑点总结

    一.背景 有一批AI摄像头需要部署到客户方,需要实现的功能:1.摄像头实时预览,摄像头安装在不同地点的内网环境,因此需要通过frpc服务器做内网摄像头的代理:2.摄像头smart事件,进入区域.离开区 ...

  4. C# 海康摄像头视频播放的两种方式

    题外话:看到很多朋友有此方面的问题,各种途径联系到我,在此声明,可以发邮件到jimi080180@qq.com进行沟通,也提供有偿项目模块外包服务. 目前市面上海康的摄像头占有率还是很高的,如果要用海 ...

  5. 海康摄像头视频调用出错,Jni Error(app bug): accessed stale local reference解决办法

    项目中要在Android手机中调用海康摄像头拍摄的画面,在公司网管配置好了网络地址(不要与其他局域网内地址冲突)和端口,并激活摄像头设备后,通过SADPTool(海康提供的摄像头搜索工具)可以自动检索 ...

  6. 海康摄像头的二次开发(java)

    海康摄像头的二次开发(java) 我第一次接触海康摄像头的二次开发的项目,一开始的时候摸不清套路,走了不少弯路,现在准备把我的一些经验留下来,让大家参考一下. 1.首先到海康的官网下载设备网络SDK: ...

  7. 两个rtsp同时抓流_海康摄像头同时添加到两台海康硬盘录像机上

    相信大家都有这种经历,我我为啥要多买两个摄像头呀,我直接一个摄像头添加到两台硬盘录像机上不香吗? 海康摄像头一般不建议同时添加到超过三台录像机,由于取流限制~ 那么如何同时添加到两台海康录像机上呢? ...

  8. 海康摄像头取、录像机RTSP视频流的字串格式

    海康摄像头取.录像机RTSP视频流的字串格式 主码流 rtsp://IP:554/h264/ch1/main/av_stream rtsp://IP:554/ISAPI/streaming/chann ...

  9. php对接海康视频教程_EasyNVR无插件互联网直播平台对接海康摄像头如何通过SDK将视频在前端网页播放...

    原标题:EasyNVR无插件互联网直播平台对接海康摄像头如何通过SDK将视频在前端网页播放 市场上常见的海康.大华.宇视等网络摄像头只要支持RTSP协议,都可以接入到EasyNVR中,今天主要给大家分 ...

最新文章

  1. Ardino基础教程 12_感光灯
  2. 对比学习系列论文SimROD(二): A Simple Adaptation Method for Robust Object Detection
  3. ajax 更新页面变量,[Django 1.5] jQuery/Ajax 在Django使用 ,如何更新模板里里变量
  4. 用python语言实现-Python语言实现百度语音识别API的使用实例
  5. 设计模式(5)--工厂模式
  6. 数据库系统常用的存取方法
  7. 远程登录阿里云上的MySQL
  8. html5与css3基础教程课件,揭秘HTML5和CSS3教学幻灯片.ppt
  9. 我与潘家园金爷的对话
  10. 流水作业调度 johnson法则
  11. 完美解决 报错原理 Unable to rename ‘XXXXXXXXX.jar‘ to xxxx
  12. 什么是BI工具,好用的BI工具软件排名
  13. Hadoop,Spark错误:Could not locate executable null\bin\winutils.exe in the Hadoop binaries.
  14. 微信支付分免密支付接口服务如何开通?
  15. 势哨乜池略撑滋度墓泵乜琴剐砂倒
  16. openCV专栏(八):图像轮廓:绘制轮廓
  17. 读书笔记-人月神话4
  18. c语言把一个英语短句倒装,高中英语倒装句(我的恩师整理)(6页)-原创力文档...
  19. Ubuntu下运行.sh文件
  20. Mac 命令行中操作剪切板

热门文章

  1. 远心镜头参数之一:远心镜头景深计算
  2. Win10安装 sql2008 R2
  3. jmeter中控制器的使用
  4. Windows获取系统托盘图标
  5. 偶遇Chrome浏览器“喔唷,崩溃啦”,错误代码(STATUS_STACK_BUFFER_OVERRUN)
  6. 【Hadoop HA】搭建Hadoop HA的详细教程
  7. 深富策略:市场良性回踩 注意把握节奏
  8. 【基于stm32 FreeRtos的智能台灯控制】
  9. Android开发经验、能力提升
  10. 苹果用户界面Aqua背后的故事