Skip to content

Commit

Permalink
加密和心跳协议
Browse files Browse the repository at this point in the history
  • Loading branch information
闫逍旭 committed Dec 27, 2015
1 parent e05ac76 commit a66c3ed
Show file tree
Hide file tree
Showing 30 changed files with 1,370 additions and 392 deletions.
6 changes: 3 additions & 3 deletions mpush-api/src/main/java/com/shinemo/mpush/api/Constants.java
Expand Up @@ -10,9 +10,9 @@ public interface Constants {
byte[] EMPTY_BYTES = new byte[0];
int MAX_PACKET_SIZE = 1024;
int HEADER_LEN = 13;
byte MAGIC_NUM1 = (byte) 33;
byte MAGIC_NUM2 = (byte) 99;
long TIME_DELAY = 58L;
short MAGIC_NUM = 1122;
byte HB = '\n';
long TIME_DELAY = 1L;

String JVM_LOG_PATH = "/opt/";

Expand Down
Expand Up @@ -8,13 +8,15 @@ public class SessionInfo {
public final String osVersion;
public final String clientVersion;
public final String deviceId;
public final String desKey;
public final byte[] sessionKey;
public final byte[] iv;

public SessionInfo(String osName, String osVersion, String clientVersion, String deviceId, String desKey) {
public SessionInfo(String osName, String osVersion, String clientVersion, String deviceId, byte[] sessionKey, byte[] iv) {
this.osName = osName;
this.osVersion = osVersion;
this.clientVersion = clientVersion;
this.deviceId = deviceId;
this.desKey = desKey;
this.sessionKey = sessionKey;
this.iv = iv;
}
}
@@ -1,6 +1,5 @@
package com.shinemo.mpush.api.protocol;

import com.google.common.base.Strings;
import com.shinemo.mpush.api.Constants;

import java.io.Serializable;
Expand All @@ -9,14 +8,15 @@

/**
* Created by ohun on 2015/12/19.
* magic(2)+cmd(1)+version(1)+flags(1)+msgId(4)+length(4)+body(n)
* length(4)+cmd(1)+cc(2)+flags(1)+sessionId(4)+lrc(1)+body(n)
*/
public class Packet implements Serializable {
private static final long serialVersionUID = -2725825199998223372L;
public byte command;
public byte version;
public byte cmd;
public short cc;
public byte flags;
public int msgId;
public int sessionId;
public byte lrc;
public byte[] body;

public int getBodyLength() {
Expand All @@ -30,10 +30,11 @@ public String getStringBody() {
@Override
public String toString() {
return "Packet{" +
"command=" + command +
", version=" + version +
"cmd=" + cmd +
", cc=" + cc +
", flags=" + flags +
", msgId=" + msgId +
", sessionId=" + sessionId +
", lrc=" + lrc +
", body=" + Arrays.toString(body) +
'}';
}
Expand Down
Expand Up @@ -2,6 +2,7 @@

import com.shinemo.mpush.api.Constants;
import com.shinemo.mpush.api.exception.DecodeException;
import com.shinemo.mpush.api.protocol.Command;
import com.shinemo.mpush.api.protocol.Packet;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
Expand All @@ -11,15 +12,29 @@

/**
* Created by ohun on 2015/12/19.
* magic(2)+length(4)+cmd(1)+version(1)+flags(1)+msgId(4)+body(n)
* length(4)+cmd(1)+cc(2)+flags(1)+sessionId(4)+lrc(1)+body(n)
*/
public class PacketDecoder extends ByteToMessageDecoder {

@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
decodeHeartbeat(in, out);
decodeFrames(in, out);
}

private void decodeHeartbeat(ByteBuf in, List<Object> out) {
while (in.isReadable()) {
if (in.readByte() == Constants.HB) {
Packet packet = new Packet();
packet.cmd = Command.Heartbeat.cmd;
out.add(packet);
} else {
in.readerIndex(in.readerIndex() - 1);
break;
}
}
}

private void decodeFrames(ByteBuf in, List<Object> out) throws Exception {
try {
while (in.readableBytes() >= Constants.HEADER_LEN) {
Expand All @@ -35,9 +50,9 @@ private void decodeFrames(ByteBuf in, List<Object> out) throws Exception {

private Packet decodeFrame(ByteBuf in) throws Exception {
int bufferSize = in.readableBytes();
if (in.readByte() != Constants.MAGIC_NUM1 || in.readByte() != Constants.MAGIC_NUM2) {
/*if (in.readShort() != Constants.MAGIC_NUM) {
throw new RuntimeException("ERROR MAGIC_NUM");
}
}*/
int bodyLength = in.readInt();
if (bufferSize < (bodyLength + Constants.HEADER_LEN)) {
throw new DecodeException("invalid frame");
Expand All @@ -47,9 +62,10 @@ private Packet decodeFrame(ByteBuf in) throws Exception {

private Packet readPacket(ByteBuf in, int bodyLength) {
byte command = in.readByte();
byte version = in.readByte();
short cc = in.readShort();
byte flags = in.readByte();
int msgId = in.readInt();
int sessionId = in.readInt();
byte lrc = in.readByte();
byte[] body = null;
if (bodyLength > 0) {
if (bodyLength > Constants.MAX_PACKET_SIZE) {
Expand All @@ -59,10 +75,11 @@ private Packet readPacket(ByteBuf in, int bodyLength) {
in.readBytes(body);
}
Packet packet = new Packet();
packet.command = command;
packet.version = version;
packet.cmd = command;
packet.cc = cc;
packet.flags = flags;
packet.msgId = msgId;
packet.sessionId = sessionId;
packet.lrc = lrc;
packet.body = body;
return packet;
}
Expand Down
@@ -1,31 +1,35 @@
package com.shinemo.mpush.connection.netty.codec;

import com.shinemo.mpush.api.Constants;
import com.shinemo.mpush.api.protocol.Command;
import com.shinemo.mpush.api.protocol.Packet;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

/**
* Created by ohun on 2015/12/19.
* length(4)+cmd(1)+cc(2)+flags(1)+sessionId(4)+lrc(1)+body(n)
*/
@ChannelHandler.Sharable
public class PacketEncoder extends MessageToByteEncoder<Packet> {
public static final PacketEncoder INSTANCE = new PacketEncoder();

@Override
protected void encode(ChannelHandlerContext ctx, Packet packet, ByteBuf out) throws Exception {
out.writeByte(Constants.MAGIC_NUM1);
out.writeByte(Constants.MAGIC_NUM2);
out.writeInt(packet.getBodyLength());
out.writeByte(packet.command);
out.writeByte(packet.flags);
out.writeByte(packet.version);
out.writeInt(packet.msgId);
if (packet.getBodyLength() > 0) {
out.writeBytes(packet.body);
if (packet.cmd == Command.Heartbeat.cmd) {
out.writeByte(Constants.HB);
} else {
out.writeInt(packet.getBodyLength());
out.writeByte(packet.cmd);
out.writeShort(packet.cc);
out.writeByte(packet.flags);
out.writeInt(packet.sessionId);
out.writeByte(packet.lrc);
if (packet.getBodyLength() > 0) {
out.writeBytes(packet.body);
}
}
}
}
Expand Up @@ -31,9 +31,7 @@ public ConnectionHandler(MessageReceiver receiver) {

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
log.warn(ctx.channel().remoteAddress() + ", channelRead");
Connection connection = ConnectionManager.INSTANCE.get(ctx.channel());

receiver.onMessage((Packet) msg, connection);
}

Expand Down
Expand Up @@ -4,61 +4,57 @@
import com.shinemo.mpush.api.protocol.Command;
import com.shinemo.mpush.api.protocol.Packet;
import com.shinemo.mpush.core.message.FastConnectMessage;
import com.shinemo.mpush.core.message.HandShakeMessage;
import com.shinemo.mpush.core.security.CredentialManager;
import com.shinemo.mpush.core.message.HandshakeMessage;
import com.shinemo.mpush.core.message.HandshakeSuccessMsg;
import com.shinemo.mpush.core.security.CipherManager;
import com.shinemo.mpush.tools.Jsons;
import com.shinemo.mpush.tools.Strings;
import com.shinemo.mpush.tools.crypto.CryptoUtils;
import com.shinemo.mpush.tools.crypto.DESUtils;
import com.shinemo.mpush.tools.crypto.AESUtils;
import com.shinemo.mpush.tools.crypto.RSAUtils;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Map;

/**
* Created by ohun on 2015/12/24.
*/
public class ClientHandler extends ChannelHandlerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(ClientHandler.class);
private String clientKey = RandomStringUtils.randomAscii(CryptoUtils.DES_KEY_SIZE);
private byte[] clientKey = CipherManager.INSTANCE.randomAESKey();
private byte[] iv = CipherManager.INSTANCE.randomAESIV();

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
String token = getToken();
if (Strings.isBlank(token)) {
RSAPublicKey publicKey = CredentialManager.INSTANCE.getPublicKey();
HandShakeMessage message = new HandShakeMessage();
if (!Strings.isBlank(token)) {
RSAPublicKey publicKey = CipherManager.INSTANCE.getPublicKey();
HandshakeMessage message = new HandshakeMessage();
message.clientKey = clientKey;
message.iv = iv;
message.clientVersion = "1.0.1";
message.deviceId = "1111111111111";
message.osName = "android";
message.osVersion = "5.0";
message.timestamp = System.currentTimeMillis();

Packet packet = new Packet();
packet.command = Command.Handshake.cmd;
packet.version = 0;
packet.flags = 0;
packet.msgId = 1;
packet.cmd = Command.Handshake.cmd;
packet.sessionId = 1;
packet.body = RSAUtils.encryptByPublicKey(Jsons.toJson(message).getBytes(Constants.UTF_8), publicKey);
ctx.writeAndFlush(packet);
} else {
FastConnectMessage message = new FastConnectMessage();
message.deviceId = "1111111111111";
message.tokenId = token;
Packet packet = new Packet();
packet.command = Command.FastConnect.cmd;
packet.version = 0;
packet.flags = 0;
packet.msgId = 1;
packet.cmd = Command.FastConnect.cmd;
packet.sessionId = 1;
packet.body = Jsons.toJson(message).getBytes(Constants.UTF_8);
ctx.writeAndFlush(packet);
}
Expand All @@ -77,14 +73,14 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
LOGGER.info("client," + ctx.channel().remoteAddress().toString(), "channelRead", msg);
if (msg instanceof Packet) {
Packet packet = (Packet) msg;
Command command = Command.toCMD(packet.command);
Command command = Command.toCMD(packet.cmd);
if (command == Command.Handshake) {
String raw = new String(DESUtils.decryptDES(packet.body, clientKey), Constants.UTF_8);
Map<String, Serializable> resp = Jsons.fromJson(raw, Map.class);
String raw = new String(AESUtils.decrypt(packet.body, clientKey, iv), Constants.UTF_8);
HandshakeSuccessMsg resp = Jsons.fromJson(raw, HandshakeSuccessMsg.class);
LOGGER.info("hand shake success, message=" + raw);
String desKey = CryptoUtils.mixString(clientKey, (String) resp.get("serverKey"));
LOGGER.info("会话密钥:{},clientKey={}, serverKey={}", desKey, clientKey, resp.get("serverKey"));
saveToken((String) resp.get("tokenId"));
byte[] sessionKey = CipherManager.INSTANCE.mixKey(clientKey, resp.serverKey);
LOGGER.info("会话密钥:{},clientKey={}, serverKey={}", sessionKey, clientKey, resp.serverKey);
saveToken(resp.sessionId);
} else if (command == Command.FastConnect) {
LOGGER.info("fast connect success, message=" + packet.getStringBody());
}
Expand Down

0 comments on commit a66c3ed

Please sign in to comment.