| 
 | 
 
 本帖最后由 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) 
        { 
            临时文本 = 取文本中间 (所欲操作的文本, 标志位置 + 取文本长度 (取值标志), 尾标志位置 - 标志位置 - 取文本长度 (取值标志)) 
        } 
        否则 
        { 
            临时文本 = 取文本中间 (所欲操作的文本, 标志位置 + 取文本长度 (取值标志), 取文本长度 (所欲操作的文本) - 标志位置 - 取文本长度 (取值标志)) 
        } 
        子文本替换 (临时文本, "\"", "", , , ) 
        返回 (临时文本) 
    } 
    否则 
    { 
        返回 ("") 
    } 
 
} 
 
 
 
 |   
 
 
 
 |