Rtsp认证主要分为两种:
基本认证(basic authentication)和摘要认证( digest authentication )。
基本认证是http 1.0提出的认证方案,其消息传输不经过加密转换因此存在严重的安全隐患。
摘要认证是http 1.1提出的基本认证的替代方案,其消息经过MD5哈希转换因此具有更高的安全性。
1.基本认证 (basic 认证)
流程如下:
步骤1:客户端发送DESCRIBE请求到服务端
DESCRIBE rtsp://10.175.30.35 RTSP/1.0
CSeq: 6
User-Agent: LibVLC/2.2.4 (LIVE555 Streaming Media v2016.02.22)
Accept: application/sdp
步骤2:RTSP服务端认为没有通过认证,发出WWW-Authenticate认证响应
RTSP/1.0 401 Unauthorized
CSeq: 6
WWW-Authenticate: Basic realm=“000102030405”
Date: Tue, Mar 19 2019 07:07:12 GMT
步骤3:客户端携带Authorization串再次发出DESCRIBE请求
DESCRIBE rtsp://10.175.30.35 RTSP/1.0
CSeq: 7
Authorization: Basic YWRtaW46YWJjZDEyMzQ=
Accept: application/sdp
其中,“YWRtaW46YWJjZDEyMzQ=” 是通过对username:password 进行base64编码所得。服务端对 “YWRtaW46YWJjZDEyMzQ=” 解码得出 “admin:abcd1234”
2.摘要认证 Digest authentication
认证流程:
步骤1:客户端发送DESCRIBE请求到服务端
DESCRIBE rtsp://10.175.30.35 RTSP/1.0
CSeq: 6
User-Agent: LibVLC/2.2.4 (LIVE555 Streaming Media v2016.02.22)
Accept: application/sdp
步骤2:服务器端返回401错误,提示未认证并以nonce质询
RTSP/1.0 401 Unauthorized
CSeq: 6
WWW-Authenticate: Digest realm=“000102030405”, nonce=“59caf6cbb9d5dd0ae2a168059919f559”, stale=“FALSE”
WWW-Authenticate: Basic realm=“000102030405”
Date: Tue, Mar 19 2019 07:07:12 GMT
注意:服务器端既返回WWW-Authenticate: Digest,也返回WWW-Authenticate: Basic说明两种方式都支持。
步骤3:客户端以用户名,密码,nonce,HTTP方法,请求的URI等信息为基础产生response信息进行反馈
DESCRIBE rtsp://10.175.30.35 RTSP/1.0
CSeq: 7
Authorization: Digest username=“admin”, realm=“000102030405”, nonce=“59caf6cbb9d5dd0ae2a168059919f559”, uri=“rtsp://10.175.30.35”, response=“039837838f10192c7dcb98b0485265e9”
User-Agent: LibVLC/2.2.4 (LIVE555 Streaming Media v2016.02.22)
Accept: application/sdp
步骤4:服务器对客户端反馈的response进行校验,通过则返回如下字段
RTSP/1.0 200 OK
CSeq: 7
Content-Type: application/sdp
Content-Base: rtsp://10.175.30.35/
Content-Length: 638
v=0
o=- 1552979233389795 1552979233389795 IN IP4 0.0.0.0
s=Media Presentation
e=NONE
b=AS:5100
t=0 0
a=control:rtsp://10.175.30.35/
m=video 0 RTP/AVP 96
c=IN IP4 0.0.0.0
b=AS:5000
a=recvonly
a=x-dimensions:1920,1200
a=control:track=1
a=rtpmap:96 H264/90000
a=fmtp:96 profile-level-id=420029; packetization-mode=1; sprop-parameter-sets=Z00AMpY1QPAEvTcBAQFAAAHCAABX5CE=,aO48gA==
m=audio 0 RTP/AVP 8
c=IN IP4 0.0.0.0
b=AS:50
a=recvonly
a=control:track=2
a=rtpmap:8 PCMA/8000
a=Audio_Bit:64000
a=Media_header:MEDIAINFO=494D4B48010200000400000111710110401F000000FA000000000000000000000000000000000000;
a=appversion:1.0
步骤5:客户端发起创建链接SETUP、PLAY等请求(用一样的方法计算response)
2.2 response计算方法
RTSP客户端应该使用username + password并计算response如下:
1)当password为MD5编码,则
response = md5( password:nonce:md5(public_method:url) );
2)当password为ANSI字符串,则
response= md5( md5(username:realm:password):nonce:md5(public_method:url) );
客户端在每次发起不同的请求方法时都需要计算response字段,同样在服务器端校验时也默认采取同样的计算方法。
此种方式好处是认证过程中并不涉及密码的传输,所以该种方式安全性更高。
Server端处理:保存Client发过来的username、realm、nonce、method、uri等信息,通过username找到password并结合realm、nonce、method、uri计算得出Server端的server_response,对比验证Client发过来的response是否一致,一致则通过验证,不一致则验证失败。
代码:
static int md5(unsigned char *src_str, int src_len, unsigned char *dst_str)
{
int i=0;
unsigned char decrypt[16] ;
MD5_CTX md5;
MD5Init(&md5);
MD5Update(&md5,src_str,src_len);
MD5Final(&md5,decrypt);
printf("加密前:%s\n加密后:",src_str);
for(i=0;i<16;i++) { printf("%02x",decrypt[i]); sprintf(&dst_str[i*2], "%02x", decrypt[i]); }
printf("\n\n");
}
int main(int argc, char *argv[])
{
//response= md5( md5(username:realm:password):nonce:md5(public_method:url) );
unsigned char username[16]="admin", realm[32]="000102030405", passwd[16]="abcd1234";
unsigned char method[16]="DESCRIBE", url[128]="rtsp://10.175.30.35", nonce[128]="59caf6cbb9d5dd0ae2a168059919f559";
unsigned char sa[128]="", ra[128]="", na[128]="";
unsigned char ha1[64]="", ha2[64]="", ha3[64]="";
sprintf(sa, "%s:%s:%s", username, realm, passwd);
md5(sa, strlen(sa), ha1);
sprintf(ra, "%s:%s", method, url);
md5(ra, strlen(ra), ha2);
sprintf(na, "%s:%s:%s", ha1, nonce, ha2);
md5(na, strlen(na), ha3);
return 0;
}
运行打印信息:
加密前:admin:000102030405:abcd1234
加密后:8d4159aab5b6802e91e0e5777da80e6e
加密前:DESCRIBE:rtsp://10.175.30.35
加密后:0683df5784efa6a374f6f673c23324c5
加密前:8d4159aab5b6802e91e0e5777da80e6e:59caf6cbb9d5dd0ae2a168059919f559:0683df5784efa6a374f6f673c23324c5
加密后:039837838f10192c7dcb98b0485265e9