添加android客户端签名验证功能

This commit is contained in:
heavyrian2012
2022-11-18 16:01:17 +08:00
parent 3ccfd9a29b
commit b4d163e144
10 changed files with 106 additions and 7 deletions
@@ -110,6 +110,9 @@ public final class BrokerConstants {
public static final String TOKEN_SECRET_KEY = "token.key";
public static final String TOKEN_EXPIRE_TIME = "token.expire_time";
public static final String CONNECT_CLIENT_SIGNATURE_LIST = "connect.client_signature_list";
public static final String CONNECT_REJECT_EMPTY_SIGNATURE = "connect.reject_empty_signature";
public static final String EMBED_DB_PROPERTY_NAME = "embed.db";
public static final String DB_AUTO_CLEAN_HISTORY_MESSAGES = "db.auto_clean_history_messages";
public static final String H2DB_PATH = "h2db.path";
@@ -147,6 +147,9 @@ public class MemoryMessagesStore implements IMessagesStore {
private boolean mDisableStrangerChat = false;
private Set<String> mAllowStrangerChatSet = new HashSet<>();
private Set<String> mClientSignatureSet = new HashSet<>();
private boolean mRejectEmptySignature = true;
private long mChatroomParticipantIdleTime = 900000;
private boolean mChatroomRejoinWhenActive = true;
private boolean mChatroomCreateWhenNotExist = true;
@@ -191,6 +194,27 @@ public class MemoryMessagesStore implements IMessagesStore {
IS_CHATROOM_MESSAGE_REMOTE_HISTORY_MESSAGE = "1".equals(m_Server.getConfig().getProperty(MESSAGE_Remote_Chatroom_History_Message, "1"));
Constants.MAX_MESSAGE_QUEUE = Integer.parseInt(m_Server.getConfig().getProperty(MESSAGE_Max_Queue));
try {
String signatureList = m_Server.getConfig().getProperty(BrokerConstants.CONNECT_CLIENT_SIGNATURE_LIST);
if(!StringUtil.isNullOrEmptyAfterTrim(signatureList)) {
signatureList = signatureList.replace(",", ",");
for (String s : signatureList.split(",")) {
mClientSignatureSet.add(s.trim());
}
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if(!mClientSignatureSet.isEmpty()) {
mRejectEmptySignature = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.CONNECT_REJECT_EMPTY_SIGNATURE, "true"));
} else {
mRejectEmptySignature = false;
}
} catch (Exception e) {
}
try {
mDisableStrangerChat = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.MESSAGE_Disable_Stranger_Chat));
} catch (Exception e) {
@@ -4330,6 +4354,25 @@ public class MemoryMessagesStore implements IMessagesStore {
return UUIDGenerator.getUUID();
}
@Override
public boolean checkSignature(String signature) {
if(StringUtil.isNullOrEmptyAfterTrim(signature)) {
if(mRejectEmptySignature) {
LOG.info("Failed check signature, no signature");
return false;
} else {
return true;
}
} else {
if(mClientSignatureSet.contains(signature)) {
return true;
} else {
LOG.info("Failed check signature, signature no matched");
return false;
}
}
}
@Override
public void storeRetained(Topic topic, StoredMessage storedMessage) {
LOG.debug("Store retained message for topic={}, CId={}", topic, storedMessage.getClientID());
@@ -249,6 +249,8 @@ public interface IMessagesStore {
//使用了数据库,会比较慢,仅能用户用户/群组等id的生成
String getShortUUID();
boolean checkSignature(String signature);
/**
* Used to initialize all persistent store structures
*/
@@ -48,6 +48,7 @@ import win.liyufan.im.HttpUtils;
import win.liyufan.im.IMTopic;
import win.liyufan.im.Utility;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -339,6 +340,24 @@ public class ProtocolProcessor {
failedCredentials(channel);
return false;
}
if(session.getPlatform() == ProtoConstants.Platform.Platform_Android || session.getPlatform() == ProtoConstants.Platform.Platform_APad) {
byte[] signature = msg.payload().signatureInBytes();
String basedSign = null;
if (signature != null && signature.length > 0) {
signature = AES.AESDecrypt(signature, session.getSecret(), true);
}
if (signature != null && signature.length > 0) {
basedSign = Base64.getEncoder().encodeToString(signature);
}
if (!m_messagesStore.checkSignature(basedSign)) {
LOG.error("Bad signature of session <{}, {}>", session.getUsername(), session.getClientID());
failedBadSignature(channel);
return false;
}
}
session.setMqttVersion(mqttVersion);
} else {
LOG.error("Client didn't supply any password and MQTT anonymous mode is disabled CId={}", clientId);
@@ -446,6 +465,11 @@ public class ProtocolProcessor {
LOG.info("Client {} failed to connect with bad username or password.", session);
}
private void failedBadSignature(Channel session) {
session.writeAndFlush(connAck(CONNECTION_REFUSED_SIGNATURE_FAILURE));
LOG.info("Client {} failed to connect with bad signature.", session);
}
private void setIdleTime(ChannelPipeline pipeline, int idleTime) {
if (pipeline.names().contains("idleStateHandler")) {
pipeline.remove("idleStateHandler");