mirror of
https://github.com/unmojang/node-minecraft-protocol.git
synced 2025-09-27 13:14:41 -04:00
successfully getting the encryption key response
This commit is contained in:
parent
043cbd5882
commit
321a97acb4
103
lib/parser.js
103
lib/parser.js
@ -49,6 +49,7 @@ var writers = {
|
||||
'int': IntWriter,
|
||||
'byte': ByteWriter,
|
||||
'string': StringWriter,
|
||||
'byteArray': ByteArrayWriter,
|
||||
};
|
||||
|
||||
var readers = {
|
||||
@ -107,8 +108,19 @@ function StringWriter(value) {
|
||||
StringWriter.prototype.write = function(buffer, offset) {
|
||||
buffer.writeInt16BE(this.value.length, offset);
|
||||
this.encoded.copy(buffer, offset + 2);
|
||||
};
|
||||
|
||||
function ByteArrayWriter(value) {
|
||||
assert.ok(Buffer.isBuffer(value), "non buffer passed to ByteArrayWriter");
|
||||
this.value = value;
|
||||
this.size = 2 + value.length;
|
||||
}
|
||||
|
||||
ByteArrayWriter.prototype.write = function(buffer, offset) {
|
||||
buffer.writeInt16BE(this.value.length, offset);
|
||||
this.value.copy(buffer, offset + 2);
|
||||
};
|
||||
|
||||
function ByteWriter(value) {
|
||||
this.value = value;
|
||||
this.size = 1;
|
||||
@ -118,6 +130,15 @@ ByteWriter.prototype.write = function(buffer, offset) {
|
||||
buffer.writeInt8(this.value, offset);
|
||||
}
|
||||
|
||||
function UByteWriter(value) {
|
||||
this.value = value;
|
||||
this.size = 1;
|
||||
}
|
||||
|
||||
UByteWriter.prototype.write = function(buffer, offset) {
|
||||
buffer.writeUInt8(this.value, offset);
|
||||
};
|
||||
|
||||
function IntWriter(value) {
|
||||
this.value = value;
|
||||
this.size = 4;
|
||||
@ -129,11 +150,13 @@ IntWriter.prototype.write = function(buffer, offset) {
|
||||
|
||||
function createPacketBuffer(packetId, params) {
|
||||
var size = 1;
|
||||
var fields = [ new ByteWriter(packetId) ];
|
||||
var fields = [ new UByteWriter(packetId) ];
|
||||
var packet = packets[packetId];
|
||||
packet.forEach(function(fieldInfo) {
|
||||
var value = params[fieldInfo.name];
|
||||
var field = new writers[fieldInfo.type](value);
|
||||
var Writer = writers[fieldInfo.type];
|
||||
assert.ok(Writer, "missing writer for data type: " + fieldInfo.type);
|
||||
var field = new Writer(value);
|
||||
size += field.size;
|
||||
fields.push(field);
|
||||
});
|
||||
@ -171,3 +194,79 @@ function parsePacket(buffer) {
|
||||
results: results,
|
||||
};
|
||||
}
|
||||
|
||||
// packet ids
|
||||
Parser.KEEP_ALIVE = 0x00;
|
||||
Parser.LOGIN_REQUEST = 0x01;
|
||||
Parser.HANDSHAKE = 0x02;
|
||||
Parser.CHAT_MESSAGE = 0x03;
|
||||
Parser.TIME_UPDATE = 0x04;
|
||||
Parser.ENTITY_EQUIPMENT = 0x05;
|
||||
Parser.SPAWN_POSITION = 0x06;
|
||||
Parser.USE_ENTITY = 0x07;
|
||||
Parser.UPDATE_HEALTH = 0x08;
|
||||
Parser.RESPAWN = 0x09;
|
||||
Parser.PLAYER = 0x0A;
|
||||
Parser.PLAYER_POSITION = 0x0B;
|
||||
Parser.PLAYER_LOOK = 0x0C;
|
||||
Parser.PLAYER_POSITION_AND_LOOK = 0x0D;
|
||||
Parser.PLAYER_DIGGING = 0x0E;
|
||||
Parser.PLAYER_BLOCK_PLACEMENT = 0x0F;
|
||||
Parser.HELD_ITEM_CHANGE = 0x10;
|
||||
Parser.USE_BED = 0x11;
|
||||
Parser.ANIMATION = 0x12;
|
||||
Parser.ENTITY_ACTION = 0x13;
|
||||
Parser.SPAWN_NAMED_ENTITY = 0x14;
|
||||
Parser.COLLECT_ITEM = 0x16;
|
||||
Parser.SPAWN_OBJECT_VEHICLE = 0x17;
|
||||
Parser.SPAWN_MOB = 0x18;
|
||||
Parser.SPAWN_PAINTING = 0x19;
|
||||
Parser.SPAWN_EXPERIENCE_ORB = 0x1A;
|
||||
Parser.ENTITY_VELOCITY = 0x1C;
|
||||
Parser.DESTROY_ENTITY = 0x1D;
|
||||
Parser.ENTITY = 0x1E;
|
||||
Parser.ENTITY_RELATIVE_MOVE = 0x1F;
|
||||
Parser.ENTITY_LOOK = 0x20;
|
||||
Parser.ENTITY_LOOK_AND_RELATIVE_MOVE = 0x21;
|
||||
Parser.ENTITY_TELEPORT = 0x22;
|
||||
Parser.ENTITY_HEAD_LOOK = 0x23;
|
||||
Parser.ENTITY_STATUS = 0x26;
|
||||
Parser.ATTACH_ENTITY = 0x27;
|
||||
Parser.ENTITY_METADATA = 0x28;
|
||||
Parser.ENTITY_EFFECT = 0x29;
|
||||
Parser.REMOVE_ENTITY_EFFECT = 0x2A;
|
||||
Parser.SET_EXPERIENCE = 0x2B;
|
||||
Parser.CHUNK_DATA = 0x33;
|
||||
Parser.MULTI_BLOCK_CHANGE = 0x34;
|
||||
Parser.BLOCK_CHANGE = 0x35;
|
||||
Parser.BLOCK_ACTION = 0x36;
|
||||
Parser.BLOCK_BREAK_ANIMATION = 0x37;
|
||||
Parser.MAP_CHUNK_BULK = 0x38;
|
||||
Parser.EXPLOSION = 0x3C;
|
||||
Parser.SOUND_OR_PARTICLE_EFFECT = 0x3D;
|
||||
Parser.NAMED_SOUND_EFFECT = 0x3E;
|
||||
Parser.CHANGE_GAME_STATE = 0x46;
|
||||
Parser.SPAWN_GLOBAL_ENTITY = 0x47;
|
||||
Parser.OPEN_WINDOW = 0x64;
|
||||
Parser.CLOSE_WINDOW = 0x65;
|
||||
Parser.CLICK_WINDOW = 0x66;
|
||||
Parser.SET_SLOT = 0x67;
|
||||
Parser.SET_WINDOW_ITEMS = 0x68;
|
||||
Parser.UPDATE_WINDOW_PROPERTY = 0x69;
|
||||
Parser.CONFIRM_TRANSACTION = 0x6A;
|
||||
Parser.CREATIVE_INVENTORY_ACTION = 0x6B;
|
||||
Parser.ENCHANT_ITEM = 0x6C;
|
||||
Parser.UPDATE_SIGN = 0x82;
|
||||
Parser.ITEM_DATA = 0x83;
|
||||
Parser.UPDATE_TILE_ENTITY = 0x84;
|
||||
Parser.INCREMENT_STATISTIC = 0xC8;
|
||||
Parser.PLAYER_LIST_ITEM = 0xC9;
|
||||
Parser.PLAYER_ABILITIES = 0xCA;
|
||||
Parser.TAB_COMPLETE = 0xCB;
|
||||
Parser.CLIENT_SETTINGS = 0xCC;
|
||||
Parser.CLIENT_STATUSES = 0xCD;
|
||||
Parser.PLUGIN_MESSAGE = 0xFA;
|
||||
Parser.ENCRYPTION_KEY_RESPONSE = 0xFC;
|
||||
Parser.ENCRYPTION_KEY_REQUEST = 0xFD;
|
||||
Parser.SERVER_LIST_PING = 0xFE;
|
||||
Parser.DISCONNECT_KICK = 0xFF;
|
||||
|
16
packets.json
16
packets.json
@ -17,6 +17,22 @@
|
||||
"type": "int"
|
||||
}
|
||||
],
|
||||
"205": [
|
||||
{
|
||||
"name": "payload",
|
||||
"type": "byte"
|
||||
}
|
||||
],
|
||||
"252": [
|
||||
{
|
||||
"name": "sharedSecret",
|
||||
"type": "byteArray"
|
||||
},
|
||||
{
|
||||
"name": "verifyToken",
|
||||
"type": "byteArray"
|
||||
}
|
||||
],
|
||||
"253": [
|
||||
{
|
||||
"name": "serverId",
|
||||
|
49
test.js
49
test.js
@ -1,9 +1,12 @@
|
||||
var Parser = require('./lib/parser');
|
||||
var Parser = require('./lib/parser')
|
||||
, ursa = require('ursa')
|
||||
, crypto = require('crypto')
|
||||
, assert = require('assert')
|
||||
|
||||
var parser = new Parser();
|
||||
parser.on('connect', function() {
|
||||
console.info("connect");
|
||||
parser.writePacket(0x02, {
|
||||
parser.writePacket(Parser.HANDSHAKE, {
|
||||
protocolVersion: 51,
|
||||
userName: 'superjoe30',
|
||||
serverHost: 'localhost',
|
||||
@ -27,19 +30,43 @@ parser.on('end', function() {
|
||||
parser.connect(25565, 'localhost');
|
||||
|
||||
var packetHandlers = {
|
||||
0xFC: onEncryptionKeyResponse,
|
||||
0xFD: onEncryptionKeyRequest,
|
||||
};
|
||||
|
||||
function onEncryptionKeyRequest(packet) {
|
||||
var sharedSecret = randomBuffer(16);
|
||||
console.log("enc key request");
|
||||
crypto.randomBytes(16, function (err, sharedSecret) {
|
||||
assert.ifError(err);
|
||||
var pubKey = mcPubKeyToURsa(packet.publicKey);
|
||||
var encryptedSharedSecret = pubKey.encrypt(sharedSecret, 'binary', 'base64', ursa.RSA_PKCS1_PADDING);
|
||||
var encryptedSharedSecretBuffer = new Buffer(encryptedSharedSecret, 'base64');
|
||||
var encryptedVerifyToken = pubKey.encrypt(packet.verifyToken, 'binary', 'base64', ursa.RSA_PKCS1_PADDING);
|
||||
var encryptedVerifyTokenBuffer = new Buffer(encryptedVerifyToken, 'base64');
|
||||
console.log("write enc key response");
|
||||
parser.writePacket(Parser.ENCRYPTION_KEY_RESPONSE, {
|
||||
sharedSecret: encryptedSharedSecretBuffer,
|
||||
verifyToken: encryptedVerifyTokenBuffer,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function randomBuffer(size) {
|
||||
var buffer = new Buffer(size);
|
||||
var i, number;
|
||||
for (i = 0; i < size; ++i) {
|
||||
number = Math.floor(Math.random() * 256);
|
||||
buffer.writeUInt8(number, i);
|
||||
}
|
||||
return buffer;
|
||||
function onEncryptionKeyResponse(packet) {
|
||||
console.log("confirmation enc key response");
|
||||
assert.strictEqual(packet.sharedSecret.length, 0);
|
||||
assert.strictEqual(packet.verifyToken.length, 0);
|
||||
// TODO: enable AES encryption, then we can do the below line
|
||||
//parser.writePacket(Parser.CLIENT_STATUSES, { payload: 0 });
|
||||
}
|
||||
|
||||
function mcPubKeyToURsa(mcPubKeyBuffer) {
|
||||
var pem = "-----BEGIN PUBLIC KEY-----\n";
|
||||
var base64PubKey = mcPubKeyBuffer.toString('base64');
|
||||
var maxLineLength = 65;
|
||||
while (base64PubKey.length > 0) {
|
||||
pem += base64PubKey.substring(0, maxLineLength) + "\n";
|
||||
base64PubKey = base64PubKey.substring(maxLineLength);
|
||||
}
|
||||
pem += "-----END PUBLIC KEY-----\n";
|
||||
return ursa.createPublicKey(pem, 'utf8');
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user