ONVIF: Authentication failure with SNC-CH110 using ONVIF protocol
Asked Answered
D

2

6

I've camera SNC-CH110 from Sony. Default user is 'admin' and password is 'admin' too. My big problem is with authentication.

<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>
        <SOAP-ENV:Text xml:lang="en">The action requested requires authorization and the sender is not authorized
        </SOAP-ENV:Text>
    </SOAP-ENV:Detail>
</SOAP-ENV:Fault>

According to ONVIF specification 1.02, I use “user name token profile” for authentication which is described in specification http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf or in http://www.onvif.org/Portals/0/documents/WhitePapers/ONVIF_WG-APG-Application_Programmer%27s_Guide.pdf

Below is the Script that I use to form soap request:

<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope 
    xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
    xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
    xmlns:tds="http://www.onvif.org/ver10/device/wsdl">
    <SOAP-ENV:Header> 
        <Security SOAP-ENV:mustUnderstand="1" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <UsernameToken> 
                <Username>admin</Username>
                <wsse:Password Type=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wssusername-token-profile-1.0#PasswordDigest"">" + hashBase64 + @"</wsse:Password> 
                <wsse:Nonce >" + Convert.ToBase64String(_nonce) + @"</wsse:Nonce> 
                <Created>" + dt + @"</Created> 
            </UsernameToken> 
        </Security> 
    </SOAP-ENV:Header>
    <SOAP-ENV:Body> 
        <tds:GetCapabilities> 
            <tds:Category>All</tds:Category> 
        </tds:GetCapabilities> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope>"

Here is my code for sending request:

byte[] _nonce = new byte[16];
RandomNumberGenerator rndGenerator = new RNGCryptoServiceProvider();
rndGenerator.GetBytes(_nonce);

// get other operands to the right format
string dt = DateTime.UtcNow.ToString("yyyy-MM-ddThh:mm:ss.fffZ");
byte[] time = Encoding.UTF8.GetBytes(dt);
byte[] pwd = Encoding.UTF8.GetBytes("admin");
byte[] operand = new byte[_nonce.Length + time.Length + pwd.Length];
Array.Copy(_nonce, operand, _nonce.Length);
Array.Copy(time, 0, operand, _nonce.Length, time.Length);
Array.Copy(pwd, 0, operand, _nonce.Length + time.Length, pwd.Length);

// create the hash
SHA1 sha1 = SHA1.Create();
string hashBase64 = Convert.ToBase64String(sha1.ComputeHash(operand));

XmlDocument xml = new XmlDocument();
xml.Load("../../../xml/GetCapabilities.xml");
Communication.SendTcpXml(xml.InnerXml, new Uri("http://192.168.1.25/onvif/device_service"));

I'm really confused, because I can't find a mistake. It's very interesting that when I use date, password, nonce and username from program ONVIF Device Manager (I took it via Wireshark), I'm successful. BUT I don't understand how this program hash password, because I'm doing it exactly according the specification and when I use same date, nonce and password I can't get same hashed password like this program. I will be grateful for any help, thank.

Dolan answered 25/2, 2012 at 18:30 Comment(1)
I made a little Java function a while ago to compute and show the Header part (just a little test). I tested the result using SoapUI and a Hikvision camera and worked perfectly; I hope it helps: pastebin.com/x16Prr2JPapst
D
4

The hash computation looks like correctly, but I found that element "Created" has wrong namespace, it should be in wsu namespace.
It is also will be more correctly to define attribute EncodingType for Nonce element with value http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary in your case.

Deanery answered 11/4, 2012 at 21:5 Comment(1)
Hi, thx for respond. About namespaces, you're right. I corrected it some time ago. But it wasn't real problem. It sends ws-usernametoken right. But I've just slightly changed code and it's generate hash like that program that I mentioned above, so correct. I'm right now busy, but when I will be free, I will find that catch and I will write it here what was problem.Dolan
R
0

Did you synchronize clocks between you and the camera?
You should first call the getSystemDateAndTime, record your local time, and after that, use the diff between the two when sending further requests.

getSystemDateAndTime does not require authentication, so you're clear at that point.

Ree answered 3/5, 2012 at 11:43 Comment(3)
What do you mean by "use the dif between the two" calls when sending future requests?? Aren't they supposed to be both using UTC?? I know I'm late, but I'd really like an answer! (: Thanks again for your time!Wendell
Hi, I mean that since this is a camera, it is most likely that its clock is not adjusted correctly. So in order to authenticate, you need to first read its clock using getSystemDateAndTime, then you compare it with your clock, and calculate the time difference. The next queries you send the camera should take into account this time difference. So you should call currentTimeMillis (I'm assuming Java here) and offset the result by the above time difference.Ree
Look at this example (see what I do with clientTime and serverTime) #8798919Ree

© 2022 - 2024 — McMap. All rights reserved.