递归火山软件开发平台

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 火山 源码 类库
查看: 1614|回复: 3
打印 上一主题 下一主题

[视窗] 海康ISAPI接口、华为RESTful北向接口、onvif接口认证登录

[复制链接]

1

主题

5

帖子

29

积分

新手上路

Rank: 1

积分
29
跳转到指定楼层
楼主
发表于 2024-5-13 14:47:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 leepetrel 于 2024-5-20 14:58 编辑

//海康ISAPI接口、华为RESTful北向接口、onvif接口认证登录,无需SDK
//需要模块:CURL网络传输、OPENSSL
//因相机版本不同,所对应的接口也不一样,都需要通过抓包查看。
//h相t机t全p地:址//w相w机w  自行替换一下//返回数据为XML或JSON
调试输出(UTF8到文本(取结果api ("h相t机t全p地:址//192.168.1.64", "/ISAPI/System/Video/inputs/channels", , "GET", , "admin", "admin123")))
//部分ISAPI地址,具体功能地址可以通过抓包相机查看
//取通道数:GET /ISAPI/System/Video/inputs/channels
//获取OSD:GET /ISAPI/System/Video/inputs/channels/1/overlays
//抓图:GET /ISAPI/Streaming/channels/101/picture?snapShotImageType=JPEG
//部分RESTful北向接口地址,具体功能地址可以通过抓包相机查看
//取通道信息:GET /SDCAPI/V1.0/CnsPaas/ChnQury
//获取OSD:GET /SDCAPI/V1.0/OsdIaas/Channels/Osd?ChannelId=" + 通道ID

//onvif登录
调试输出(UTF8到文本(取结果api ("h相t机t全p地:址192.168.1.64", "/onvif/Media", "POST", "POST",  "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<soap:Envelope xmlns:soap=\"h相t机t全p地:址//w相w机w.w3.org/2003/05/soap-envelope\" xmlns:trt=\"h相t机t全p地:址//w相w机w.onvif.org/ver10/media/wsdl\" xmlns:tt=\"h相t机t全p地:址//w相w机w.onvif.org/ver10/schema\">\r\n  <soap:Body>\r\n    <trt:GetProfiles />\r\n  </soap:Body>\r\n</soap:Envelope>","admin", "admin123")))
//onvif具体功能请看官方文档,只是提交的xml文本不一样。
<火山程序 类型 = "通常" 版本 = 1 />

