RTSP中摘要认证

rtsp认证分为2种,基本认证(basic authentication),摘要认证(digest authentication)

基本认证是http1.0的认证方案,另一个是1.1针对1.0的改进版本,1.0的由于存在未加密直接传送有安全隐患,1.1的经过MD5转换,具备更高的安全性.

在rtsp交互中

OPTIONS rtsp://192.168.1.104:8554/testStream RTSP/1.0
CSeq: 2
User-Agent: LibVLC/2.0.8 (LIVE555 Streaming Media v2011.12.23)

RTSP/1.0 200 OK
CSeq: 2
Date: Sat, Jun 27 2015 03:26:54 GMT
Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER, SET_PARAMETER

DESCRIBE rtsp://192.168.1.104:8554/testStream RTSP/1.0
CSeq: 3
User-Agent: LibVLC/2.0.8 (LIVE555 Streaming Media v2011.12.23)
Accept: application/sdp

RTSP/1.0 401 Unauthorized
CSeq: 3
Date: Sat, Jun 27 2015 03:26:54 GMT
WWW-Authenticate: Digest realm=”LIVE555 Streaming Media”, nonce=”60a76a995a0cb012f1707abc188f60cb”

这是没有输入用户和密码的第一次交互,可以看到客户端请求DESCRIBE之后,服务器返回RTSP/1.0 401 Unauthorized并且将验证相关的WWW-Authenticate: Digest realm=”LIVE555 Streaming Media”,(摘要范围) 和临时随机数nonce=”60a76a995a0cb012f1707abc188f60cb”这个处理在Live555中,Boolean RTSPServer::RTSPClientConnection
::authenticationOK(char const* cmdName, char const* urlSuffix, char const* fullRequestStr) {//这里的cmdName为’DESCRIBE’

…..

// If we get here, we failed to authenticate the user.
// Send back a “401 Unauthorized” response, with a new random nonce:
fCurrentAuthenticator.setRealmAndRandomNonce(authDB->realm());
snprintf((char*)fResponseBuffer, sizeof fResponseBuffer,
“RTSP/1.0 401 Unauthorized\r\n”
“CSeq: %s\r\n”
“%s”
“WWW-Authenticate: Digest realm=\”%s\”, nonce=\”%s\”\r\n\r\n”,
fCurrentCSeq,
dateHeader(),
fCurrentAuthenticator.realm(), fCurrentAuthenticator.nonce());

return False;
}//到这里全部将其返回给fResponseBuffer然后通过handleRequestBytes输出send给客户端,这里的fResponseBuffer就是RTSP/1.0 401 Unauthorized
CSeq: 3
Date: Sat, Jun 27 2015 03:26:54 GMT
WWW-Authenticate: Digest realm=”LIVE555 Streaming Media”, nonce=”60a76a995a0cb012f1707abc188f60cb”

.这里的随机数nonce后面客户端用到()他进行对密码进行md5加密,新版本的live555每次都会分配新的随机数实际上这次的随机数只是提示了用户,服务器需要密码.

客户端vlc这时候,就会弹出输入账号和密码的用户框.之后进行下面

OPTIONS rtsp://192.168.1.104:8554/testStream RTSP/1.0
CSeq: 4
User-Agent: LibVLC/2.0.8 (LIVE555 Streaming Media v2011.12.23)

RTSP/1.0 200 OK
CSeq: 4
Date: Sat, Jun 27 2015 03:27:50 GMT
Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER, SET_PARAMETER

DESCRIBE rtsp://192.168.1.104:8554/testStream RTSP/1.0
CSeq: 5
User-Agent: LibVLC/2.0.8 (LIVE555 Streaming Media v2011.12.23)
Accept: application/sdp

RTSP/1.0 401 Unauthorized
CSeq: 5
Date: Sat, Jun 27 2015 03:27:50 GMT
WWW-Authenticate: Digest realm=”LIVE555 Streaming Media”, nonce=”9cf2a635ab2014532c9efe02876162fe”

DESCRIBE rtsp://192.168.1.104:8554/testStream RTSP/1.0
CSeq: 6
Authorization: Digest username=”username1″,/验证用户名,域,随机数,以及按照加密之后user+password+uri的md5码/

