AES encryption/decryption working.

now getting kicked for not verifying username
This commit is contained in:
Andrew Kelley 2013-01-01 01:49:38 -05:00
parent 321a97acb4
commit 3bc30a97b5
3 changed files with 60 additions and 3 deletions

View file

@ -11,6 +11,11 @@ module.exports = Parser;
function Parser(options) {
EventEmitter.call(this);
this.client = null;
this.encryptionEnabled = false;
this.cipher = null;
this.decipher = null;
}
util.inherits(Parser, EventEmitter);
@ -21,6 +26,7 @@ Parser.prototype.connect = function(port, host) {
});
var incomingBuffer = new Buffer(0);
self.client.on('data', function(data) {
if (self.encryptionEnabled) data = new Buffer(self.decipher.update(data), 'binary');
incomingBuffer = Buffer.concat([incomingBuffer, data]);
var parsed;
while (true) {
@ -42,7 +48,9 @@ Parser.prototype.connect = function(port, host) {
Parser.prototype.writePacket = function(packetId, params) {
var buffer = createPacketBuffer(packetId, params);
this.client.write(buffer);
var out = this.encryptionEnabled ? new Buffer(this.cipher.update(buffer), 'binary') : buffer;
if (this.encryptionEnabled) console.log("writing", packetId, "packet with encryption");
this.client.write(out);
};
var writers = {
@ -180,6 +188,7 @@ function parsePacket(buffer) {
for (i = 0; i < packetInfo.length; ++i) {
fieldInfo = packetInfo[i];
read = readers[fieldInfo.type];
assert.ok(read, "missing reader for data type: " + fieldInfo.type);
readResults = read(buffer, size);
if (readResults) {
results[fieldInfo.name] = readResults.value;

View file

@ -1,4 +1,34 @@
{
"1": [
{
"name": "entityId",
"type": "int"
},
{
"name": "levelType",
"type": "string"
},
{
"name": "gameMode",
"type": "byte"
},
{
"name": "dimension",
"type": "byte"
},
{
"name": "difficulty",
"type": "byte"
},
{
"name": "_notUsed1",
"type": "byte"
},
{
"name": "maxPlayers",
"type": "byte"
}
],
"2": [
{
"name": "protocolVersion",
@ -46,5 +76,11 @@
"name": "verifyToken",
"type": "byteArray"
}
],
"255": [
{
"name": "reason",
"type": "string"
}
]
}

16
test.js
View file

@ -32,8 +32,18 @@ parser.connect(25565, 'localhost');
var packetHandlers = {
0xFC: onEncryptionKeyResponse,
0xFD: onEncryptionKeyRequest,
0x01: onLoginRequest,
0xFF: onKick,
};
function onKick(packet) {
console.log("kick", packet);
}
function onLoginRequest(packet) {
console.log("login request", packet);
}
function onEncryptionKeyRequest(packet) {
console.log("enc key request");
crypto.randomBytes(16, function (err, sharedSecret) {
@ -43,6 +53,8 @@ function onEncryptionKeyRequest(packet) {
var encryptedSharedSecretBuffer = new Buffer(encryptedSharedSecret, 'base64');
var encryptedVerifyToken = pubKey.encrypt(packet.verifyToken, 'binary', 'base64', ursa.RSA_PKCS1_PADDING);
var encryptedVerifyTokenBuffer = new Buffer(encryptedVerifyToken, 'base64');
parser.cipher = crypto.createCipheriv('aes-128-cfb8', sharedSecret, sharedSecret);
parser.decipher = crypto.createDecipheriv('aes-128-cfb8', sharedSecret, sharedSecret);
console.log("write enc key response");
parser.writePacket(Parser.ENCRYPTION_KEY_RESPONSE, {
sharedSecret: encryptedSharedSecretBuffer,
@ -55,8 +67,8 @@ 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 });
parser.encryptionEnabled = true;
parser.writePacket(Parser.CLIENT_STATUSES, { payload: 0 });
}
function mcPubKeyToURsa(mcPubKeyBuffer) {