关于SIP中的Authorization

来源:互联网 发布:淘宝店铺音乐怎么设置 编辑:程序博客网 时间:2024/05/01 02:26

  SIP Client起来后第一件事应该是到服务器去注册,这样当有电话呼叫时服务器才能正确的定位 ,注册设计到一个认证的过程。

  RFC2617定义了两种加密的方式,一种是BASE64的,另一种是MD5加密,大多SIP协议栈都采用的后者,可能是出于安全的考虑,因为MD5是不可逆的。

  对于MD5的方式,RFC2617有提供一个example的实现,有源代码,但奇怪的是我将它的源代码复制下来,运行后发现,计算RFC2617中的例子时得到的MD5值是对的,但我自己架的3CX Server和PBX却总是work不起来,我用x-lite去注册,然后抓包比对发现原因是我计算出来到MD5值Response不对,这让我很是郁闷,后来比对发现两者之间有些差别,例子中有Cnonce值,但我抓的包中没有,于是我将Cnonce置为NULL计算,发现还是不对,没辙了,只好去研究它们的计算方法。

  后来发现SIP中验证的MD5值是通过如下方式得到的:

   step1:caculate username:realm:password MD5 value to get HA1

   step2:caculate method:uri MD5 value to get HA2

   step3:caculate HA1:nonce:HA2 MD5 value, it's the result

  对比源代码,我注掉一段code后,发现得到了正确的MD5值,如下:

void DigestCalcResponse(
 IN HASHHEX HA1, /* H(A1) */
 IN char * pszNonce, /* nonce from server */
 IN char * pszNonceCount, /* 8 hex digits */
 IN char * pszCNonce, /* client nonce */
 IN char * pszQop, /* qop-value: "", "auth", "auth-int" */
 IN char * pszMethod, /* method from the request */
 IN char * pszDigestUri, /* requested URL */
 IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */
 OUT HASHHEX Response /* request-digest or response-digest */
 )
{
 MD5_CTX Md5Ctx;
 HASH HA2;
 HASH RespHash;
 HASHHEX HA2Hex;
 
 // calculate H(A2)
 MD5Init(&Md5Ctx);
 MD5Update(&Md5Ctx, pszMethod, strlen(pszMethod));
 MD5Update(&Md5Ctx, ":", 1);
 MD5Update(&Md5Ctx, pszDigestUri, strlen(pszDigestUri));
 if (stricmp(pszQop, "auth-int") == 0) {
  MD5Update(&Md5Ctx, ":", 1);
  MD5Update(&Md5Ctx, HEntity, HASHHEXLEN);
 };
 MD5Final(HA2, &Md5Ctx);
 CvtHex(HA2, HA2Hex);
 
 // calculate response
 MD5Init(&Md5Ctx);
 MD5Update(&Md5Ctx, HA1, HASHHEXLEN);
 MD5Update(&Md5Ctx, ":", 1);
 MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce));
 MD5Update(&Md5Ctx, ":", 1);
 
 if (*pszQop) {
  MD5Update(&Md5Ctx, pszNonceCount, strlen(pszNonceCount));
  MD5Update(&Md5Ctx, ":", 1);
  MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));
  MD5Update(&Md5Ctx, ":", 1);
  MD5Update(&Md5Ctx, pszQop, strlen(pszQop));
  MD5Update(&Md5Ctx, ":", 1);
 };

 
 MD5Update(&Md5Ctx, HA2Hex, HASHHEXLEN);
 MD5Final(RespHash, &Md5Ctx);
 CvtHex(RespHash, Response);
};

原创粉丝点击