方法 取结果api <类型 = 字节集类>
参数 地址 <类型 = 文本型>
参数 apiurl <类型 = 文本型>
参数 method1 <类型 = 文本型 @默认值 = "GET">
参数 method2 <类型 = 文本型>
参数 提交的数据 <类型 = 文本型 @默认值 = "">
参数 用户名 <类型 = 文本型>
参数 密码 <类型 = 文本型>
{
    变量 http <类型 = 网络访问类>
    变量 http响应结果 <类型 = 网页访问响应类>
    变量 请求头 <类型 = 文本数组类>
    变量 realm值 <类型 = 文本型>
    变量 nonce值 <类型 = 文本型>
    变量 algorithm值 <类型 = 文本型>
    变量 qop值 <类型 = 文本型>
    变量 nc值 <类型 = 文本型>
    变量 cnonce值 <类型 = 文本型>
    变量 哈希算法 <类型 = 加解密类>
    变量 i <类型 = 整数>
    变量 提交的数据临 <类型 = 字节集类>
    提交的数据临 = 文本到UTF8 (提交的数据, 假)
    method1 = 到大写 (method1)
    method2 = 到大写 (method2)
    如果 (method1 == "GET")
    {
        http响应结果 = http.网页访问2 (地址 + apiurl, 网页访问方式.GET, 提交的数据临, 请求头, , , , , , 10000, , )
    }
    否则 (method1 == "POST")
    {
        http响应结果 = http.网页访问2 (地址 + apiurl, 网页访问方式.POST, 提交的数据临, 请求头, , , , , , 10000, , )
    }
    否则 (method1 == "PUT")
    {
        http响应结果 = http.网页访问2 (地址 + apiurl, 网页访问方式.PUT, 提交的数据临, 请求头, , , , , , 10000, , )
    }
    否则 (method1 == "DELETE")
    {
        http响应结果 = http.网页访问2 (地址 + apiurl, 网页访问方式.DELETE, 提交的数据临, 请求头, , , , , , 10000, , )
    }
    如果 (http响应结果.响应码 == 401)
    {
        i = -1
        http响应结果.响应头.枚举循环 ()
        {
            如果真 (寻找文本 (http响应结果.响应头.取枚举值 (), "Digest", , ) > -1)
            {
                i = http响应结果.响应头.取枚举索引 ()
                跳出循环
            }
        }
        如果 (i > -1)
        {
            realm值 = 取文本值 (http响应结果.响应头.取成员 (i), "realm=")
            nonce值 = 取文本值 (http响应结果.响应头.取成员 (i), "nonce=")
            algorithm值 = 取文本值 (http响应结果.响应头.取成员 (i), "algorithm=")
            algorithm值 = 选择 (algorithm值 == "", "MD5", algorithm值)
            qop值 = 取文本值 (http响应结果.响应头.取成员 (i), "qop=")
            nc值 = "00000001"
            cnonce值 = 到小写 (哈希算法.取数据MD5 (文本到多字节 (nonce值, 假)))
            请求头.加入成员 ("User-Agent:PostmanRuntime-ApipostRuntime/1.1.0")
            请求头.加入成员 ("Content-Type:application/json; application/x-www-form-urlencoded; charset=UTF-8")
            请求头.加入成员 ("Accept:application/json;version=1.0")
            请求头.加入成员 ("Accept-Encoding:gzip, deflate, br")
            请求头.加入成员 ("X-Requested-With: XMLHttpRequest")
            如果 (qop值 == "")
            {
                请求头.加入成员 ("Authorization:Digest username=\"" + 用户名 + "\",realm=\"" + realm值 + "\",nonce=\"" + nonce值 + "\",uri=\"" + apiurl + "\",algorithm=\"" + algorithm值 + "\",response=\"" + 取摘要response (algorithm值, 用户名, 密码, realm值, nonce值, qop值, cnonce值, nc值, method2 + ":" + apiurl) + "\"")
            }
            否则
            {
                请求头.加入成员 ("Authorization:Digest username=\"" + 用户名 + "\",realm=\"" + realm值 + "\",nonce=\"" + nonce值 + "\",uri=\"" + apiurl + "\",algorithm=\"" + algorithm值 + "\",qop=" + qop值 + ",nc=" + nc值 + ",cnonce=\"" + cnonce值 + "\",response=\"" + 取摘要response (algorithm值, 用户名, 密码, realm值, nonce值, qop值, cnonce值, nc值, method2 + ":" + apiurl) + "\"")
            }
            如果 (method2 == "GET")
            {
                http响应结果 = http.网页访问2 (地址 + apiurl, 网页访问方式.GET, 提交的数据临, 请求头, , , , , , 10000, , )
            }
            否则 (method2 == "POST")
            {
                http响应结果 = http.网页访问2 (地址 + apiurl, 网页访问方式.POST, 提交的数据临, 请求头, , , , , , 10000, , )
            }
            否则 (method2 == "PUT")
            {
                http响应结果 = http.网页访问2 (地址 + apiurl, 网页访问方式.PUT, 提交的数据临, 请求头, , , , , , 10000, , )
            }
            否则 (method2 == "DELETE")
            {
                http响应结果 = http.网页访问2 (地址 + apiurl, 网页访问方式.DELETE, 提交的数据临, 请求头, , , , , , 10000, , )
            }
            否则
            {
                返回 (取空白字节集 (0))
            }
            如果 (http响应结果.响应码 == 200)
            {
                返回 (http响应结果.请求结果)
            }
            否则
            {
                返回 (文本到多字节 (到文本 (http响应结果.响应码), 假))
            }
        }
        否则
        {
            返回 (取空白字节集 (0))
        }
    }
    否则
    {
        返回 (取空白字节集 (0))
    }

}

<火山程序 类型 = "通常" 版本 = 1 />

