11package com .tencentyun ;
22
33// 使用旧版本 base64 编解码实现增强兼容性
4+
45import sun .misc .BASE64Encoder ;
56
67import java .io .UnsupportedEncodingException ;
1213
1314import javax .crypto .Mac ;
1415import javax .crypto .spec .SecretKeySpec ;
16+
1517import org .json .JSONObject ;
1618
1719public class TLSSigAPIv2 {
@@ -42,18 +44,18 @@ private String hmacsha256(String identifier, long currTime, long expire, String
4244 return "" ;
4345 } catch (NoSuchAlgorithmException e ) {
4446 return "" ;
45- } catch (InvalidKeyException e ) {
47+ } catch (InvalidKeyException e ) {
4648 return "" ;
4749 }
4850 }
4951
50- private String genSig (String identifier , long expire , byte [] userbuf ) {
52+ private String genUserSig (String userid , long expire , byte [] userbuf ) {
5153
52- long currTime = System .currentTimeMillis ()/ 1000 ;
54+ long currTime = System .currentTimeMillis () / 1000 ;
5355
5456 JSONObject sigDoc = new JSONObject ();
5557 sigDoc .put ("TLS.ver" , "2.0" );
56- sigDoc .put ("TLS.identifier" , identifier );
58+ sigDoc .put ("TLS.identifier" , userid );
5759 sigDoc .put ("TLS.sdkappid" , sdkappid );
5860 sigDoc .put ("TLS.expire" , expire );
5961 sigDoc .put ("TLS.time" , currTime );
@@ -63,26 +65,137 @@ private String genSig(String identifier, long expire, byte[] userbuf) {
6365 base64UserBuf = new BASE64Encoder ().encode (userbuf );
6466 sigDoc .put ("TLS.userbuf" , base64UserBuf );
6567 }
66- String sig = hmacsha256 (identifier , currTime , expire , base64UserBuf );
68+ String sig = hmacsha256 (userid , currTime , expire , base64UserBuf );
6769 if (sig .length () == 0 ) {
6870 return "" ;
6971 }
7072 sigDoc .put ("TLS.sig" , sig );
7173 Deflater compressor = new Deflater ();
7274 compressor .setInput (sigDoc .toString ().getBytes (Charset .forName ("UTF-8" )));
7375 compressor .finish ();
74- byte [] compressedBytes = new byte [2048 ];
76+ byte [] compressedBytes = new byte [2048 ];
7577 int compressedBytesLength = compressor .deflate (compressedBytes );
7678 compressor .end ();
7779 return (new String (Base64URL .base64EncodeUrl (Arrays .copyOfRange (compressedBytes ,
7880 0 , compressedBytesLength )))).replaceAll ("\\ s*" , "" );
7981 }
8082
81- public String genSig (String identifier , long expire ) {
82- return genSig (identifier , expire , null );
83+ /**
84+ * 用于生成实时音视频(TRTC)业务进房权限加密串,具体用途用法参考TRTC文档:https://cloud.tencent.com/document/product/647/32240
85+ * TRTC业务进房权限加密串需使用用户定义的userbuf
86+ * 生成 userbuf
87+ *
88+ * @param account 用户名
89+ * @param dwAuthID 数字房间号
90+ * @param dwExpTime 过期时间:该权限加密串的过期时间,超时时间内拿到该签名,并且发起进房间操作,时间为有效期
91+ * 实际填入userBuf为:expire,过期时间,当前时间 + 有效期(单位:秒)
92+ * @param dwPrivilegeMap 用户权限,255表示所有权限,主播0xff,观众0xab
93+ * @param dwAccountType 用户类型,默认为0
94+ * @return byte[] userbuf
95+ */
96+ public byte [] genUserBuf (String account , long dwAuthID , long dwExpTime ,
97+ long dwPrivilegeMap , long dwAccountType ) {
98+ //视频校验位需要用到的字段,按照网络字节序放入buf中
99+ /*
100+ cVer unsigned char/1 版本号,填0
101+ wAccountLen unsigned short /2 第三方自己的帐号长度
102+ account wAccountLen 第三方自己的帐号字符
103+ dwSdkAppid unsigned int/4 sdkappid
104+ dwAuthID unsigned int/4 群组号码
105+ dwExpTime unsigned int/4 过期时间 ,直接使用填入的值
106+ dwPrivilegeMap unsigned int/4 权限位,主播0xff,观众0xab
107+ dwAccountType unsigned int/4 第三方帐号类型
108+ */
109+ int accountLength = account .length ();
110+ int offset = 0 ;
111+ byte [] userbuf = new byte [1 + 2 + accountLength + 4 + 4 + 4 + 4 + 4 ];
112+
113+ //cVer
114+ userbuf [offset ++] = 0 ;
115+
116+ //wAccountLen
117+ userbuf [offset ++] = (byte ) ((accountLength & 0xFF00 ) >> 8 );
118+ userbuf [offset ++] = (byte ) (accountLength & 0x00FF );
119+
120+ //account
121+ for (; offset < 3 + accountLength ; ++offset ) {
122+ userbuf [offset ] = (byte ) account .charAt (offset - 3 );
123+ }
124+
125+ //dwSdkAppid
126+ userbuf [offset ++] = (byte ) ((sdkappid & 0xFF000000 ) >> 24 );
127+ userbuf [offset ++] = (byte ) ((sdkappid & 0x00FF0000 ) >> 16 );
128+ userbuf [offset ++] = (byte ) ((sdkappid & 0x0000FF00 ) >> 8 );
129+ userbuf [offset ++] = (byte ) (sdkappid & 0x000000FF );
130+
131+ //dwAuthId,房间号
132+ userbuf [offset ++] = (byte ) ((dwAuthID & 0xFF000000 ) >> 24 );
133+ userbuf [offset ++] = (byte ) ((dwAuthID & 0x00FF0000 ) >> 16 );
134+ userbuf [offset ++] = (byte ) ((dwAuthID & 0x0000FF00 ) >> 8 );
135+ userbuf [offset ++] = (byte ) (dwAuthID & 0x000000FF );
136+
137+ //expire,过期时间,当前时间 + 有效期(单位:秒)
138+ long currTime = System .currentTimeMillis () / 1000 ;
139+ long expire = currTime + dwExpTime ;
140+ userbuf [offset ++] = (byte ) ((expire & 0xFF000000 ) >> 24 );
141+ userbuf [offset ++] = (byte ) ((expire & 0x00FF0000 ) >> 16 );
142+ userbuf [offset ++] = (byte ) ((expire & 0x0000FF00 ) >> 8 );
143+ userbuf [offset ++] = (byte ) (expire & 0x000000FF );
144+
145+ //dwPrivilegeMap,权限位
146+ userbuf [offset ++] = (byte ) ((dwPrivilegeMap & 0xFF000000 ) >> 24 );
147+ userbuf [offset ++] = (byte ) ((dwPrivilegeMap & 0x00FF0000 ) >> 16 );
148+ userbuf [offset ++] = (byte ) ((dwPrivilegeMap & 0x0000FF00 ) >> 8 );
149+ userbuf [offset ++] = (byte ) (dwPrivilegeMap & 0x000000FF );
150+
151+ //dwAccountType,账户类型
152+ userbuf [offset ++] = (byte ) ((dwAccountType & 0xFF000000 ) >> 24 );
153+ userbuf [offset ++] = (byte ) ((dwAccountType & 0x00FF0000 ) >> 16 );
154+ userbuf [offset ++] = (byte ) ((dwAccountType & 0x0000FF00 ) >> 8 );
155+ userbuf [offset ++] = (byte ) (dwAccountType & 0x000000FF );
156+
157+ return userbuf ;
158+ }
159+
160+ /**
161+ * 【功能说明】用于签发 TRTC 和 IM 服务中必须要使用的 UserSig 鉴权票据
162+ *
163+ * 【参数说明】
164+ * @param userid - 用户id,限制长度为32字节,只允许包含大小写英文字母(a-zA-Z)、数字(0-9)及下划线和连词符。
165+ * @param expire - UserSig 票据的过期时间,单位是秒,比如 86400 代表生成的 UserSig 票据在一天后就无法再使用了。
166+ * @return usersig -生成的签名
167+ */
168+ public String genUserSig (String userid , long expire ) {
169+ return genUserSig (userid , expire , null );
83170 }
84171
85- public String genSigWithUserBuf (String identifier , long expire , byte [] userbuf ) {
86- return genSig (identifier , expire , userbuf );
172+ /**
173+ * 【功能说明】
174+ * 用于签发 TRTC 进房参数中可选的 PrivateMapKey 权限票据。
175+ * PrivateMapKey 需要跟 UserSig 一起使用,但 PrivateMapKey 比 UserSig 有更强的权限控制能力:
176+ * - UserSig 只能控制某个 UserID 有无使用 TRTC 服务的权限,只要 UserSig 正确,其对应的 UserID 可以进出任意房间。
177+ * - PrivateMapKey 则是将 UserID 的权限控制的更加严格,包括能不能进入某个房间,能不能在该房间里上行音视频等等。
178+ * 如果要开启 PrivateMapKey 严格权限位校验,需要在【实时音视频控制台】/【应用管理】/【应用信息】中打开“启动权限密钥”开关。
179+ *
180+ * 【参数说明】
181+ * @param userid - 用户id,限制长度为32字节,只允许包含大小写英文字母(a-zA-Z)、数字(0-9)及下划线和连词符。
182+ * @param expire - PrivateMapKey 票据的过期时间,单位是秒,比如 86400 生成的 PrivateMapKey 票据在一天后就无法再使用了。
183+ * @param roomid - 房间号,用于指定该 userid 可以进入的房间号
184+ * @param privilegeMap - 权限位,使用了一个字节中的 8 个比特位,分别代表八个具体的功能权限开关:
185+ * - 第 1 位:0000 0001 = 1,创建房间的权限
186+ * - 第 2 位:0000 0010 = 2,加入房间的权限
187+ * - 第 3 位:0000 0100 = 4,发送语音的权限
188+ * - 第 4 位:0000 1000 = 8,接收语音的权限
189+ * - 第 5 位:0001 0000 = 16,发送视频的权限
190+ * - 第 6 位:0010 0000 = 32,接收视频的权限
191+ * - 第 7 位:0100 0000 = 64,发送辅路(也就是屏幕分享)视频的权限
192+ * - 第 8 位:1000 0000 = 200,接收辅路(也就是屏幕分享)视频的权限
193+ * - privilegeMap == 1111 1111 == 255 代表该 userid 在该 roomid 房间内的所有功能权限。
194+ * - privilegeMap == 0010 1010 == 42 代表该 userid 拥有加入房间和接收音视频数据的权限,但不具备其他权限。
195+ * @return usersig - 生成带userbuf的签名
196+ */
197+ public String genPrivateMapKey (String userid , long expire , long roomid , long privilegeMap ) {
198+ byte [] userbuf = genUserBuf (userid , roomid , expire , privilegeMap , 0 ); //生成userbuf
199+ return genUserSig (userid , expire , userbuf );
87200 }
88201}
0 commit comments