Search code examples
soapdartonvif

How to generate Digest password on Dart for communicate with ip camera


I am trying to communicate with ip camera supporting the Onvif protocol and I need to generate a Digest password. Here's similar topic but it's didn't help. Here's oasis-open standart for this thing. If I understand correctly I should use this formula

Digest = B64ENCODE( SHA1( B64DECODE( Nonce ) + Date + Password ) )

I tried something like this:

import 'package:crypto/crypto.dart';
var username = "admin";
var mNonce = base64Encode(utf8.encode("12345678901234567890"));
Digest digest = sha1.convert(utf8.encode(mNonce + -12-25T07:55:35Z' + '21063598'));
var mPasswordDigest = base64Encode(digest.bytes);

But the ip camera response: 400 "not Authorized"

I used http sniffer and check what send worked app (Onvifer on Android), I send the same copied request and it gives ok status code 200. So the problem is incorrect way of digestPassword generation.

This is a body of a working request:

<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" '
         'xmlns:c="http://www.w3.org/2003/05/soap-encoding" xmlns:v="http://www.w3.org/2003/05/soap-envelope">'
         '<v:Header><Action mustUnderstand="1" xmlns="http://www.w3.org/2005/08/addressing">http://www.onvif.org/ver10/media/wsdl/GetSnapshotUri</Action>'
         '<Security 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">'
         ''x8IytKlr8cTH+sT9EzEaVDLqYGw='</Password>'
         '<Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">'
         ''Njg2YzYxZDI4YjA4ZDA0Nw=='</Nonce><Created xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">'
         ''2019-12-25T07:55:35Z'</Created></UsernameToken></Security></v:Header><v:Body><GetSnapshotUri xmlns="http://www.onvif.org/ver10/media/wsdl">'
         '<ProfileToken>PROFILE_000</ProfileToken></GetSnapshotUri></v:Body></v:Envelope>';


Solution

  • We need to generate use this formula

    Digest = B64ENCODE( SHA1( Nonce + Date + Password ) )

    import 'package:crypto/crypto.dart';
    var username = "admin";
    var mNonce = base64Encode(utf8.encode("12345678901234567890"));
    Digest digest = sha1.convert(utf8.encode("12345678901234567890"+ -12-25T07:55:35Z' + '21063598'));
    var mPasswordDigest = base64Encode(digest.bytes);