方法 取摘要response <类型 = 文本型>
参数 algorithm值 <类型 = 文本型>
参数 用户名 <类型 = 文本型>
参数 密码 <类型 = 文本型>
参数 realm值 <类型 = 文本型>
参数 nonce值 <类型 = 文本型>
参数 qop值 <类型 = 文本型>
参数 cnonce值 <类型 = 文本型>
参数 nc值 <类型 = 文本型>
参数 methodurl <类型 = 文本型 注释 = "method:url(GET:/SDCAPI/V1.0/Rest/RestClient)">
{

    变量 哈希算法 <类型 = 加解密类>
    变量 a1 <类型 = 文本型>
    变量 a2 <类型 = 文本型>
    // 在说明如何计算摘要之前,先说明参加摘要计算的信息块。信息块主要有两种:
    // 1,表示与安全相关的数据的A1。
    // A1中的数据时密码和受保护信息的产物,它包括用户名,密码,保护域和随机数等内容,A1只涉及安全信息,与底层报文自身无关。
    // 若算法是:MD5
    // 则A1=<user>:<realm>:<password>
    // 若算法是:MD5-sess
    // 则A1=MD5(<user>:<realm>:<password>):<nonce>:<cnonce>
    // 2,表示与报文相关的数据的A2.
    // A2表示是与报文自身相关的信息,比如URL,请求反复和报文实体的主体部分,A2加入摘要计算主要目的是有助于防止反复,资源或者报文被篡改。
    // 若qop未定义或者auth:
    // A2=<request-method>:<uri-directive-value>
    // 若qop为auth:-int
    // A2=<request-method>:<uri-directive-value>:MD5(<request-entity-body>)
    // 下面定义摘要的计算规则:
    // 若qop没有定义:
    // 摘要response=MD5(MD5(A1):<nonce>:MD5(A2))
    // 若qop为auth:
    // 摘要response=MD5(MD5(A1):<nonce>:<nc>:<cnonce>:<qop>:MD5(A2))
    // 若qop为auth-int:
    // 摘要response= MD5(MD5(A1):<nonce>:<nc>:<cnonce>:<qop>:MD5(A2))
    qop值 = 到小写 (qop值)
    algorithm值 = 到大写 (algorithm值)
    nonce值 = 到小写 (nonce值)
    cnonce值 = 到小写 (cnonce值)
    如果 (algorithm值 == "MD5")
    {
        a1 = 到小写 (哈希算法.取数据MD5 (文本到多字节 (用户名 + ":" + realm值 + ":" + 密码, 假)))
    }
    否则 (algorithm值 == "MD5-SESS")
    {
        a1 = 到小写 (哈希算法.取数据MD5 (文本到多字节 (用户名 + ":" + realm值 + ":" + 密码, 假))) + ":" + nonce值 + ":" + cnonce值
    }
    否则
    {
        a1 = 到小写 (哈希算法.取数据SHA256 (文本到多字节 (用户名 + ":" + realm值 + ":" + 密码, 假)))
    }
    如果 (qop值 == "")
    {

        如果 (寻找文本 (algorithm值, "MD5", , ) > -1)
        {
            a2 = 到小写 (哈希算法.取数据MD5 (文本到多字节 (methodurl, 假)))
            返回 (到小写 (哈希算法.取数据MD5 (文本到多字节 (a1 + ":" + nonce值 + ":" + a2, 假))))
        }
        否则
        {
            a2 = 到小写 (哈希算法.取数据SHA256 (文本到多字节 (methodurl, 假)))
            返回 (到小写 (哈希算法.取数据SHA256 (文本到多字节 (a1 + ":" + nonce值 + ":" + a2, 假))))
        }
    }
    否则
    {
        如果 (寻找文本 (algorithm值, "MD5", , ) > -1)
        {
            a2 = 到小写 (哈希算法.取数据MD5 (文本到多字节 (methodurl, 假)))
            返回 (到小写 (哈希算法.取数据MD5 (文本到多字节 (a1 + ":" + nonce值 + ":" + nc值 + ":" + cnonce值 + ":" + qop值 + ":" + a2, 假))))
        }
        否则
        {
            a2 = 到小写 (哈希算法.取数据SHA256 (文本到多字节 (methodurl, 假)))
            返回 (到小写 (哈希算法.取数据SHA256 (文本到多字节 (a1 + ":" + nonce值 + ":" + nc值 + ":" + cnonce值 + ":" + qop值 + ":" + a2, 假))))
        }
    }

}

<火山程序 类型 = "通常" 版本 = 1 />

方法 取文本值 <类型 = 文本型>
参数 所欲操作的文本 <类型 = 文本型>
参数 取值标志 <类型 = 文本型>
{
    变量 标志位置 <类型 = 整数>
    变量 尾标志位置 <类型 = 整数>
    变量 临时文本 <类型 = 文本型>
    子文本替换 (所欲操作的文本, "\r\n", "", , , )
    标志位置 = 寻找文本 (所欲操作的文本, 取值标志, , )
    如果 (标志位置 > -1)
    {
        尾标志位置 = 寻找文本 (所欲操作的文本, ",", 标志位置, )
        如果 (尾标志位置 > -1)
        {
            临时文本 = 取文本中间 (所欲操作的文本, 标志位置 + 取文本长度 (取值标志), 尾标志位置 - 标志位置 - 取文本长度 (取值标志))
        }
        否则
        {
            临时文本 = 取文本中间 (所欲操作的文本, 标志位置 + 取文本长度 (取值标志), 取文本长度 (所欲操作的文本) - 标志位置 - 取文本长度 (取值标志))
        }
        子文本替换 (临时文本, "\"", "", , , )
        返回 (临时文本)
    }
    否则
    {
        返回 ("")
    }

}



回复

使用道具 举报

29

主题

305

帖子

2590

积分

核心用户

Rank: 9Rank: 9Rank: 9

积分
2590
沙发
发表于 2024-5-18 09:58:43 | 只看该作者
直接放个文件吧,这样看有点乱
回复

使用道具 举报

1

主题

5

帖子

29

积分

新手上路

Rank: 1

积分
29
板凳
 楼主| 发表于 2024-5-20 14:59:41 | 只看该作者
cxz7411 发表于 2024-5-18 09:58
直接放个文件吧,这样看有点乱

没权限上传不了附件,直接复制粘贴到火山就可以用
回复

使用道具 举报

8

主题

49

帖子

207

积分

中级会员

Rank: 3Rank: 3

积分
207
地板
发表于 4 天前 | 只看该作者
这个格式看着真难受
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|递归火山软件开发平台 ( 鄂ICP备18029190号 )

GMT+8, 2024-11-22 04:03 , Processed in 0.087979 second(s), 17 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表