如何修复IP摄像机的“ 400错误请求”?使用ONVIF

时间:2019-04-07 15:27:08

标签: c++ ip-camera onvif

我正在编写一个小型客户端应用程序,该应用程序将使用ONVIF协议来轮询IP摄像机,但是无法解决问题。 只需使用C ++,而无需使用gSOAP工具。

我使用来自此链接Onvif programmers guide

的示例

没有密码保护的相机,因此不需要生成授权数据即可正确响应。 我面临的问题是授权数据的形成。

向摄像机发送任何请求(例如,GetProfiles)时,摄像机始终会响应400错误。 这是一个示例请求:

POST /onvif/Media_service HTTP/1.1
Connection: keep-alive
Content-Length: 948
Content-Type: application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver10/media/wsdl/GetProfiles"
Host: 192.168.10.205
User-Agent: gSOAP/2.8

<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
    <s:Header>
       <Security s:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <UsernameToken>
            <Username>admin</Username>
                <Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">M2IzYWYyOGE5OWE3ZDk3NGYzMGU1MzlkZWVhMDYyODMxMmU3NDIxMA==</Password>
                <Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">MTIzNDU2Nzg5</Nonce>
                <Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2019-03-16T10:43:18Z</Created>
            </UsernameToken>
      </Security>
    </s:Header>
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <GetProfiles xmlns="http://www.onvif.org/ver10/media/wsdl"/>
    </s:Body>
</s:Envelope> 

以下是摄像机响应的示例:

HTTP/1.1 400 Bad Request
Server: gSOAP/2.8
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 1212
Connection: close


<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope > // I skipped the listing of the namespace
    <SOAP-ENV:Header>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
    <SOAP-ENV:Code>
        <SOAP-ENV:Value>SOAP-ENV:Sender</SOAP-ENV:Value>
        <SOAP-ENV:Subcode>
            <SOAP-ENV:Value>ter:NotAuthorized</SOAP-ENV:Value>
        </SOAP-ENV:Subcode>
    </SOAP-ENV:Code>
    <SOAP-ENV:Reason>
        <SOAP-ENV:Text xml:lang="en">Sender not Authorized</SOAP-ENV:Text>
    </SOAP-ENV:Reason>
    <SOAP-ENV:Detail>The action requested requires authorization and the sender is not authorized.</SOAP-ENV:Detail>
        </SOAP-ENV:Fault>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

根据上述文档中的“ 6.1.1.3”,需要创建一个“摘要”,如下所示:

  

摘要= B64ENCODE(SHA1(B64DECODE(Nonce)+日期+密码))

在我的代码中,通过与各种在线生成器进行比较检查,函数B64DECODE,SHA1和B64ENCODE可以正常工作。

我尝试以其他方式设置Nonce参数。到目前为止,都无济于事。 我猜测错误恰恰在于发送给SHA1()函数的参数的工作,但我可能是错的。

谁能说出导致错误的原因?

我发布的代码不是全部,而是发布了与必要数据形成有关的部分。

感谢您的帮助。

代码:

// hardcoded nonce
char caNonceTest[20] = { 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
    0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38 };
caNonceTest[19] = '\0';

// Random generaterd nonce
//char caNonceTest[SHA_DIGEST_LENGTH];
//int nonceInt = rand();

//memset(caNonceTest, 1, SHA_DIGEST_LENGTH);
//memcpy(caNonceTest, &nonceInt, sizeof(nonceInt));


// Get data/time
string sDataUTC = currentISO8601TimeUTC();

// non-crypted password. Make function to get password from user
string sPass = "admin";
string sName = "default";

string sNonce(caNonceTest);

// temp string for SHA1
string sTempSumBin = (sNonce) + /*string2bin*/(sDataUTC)+ /*string2bin*/(sPass); // with string2bin it is also not working


unsigned char digest[SHA_DIGEST_LENGTH];

char cstr[sTempSumBin.size() + 1];
strcpy(cstr, sTempSumBin.c_str());

SHA1((unsigned char*)&cstr, strlen(cstr), (unsigned char*)&digest);

char cSHA1Pass[SHA_DIGEST_LENGTH * 2 + 1];

for (int i = 0; i < SHA_DIGEST_LENGTH; i++)
    sprintf(&cSHA1Pass[i * 2], "%02x", (unsigned int)digest[i]);
printf("SHA1 string before : %s \n", cSHA1Pass);

string strTob64(cSHA1Pass);
string strFinishedPAss = base64_encode(strTOb64); // this is the final result of the password

0 个答案:

没有答案