realm=”LIVE555 Streaming Media”, nonce=”9cf2a635ab2014532c9efe02876162fe”, uri=”rtsp://192.168.1.104:8554/testStream”, response=”77670bd2b0957a780b74b1ad9fa4fceb”
User-Agent: LibVLC/2.0.8 (LIVE555 Streaming Media v2011.12.23)
Accept: application/sdp

RTSP/1.0 200 OK
CSeq: 6
Date: Sat, Jun 27 2015 03:27:50 GMT
Content-Base: rtsp://192.168.1.104:8554/testStream/
Content-Type: application/sdp
Content-Length: 595

v=0
o=- 1435375112110313 1 IN IP4 192.168.1.104
s=Session streamed by “testH264VideoStreamer”
i=test.264
t=0 0
a=tool:LIVE555 Streaming Media v2015.06.11
a=type:broadcast
a=control:*
a=source-filter: incl IN IP4 * 192.168.1.104
a=rtcp-unicast: reflection
a=range:npt=0-
a=x-qt-text-nam:Session streamed by “testH264VideoStreamer”
a=x-qt-text-inf:test.264
m=video 18888 RTP/AVP 96
c=IN IP4 232.139.198.250/255
b=AS:500
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=4D4033;sprop-parameter-sets=Z01AM5JUDAS0IAAAAwBAAAAM0eMGVA==,aO48gA==
a=control:track1

服务端会进行密码的验证,验证先重新从OPTION开始,option请求会返回服务器有哪些方法可以提供,随后的DESCRIBE的回应会有服务器针对这一轮新的随机数nonce,根据这个随机数客户端产生加密后的response,服务端收到后进行验证,这里的验证只是验证整个response,并不解出来看真实的用户名和密码.代码如下:

authenticationOK

{

……

do {
// To authenticate, we first need to have a nonce set up
// from a previous attempt:
if (fCurrentAuthenticator.nonce() == NULL) break;

// Next, the request needs to contain an “Authorization:” header,
// containing a username, (our) realm, (our) nonce, uri,
// and response string:解出头username, realm,nonce,uri,response 首先检查随机数nonce和域realm是否和当前服务器上次分配的匹配.也就是是否是同一次会话,
if (!parseAuthorizationHeader(fullRequestStr,
username, realm, nonce, uri, response)
|| username == NULL
|| realm == NULL || strcmp(realm, fCurrentAuthenticator.realm()) != 0
|| nonce == NULL || strcmp(nonce, fCurrentAuthenticator.nonce()) != 0
|| uri == NULL || response == NULL) {
break;
}

// Next, the username has to be known to us:
char const* password = authDB->lookupPassword(username);
/* :TODO:Wednesday, June 24, 2015 11:03:19 HKT:hwt: open by sean */
//#ifdef DEBUG
fprintf(stderr, “line [%d] lookupPassword(%s) returned password %s uri[%s]\n”, __LINE__, username, password, uri);
//#endif
/* :TODO:End— */
if (password == NULL) break;
fCurrentAuthenticator.setUsernameAndPassword(username, password, authDB->passwordsAreMD5());

// Finally, compute a digest response from the information that we have,
// and compare it to the one that we were given:将服务器查找到的账户和密码,用和客户端相同的方法计算response,最后比较这个经过加密的md5字符串是否相等来判断账号和密码是否匹配,他们的计算方式由computeDigestResponse实现
char const* ourResponse
= fCurrentAuthenticator.computeDigestResponse(cmdName, uri);
printf(“line [%d] ourResponse[%s]\n”, __LINE__, ourResponse);
success = (strcmp(ourResponse, response) == 0);
fCurrentAuthenticator.reclaimDigestResponse(ourResponse);
int ret = (success == True)?1:0;
/* :TODO:Wednesday, June 24, 2015 11:05:57 HKT:hwt: */
fprintf(stderr, “line [%d] success [%d] ourResponse(%s) response %s\n”, __LINE__, ret, ourResponse, response);
/* :TODO:End— */
} while (0);

}

认证response的计算方式如函数computeDigestResponse写明

// The “response” field is computed as:
// md5(md5(<username>:<realm>:<password>):<nonce>:md5(<cmd>:<url>))
// or, if “fPasswordIsMD5” is True:
// md5(<password>:<nonce>:md5(<cmd>:<url>))

sprintf((char*)ha1Data, “%s:%s:%s”, username(), realm(), password());
our_MD5Data(ha1Data, ha1DataLen, ha1Buf);//MD5调用之处.

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值