文档首页 > > SDK参考> 接入鉴权

接入鉴权

分享
更新时间:2021/01/07 GMT+08:00

为保证RTC的通信安全,当用户加入频道时,华为云RTC服务需要对其进行接入鉴权。本章节主要介绍华为云RTC接入鉴权的实现原理及鉴权签名的生成方法。

鉴权原理

华为云RTC系统使用数字签名作为接入鉴权方式,需要在相应的SDK的初始化或登录函数中提供“app_id”“room_id”“user_id”“ctime”“signature”等信息,才能接入华为RTC服务。“signature”为标识签名,由租户使用华为云RTC提供的“app_key”,按照华为RTC的签名算法自行生成。
signature = HMAC256(app_key,(app_id + room_id + user_id +ctime))
  • app_key:华为云RTC针对每个app生成的鉴权密钥,需要安全保存,谨防泄漏。
  • app_id:华为云RTC生成的应用ID。
  • room_id:租户自行创建的房间ID。
  • user_id:租户接入华为云RTC系统的用户ID。
  • ctime:签名鉴权的过期时间,是系统当前UTC时间(unix时间戳)+鉴权过期时间(推荐2小时),单位为秒。

    ctime的为创建时间+过期时间,示例:当前时间为9:00,鉴权过期时间为30分钟,则ctime应该为9:30分。即超过9:30分后,signature签名将失效。

建议租户构建自己的应用签名分发服务器,以防止“app_key”下沉到终端APP的过程中造成不必要的泄漏,鉴权原理如图1所示

图1 鉴权原理

签名生成方法

您可以参考如下方法生成对应的签名。

  1. “app_id”“room_id”“user_id ”“ctime”拼接为一个字符串。
    1
    2
    long ctime = System.currentTimeMillis() / 1000 + 60 * 60;   //有效时间为1小时,单位是秒
    String content = app_id + "+" + room_id + "+" + user_id + "+" + ctime;
    
  2. 使用“app_key”,通过HAMC-SHA265方式将字符串“content”进行加密,得到签名字符串。
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
        String signatureStr = hmacSha(appKey, content, "HmacSHA256");
        static String hmacSha(String KEY, String VALUE, String SHA_TYPE) {
            try {
                SecretKeySpec signingKey = new SecretKeySpec(KEY.getBytes("UTF-8"), SHA_TYPE);
                Mac mac = Mac.getInstance(SHA_TYPE);
                mac.init(signingKey);
                byte[] rawHmac = mac.doFinal(VALUE.getBytes("UTF-8"));
    
                byte[] hexArray = {
                        (byte) '0', (byte) '1', (byte) '2', (byte) '3',
                        (byte) '4', (byte) '5', (byte) '6', (byte) '7',
                        (byte) '8', (byte) '9', (byte) 'a', (byte) 'b',
                        (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f'
                };
                byte[] hexChars = new byte[rawHmac.length * 2];
                for (int j = 0; j < rawHmac.length; j++) {
                    int v = rawHmac[j] & 0xFF;
                    hexChars[j * 2] = hexArray[v >>> 4];
                    hexChars[j * 2 + 1] = hexArray[v & 0x0F];
                }
                return new String(hexChars);
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }
    

签名生成样例

为防止“app_key”密钥泄漏,建议您配置自己的应用签名分发服务器,向服务器传入“app_id”“room_id”“user_id ”“ctime”后,由服务器返回签名。详细代码示例如下所示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package com.xxx.xxx.utils;

import androidx.annotation.NonNull;

import com.alibaba.fastjson.JSON;
import com.huawei.rtcdemo.Constants;

import java.io.IOException;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import okhttp3.Response;

public class SignatureUtil {
    private static final String TAG = "SignatureUtil";

    public interface onSignatureSuccess {
        void onSuccess(String signature);
    }

    public static void getSignature(String appid, String roomid, String userid, long ctime, String signatureKey, onSignatureSuccess callback) {
        if (Constants.RTC_SIGNATURE_USE_LOCAL) {
            getSignatureLocal(appid, roomid, userid, ctime, signatureKey, callback);
        } else {
            getSignatureRemote(appid, roomid, userid, ctime, callback);
        }
    }

    private static void getSignatureLocal(String appid, String roomid, String userid, long ctime, String signatureKey, @NonNull onSignatureSuccess callback) {
        String content = appid + "+" + roomid + "+" + userid + "+" + ctime; // here "+" is real char in content.
        String signature = SignatureUtil.hmacSha256(signatureKey, content);
        callback.onSuccess(signature);
    }

    private static void getSignatureRemote(String appid, String roomid, String userid, long ctime, @NonNull onSignatureSuccess callback) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                HttpUtil httpUtil = new HttpUtil();
                String url = Constants.RTC_SIGNATURE_URL + "?appid=" + appid + "&roomid=" + roomid + "&userid=" + userid + "&ctime=" + ctime;
                Response response = httpUtil.sendGetMethodWithHead(url, "X-AUTH-TOKEN", Constants.RTC_AUTH_TOKEN);
                if (response == null) {
                    return;
                }

                if (response.isSuccessful()) {
                    try {
                        String json = response.body().string();
                        String signature = JSON.parseObject(json).getString("signature");
                        callback.onSuccess(signature);
                    } catch (IOException e) {
                        LogUtil.e(TAG, "getSignature failed:" + e.getMessage());
                    }
                } else {
                    LogUtil.e(TAG, "getSignature failed!");
                }
            }
        }).start();
    }

    public static String hmacSha256(String KEY, String VALUE) {
        return hmacSha(KEY, VALUE, "HmacSHA256");
    }

    private static String hmacSha(String KEY, String VALUE, String SHA_TYPE) {
        try {
            SecretKeySpec signingKey = new SecretKeySpec(KEY.getBytes("UTF-8"), SHA_TYPE);
            Mac mac = Mac.getInstance(SHA_TYPE);
            mac.init(signingKey);
            byte[] rawHmac = mac.doFinal(VALUE.getBytes("UTF-8"));

            byte[] hexArray = {
                    (byte) '0', (byte) '1', (byte) '2', (byte) '3',
                    (byte) '4', (byte) '5', (byte) '6', (byte) '7',
                    (byte) '8', (byte) '9', (byte) 'a', (byte) 'b',
                    (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f'
            };
            byte[] hexChars = new byte[rawHmac.length * 2];
            for (int j = 0; j < rawHmac.length; j++) {
                int v = rawHmac[j] & 0xFF;
                hexChars[j * 2] = hexArray[v >>> 4];
                hexChars[j * 2 + 1] = hexArray[v & 0x0F];
            }
            return new String(hexChars);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}
分享:

    相关文档

    相关产品

文档是否有解决您的问题?

提交成功!非常感谢您的反馈,我们会继续努力做到更好!
反馈提交失败,请稍后再试!

*必选

请至少选择或填写一项反馈信息

字符长度不能超过200

提交反馈 取消

如您有其它疑问,您也可以通过华为云社区问答频道来与我们联系探讨

智能客服提问云社区提问