onvif digest 鉴权过程分析

本文深入分析了ONVIF设备的Digest鉴权过程。当客户端初次请求失败收到401响应时,设备会提供一个nonce。客户端使用特定公式结合nonce计算digest,再次请求时附带此digest,从而完成授权并成功访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

鉴权过程如下:

客户端第一次请求 onvif 设备,如 onvif 设备验证 Authorization 失败,则响应 401,同时响应头包含 WWW-Authenticate 头信息(onvif 设备生成的随机数),客户端拿到该数据后根据下面公式计算 digest,再次请求,同时携带计算的 digest 数据即可成功请求。

客户端第一次请求

POST /onvif/PTZ HTTP/1.1
Host: 192.168.1.212
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 644

<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><AbsoluteMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>media_profile_token1</ProfileToken><Position><PanTilt x="0.01" y="0.01" space="http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace" xmlns="http://www.onvif.org/ver10/schema"/><Zoom x="0" space="http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace" xmlns="http://www.onvif.org/ver10/schema"/></Position></AbsoluteMove></s:Body></s:Envelope>HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest realm="IPC_CAM", qop="auth,auth-int", nonce="62fb10dacb7f08aa31fc", opaque="025f3a12"
Server: gSOAP/2.8
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 1707
Connection: close

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsdd="http://schemas.xmlsoap.org/ws/2005/04/discovery" xmlns:chan="http://schemas.microsoft.com/ws/2005/02/duplex" xmlns:wsa5="http://www.w3.org/2005/08/addressing" xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:wsc="http://schemas.xmlsoap.org/ws/2005/02/sc" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:xmime="http://tempuri.org/xmime.xsd" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:wsrfbf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:tdn="http://www.onvif.org/ver10/network/wsdl" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl"><SOAP-ENV:Body><SOAP-ENV:Fault><SOAP-ENV:Code><SOAP-ENV:Value>SOAP-ENV:Sender</SOAP-ENV:Value></SOAP-ENV:Code><SOAP-ENV:Reason><SOAP-ENV:Text xml:lang="en">HTTP Error: 401 Unauthorized</SOAP-ENV:Text></SOAP-ENV:Reason></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>

客户端第二次请求

POST /onvif/PTZ HTTP/1.1
Host: 192.168.1.212
Content-Type: application/soap+xml; charset=utf-8
Authorization: Digest username="admin",realm="IPC_CAM",qop="auth",algorithm=MD5,uri="/onvif/PTZ",nonce="62fb10dacb7f08aa31fc",nc=00000001,cnonce="D12DE722E3B5C2BE8128768A68DE4209",opaque="025f3a12",response="1f73853bc5a5f6728e4f68b26d01065a"
Content-Length: 644

<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><AbsoluteMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>media_profile_token1</ProfileToken><Position><PanTilt x="0.01" y="0.01" space="http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace" xmlns="http://www.onvif.org/ver10/schema"/><Zoom x="0" space="http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace" xmlns="http://www.onvif.org/ver10/schema"/></Position></AbsoluteMove></s:Body></s:Envelope>HTTP/1.1 200 OK
Server: gSOAP/2.8
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 1542
Connection: close

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsdd="http://schemas.xmlsoap.org/ws/2005/04/discovery" xmlns:chan="http://schemas.microsoft.com/ws/2005/02/duplex" xmlns:wsa5="http://www.w3.org/2005/08/addressing" xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:wsc="http://schemas.xmlsoap.org/ws/2005/02/sc" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:xmime="http://tempuri.org/xmime.xsd" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:wsrfbf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:tdn="http://www.onvif.org/ver10/network/wsdl" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl"><SOAP-ENV:Body><tptz:AbsoluteMoveResponse></tptz:AbsoluteMoveResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>

digest 计算部分如下

QString Onvif::calcDigest()
{
    QString username = "admin";
    QString realm = "IPC_CAM";
    QString qop = "auth";
    QString algorithm = "MD5";
    QString uri = "/onvif/PTZ";
    QString nonce = "62fa0f4ecaee87486d09";
    QString nc = "00000001";
    QString cnonce = "AA5187988E637D496C41C22809D08C8E";
    QString opaque = "bcf3610f";
    QString response = "f0b63294cce2664ffb7bfdcf887dde44";
    // R"(Digest username="admin",realm="IPC_CAM",qop="auth",algorithm=MD5,uri="/onvif/PTZ",nonce="62fa0f4ecaee87486d09",nc=00000001,cnonce="AA5187988E637D496C41C22809D08C8E",opaque="bcf3610f",response="f0b63294cce2664ffb7bfdcf887dde44")";

    /*!
    HA1 = MD5(username:realm:password)
    HA2 = MD5(method:uri)
    response = MD5(HA1:nonce:nonceCount:cnonce:qop:HA2)
    */

    QString password = "123";
    QString HA1 = QCryptographicHash::hash(QString("%1:%2:%3").arg(username).arg(realm).arg(password).toUtf8(),QCryptographicHash::Md5).toHex();

    QString method = "POST";
    QString HA2 = QCryptographicHash::hash(QString("%1:%2").arg(method).arg(uri).toUtf8(),QCryptographicHash::Md5).toHex();

    QString eq_response = QCryptographicHash::hash(QString("%1:%2:%3:%4:%5:%6")
                                                   .arg(HA1)
                                                   .arg(nonce)
                                                   .arg(nc)
                                                   .arg(cnonce)
                                                   .arg(qop)
                                                   .arg(HA2)
                                                   .toUtf8()
                                                   ,QCryptographicHash::Md5).toHex();

    QString eq_cnonce = QCryptographicHash::hash(QByteArray::number(QDateTime::currentDateTimeUtc().currentSecsSinceEpoch()),QCryptographicHash::Md5).toHex();

    qDebug() << "HA1:" << HA1;
    qDebug() << "HA2:" << HA2;
    qDebug() << "Response:" << eq_response;
    qDebug() << eq_cnonce;
    return "None";
}

https://www.cnblogs.com/lsdb/p/10621940.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值