【问题标题】:ONVIF: Authentication failure with SNC-CH110 using ONVIF protocolONVIF:使用 ONVIF 协议的 SNC-CH110 身份验证失败
【发布时间】:2012-02-25 18:30:06
【问题描述】:

我有索尼的 SNC-CH110 相机。默认用户是“admin”,密码也是“admin”。我的大问题是身份验证。

<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>

根据 ONVIF 规范 1.02,我使用规范 http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdfhttp://www.onvif.org/Portals/0/documents/WhitePapers/ONVIF_WG-APG-Application_Programmer%27s_Guide.pdf 中描述的“用户名令牌配置文件”进行身份验证

下面是我用来形成soap请求的脚本:

<?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>"

这是我发送请求的代码:

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"));

我真的很困惑,因为我找不到错误。非常有趣的是,当我从程序 ONVIF 设备管理器(我通过 Wireshark 获取)中使用日期、密码、随机数和用户名时,我成功了。但是我不明白这个程序是如何散列密码的,因为我完全按照规范去做,当我使用相同的日期、随机数和密码时,我无法获得像这个程序一样的散列密码。如有任何帮助,我将不胜感激,谢谢。

【问题讨论】:

  • 我不久前做了一个小的 Java 函数来计算和显示 Header 部分(只是一个小测试)。我使用 SoapUI 和海康威视相机测试了结果,效果很好;希望对您有所帮助:pastebin.com/x16Prr2J

标签: authentication camera video-streaming ip onvif


【解决方案1】:

哈希计算看起来正确,但我发现元素“Created”的命名空间错误,它应该在 wsu 命名空间中。
在您的情况下,为具有值 http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary 的 Nonce 元素定义属性 EncodingType 也会更正确。

【讨论】:

  • 嗨,谢谢回复。关于命名空间,你是对的。我前段时间更正了。但这不是真正的问题。它发送 ws-usernametoken 权利。但是我只是稍微更改了代码,它会像我上面提到的那个程序一样生成哈希,所以正确。我现在很忙,但是当我有空时,我会找到那个 catch,我会在这里写下有什么问题。
【解决方案2】:

您是否在您和相机之间同步了时钟?
您应该首先调用getSystemDateAndTime,记录您的当地时间,然后在发送进一步请求时使用两者之间的差异。

getSystemDateAndTime 不需要身份验证,所以你很清楚。

【讨论】:

  • 发送未来请求时“使用两者之间的差异”调用是什么意思?他们不应该都使用UTC吗?我知道我迟到了,但我真的很想要一个答案! (:再次感谢您的宝贵时间!
  • 您好,我的意思是,由于这是一台相机,它的时钟很可能没有正确调整。因此,为了进行身份验证,您需要先使用getSystemDateAndTime 读取其时钟,然后将其与您的时钟进行比较,并计算时差。您发送给相机的下一个查询应该考虑到这个时间差。所以你应该调用currentTimeMillis(我在这里假设Java)并将结果抵消上述时间差。
  • 看这个例子(看看我用clientTime和serverTime做了什么)stackoverflow.com/questions/8798419/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-02
相关资源
最近更新 更多