TRTC 使用服务端的Sig

This commit is contained in:
huangjian
2021-11-25 15:32:48 +08:00
parent f5c5c6a2e6
commit b41232d990
5 changed files with 8 additions and 190 deletions

View File

@@ -138,6 +138,7 @@ public class AvRoomPresenter extends BaseMvpPresenter<IAvRoomView> {
AvRoomDataManager.get().gender = roomInfo.getGender();
AvRoomDataManager.get().avatar = roomInfo.getAvatar();
AvRoomDataManager.get().isRoomFans = roomInfo.isRoomFans();
AvRoomDataManager.get().trtcSig = roomInfo.getTrtcSig();
AvRoomDataManager.get().setRedEnvelopeOpen(roomInfo.isRedEnvelopeOpen());
StatisticManager.Instance().onEvent(StatisticsProtocol.Event.EVENT_ROOM_LIST_TYPE,
"区分房间类型:" + roomInfo.getRoomTypeLable());

View File

@@ -1,186 +0,0 @@
package com.yizhuan.xchat_android_core.manager.trtc;
import android.util.Base64;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.zip.Deflater;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
/*
* Module: GenerateTestUserSig
*
* Function: 用于生成测试用的 UserSigUserSig 是腾讯云为其云服务设计的一种安全保护签名。
* 其计算方法是对 SDKAppID、UserID 和 EXPIRETIME 进行加密,加密算法为 HMAC-SHA256。
*
* Attention: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下:
*
* 本文件中的代码虽然能够正确计算出 UserSig但仅适合快速调通 SDK 的基本功能,不适合线上产品,
* 这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。
* 一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。
*
* 正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。
* 由于破解服务器的成本要高于破解客户端 App所以服务器计算的方案能够更好地保护您的加密密钥。
*
* Referencehttps://cloud.tencent.com/document/product/269/32688#Server
*/
public class GenerateTestUserSig {
/**
* 计算签名用的加密密钥,获取步骤如下:
* <p>
* step1. 进入腾讯云云通信[控制台](https://console.cloud.tencent.com/avc) ,如果还没有应用就创建一个,
* step2. 单击“应用配置”进入基础配置页面,并进一步找到“帐号体系集成”部分。
* step3. 点击“查看密钥”按钮,就可以看到计算 UserSig 使用的加密的密钥了,请将其拷贝并复制到如下的变量中
* <p>
* 注意该方案仅适用于调试Demo正式上线前请将 UserSig 计算代码和密钥迁移到您的后台服务器上,以避免加密密钥泄露导致的流量盗用。
* 文档https://cloud.tencent.com/document/product/269/32688#Server
*/
public static final String SECRETKEY = "b61263a7d5a47ec9f53641fdc4e8c86fcbda584a81b61578ef3f1a60381a4290";
/**
* 腾讯云 SDKAppId需要替换为您自己账号下的 SDKAppId。
* <p>
* 进入腾讯云云通信[控制台](https://console.cloud.tencent.com/avc) 创建应用,即可看到 SDKAppId
* 它是腾讯云用于区分客户的唯一标识。
*/
private static final int SDKAPPID = SDKConfig.TX_SDKAPPID;
/**
* 签名过期时间,建议不要设置的过短
* <p>
* 时间单位:秒
* 默认时间7 x 24 x 60 x 60 = 604800 = 7 天
*/
private static final int EXPIRETIME = 604800;
private long sdkappid;
private String key;
public GenerateTestUserSig(long sdkappid, String key) {
this.sdkappid = sdkappid;
this.key = key;
}
/**
* 计算 UserSig 签名
* <p>
* 函数内部使用 HMAC-SHA256 非对称加密算法,对 SDKAPPID、userId 和 EXPIRETIME 进行加密。
*
* @note: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下:
* <p>
* 本文件中的代码虽然能够正确计算出 UserSig但仅适合快速调通 SDK 的基本功能,不适合线上产品,
* 这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。
* 一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。
* <p>
* 正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。
* 由于破解服务器的成本要高于破解客户端 App所以服务器计算的方案能够更好地保护您的加密密钥。
* <p>
* 文档https://cloud.tencent.com/document/product/269/32688#Server
*/
public static String genTestUserSig(String userId) {
return new GenerateTestUserSig(SDKAPPID, SECRETKEY).genSig(userId, EXPIRETIME);
}
public static byte[] base64EncodeUrl(byte[] input) {
byte[] base64 = new String(Base64.encode(input, Base64.NO_WRAP)).getBytes();
for (int i = 0; i < base64.length; ++i)
switch (base64[i]) {
case '+':
base64[i] = '*';
break;
case '/':
base64[i] = '-';
break;
case '=':
base64[i] = '_';
break;
default:
break;
}
return base64;
}
private String hmacsha256(String identifier, long currTime, long expire, String base64Userbuf) {
String contentToBeSigned = "TLS.identifier:" + identifier + "\n"
+ "TLS.sdkappid:" + sdkappid + "\n"
+ "TLS.time:" + currTime + "\n"
+ "TLS.expire:" + expire + "\n";
if (null != base64Userbuf) {
contentToBeSigned += "TLS.userbuf:" + base64Userbuf + "\n";
}
try {
byte[] byteKey = key.getBytes("UTF-8");
Mac hmac = Mac.getInstance("HmacSHA256");
SecretKeySpec keySpec = new SecretKeySpec(byteKey, "HmacSHA256");
hmac.init(keySpec);
byte[] byteSig = hmac.doFinal(contentToBeSigned.getBytes("UTF-8"));
return new String(Base64.encode(byteSig, Base64.NO_WRAP));
} catch (UnsupportedEncodingException e) {
return "";
} catch (NoSuchAlgorithmException e) {
return "";
} catch (InvalidKeyException e) {
return "";
}
}
private String genSig(String identifier, long expire, byte[] userbuf) {
long currTime = System.currentTimeMillis() / 1000;
JSONObject sigDoc = new JSONObject();
try {
sigDoc.put("TLS.ver", "2.0");
sigDoc.put("TLS.identifier", identifier);
sigDoc.put("TLS.sdkappid", sdkappid);
sigDoc.put("TLS.expire", expire);
sigDoc.put("TLS.time", currTime);
} catch (JSONException e) {
e.printStackTrace();
}
String base64UserBuf = null;
if (null != userbuf) {
//base64UserBuf = new String(Base64.encode(userbuf,Base64.URL_SAFE));
base64UserBuf = Base64.encodeToString(userbuf, Base64.NO_WRAP);
try {
sigDoc.put("TLS.userbuf", base64UserBuf);
} catch (JSONException e) {
e.printStackTrace();
}
}
String sig = hmacsha256(identifier, currTime, expire, base64UserBuf);
if (sig.length() == 0) {
return "";
}
try {
sigDoc.put("TLS.sig", sig);
} catch (JSONException e) {
e.printStackTrace();
}
Deflater compressor = new Deflater();
String s = sigDoc.toString();
compressor.setInput(sigDoc.toString().getBytes(Charset.forName("UTF-8")));
compressor.finish();
byte[] compressedBytes = new byte[2048];
int compressedBytesLength = compressor.deflate(compressedBytes);
compressor.end();
return new String(GenerateTestUserSig.base64EncodeUrl(Arrays.copyOfRange(compressedBytes, 0, compressedBytesLength)));
}
public String genSig(String identifier, long expire) {
return genSig(identifier, expire, null);
}
public String genSigWithUserBuf(String identifier, long expire, byte[] userbuf) {
return genSig(identifier, expire, userbuf);
}
}

View File

@@ -12,9 +12,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.orhanobut.logger.Logger;
import com.yizhuan.xchat_android_constants.XChatConstants;
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager;
import com.yizhuan.xchat_android_core.manager.BaseEngine;
import com.yizhuan.xchat_android_core.manager.agora.RtcEngineHandler;
import com.yizhuan.xchat_android_core.music.db.bean.LocalMusicBean;
import com.yizhuan.xchat_android_core.music.model.PlayerModel;
import com.yizhuan.xchat_android_library.utils.config.BasicConfig;
@@ -23,7 +22,6 @@ import java.io.File;
import java.util.Locale;
import io.agora.rtc.Constants;
import io.agora.rtc.RtcEngine;
/**
@@ -75,7 +73,7 @@ public class TRtcEngineManager extends BaseEngine {
+ File.separator + BasicConfig.INSTANCE.getAppContext().getPackageName()
+ "/log/agora-rtc.log");
}
mRtcEngine.joinChannel(GenerateTestUserSig.genTestUserSig(String.valueOf(uid)), String.valueOf(channelId), null, (int) uid);
mRtcEngine.joinChannel(AvRoomDataManager.get().trtcSig, String.valueOf(channelId), null, (int) uid);
}
@Override

View File

@@ -173,6 +173,9 @@ public final class AvRoomDataManager {
public int gender;
public String avatar;
//TRTC SIG
public String trtcSig;
/**
* 缓存师父的 UID
*/

View File

@@ -188,6 +188,8 @@ public class RoomInfo implements Parcelable,Serializable {
*/
private String audioSdkType;
private String trtcSig;
// /**
// * 房间角标
// */