private void HandleEncryptionResponse(EncryptionResponsePacket packet) { if (Authorized) { return; } if (AuthorizationStatus.HasFlag(AuthorizationStatus.EncryprionEnabled)) { var pkcs = new PKCS1Signer(Module.Security.RSAKeyPair); var decryptedToken = pkcs.DeSignData(packet.VerificationToken); for (var i = 0; i < VerificationToken.Length; i++) { if (decryptedToken[i] != VerificationToken[i]) { SendPacket(new AuthorizationDisconnectPacket { Reason = "Unable to authenticate." }); return; } } Array.Clear(VerificationToken, 0, VerificationToken.Length); var sharedKey = pkcs.DeSignData(packet.SharedSecret); Stream = new ProtobufTransmission <SCONPacket>(Socket, new BouncyCastleAesStream(Socket, sharedKey)); } else { SendPacket(new AuthorizationDisconnectPacket { Reason = "Encryption not enabled!" }); } }
private void HandleEncryptionResponse(EncryptionResponsePacket packet) { byte[] decrypted = Server.RsaEncryption.Decrypt(packet.VerifyToken); for (int i = 0; i < _encryptionVerification.Length; i++) { if (!decrypted[i].Equals(_encryptionVerification[i])) { Log.Warn("Encryption verification failed!"); return; } } byte[] decryptedSharedSecret = Server.RsaEncryption.Decrypt(packet.SharedSecret); Array.Resize(ref decryptedSharedSecret, 16); InitEncryption(decryptedSharedSecret); if (!AuthMojang()) //TODO: Check if we are in online mode. { } ChangeToPlay(); }
private void HandleEncryptionResponse(EncryptionResponsePacket packet) { if (IsInitialized) { return; } if ((AuthorizationStatus & AuthorizationStatus.EncryprionEnabled) != 0) { /* * var pkcs = new PKCS1Signer(Module.Security.RSAKeyPair); * * var decryptedToken = pkcs.DeSignData(packet.VerificationToken); * for (int i = 0; i < VerificationToken.Length; i++) * if (decryptedToken[i] != VerificationToken[i]) * { * SendPacket(new AuthorizationDisconnectPacket { Reason = "Unable to authenticate." }); * return; * } * Array.Clear(VerificationToken, 0, VerificationToken.Length); * * var sharedKey = pkcs.DeSignData(packet.SharedSecret); * * // TODO * //Stream.InitializeEncryption(sharedKey); * Join(); * IsInitialized = true; */ } else { SendPacket(new AuthorizationDisconnectPacket { Reason = "Encryption not enabled!" }); } }
/// <summary> /// Gets the next packet from the server /// </summary> /// <returns></returns> public PacketData ReadNextPacket() { int packetId; byte[] payload; lock (_streamReadLock) { int length = VarInt.ReadNext(ReadBytes); List <byte> buffer = new List <byte>(); // check if data is compressed if (_compressionThreshold >= 0) { int dataLength = VarInt.ReadNext(ReadBytes); length -= VarInt.GetBytes(dataLength).Length; // remove size of data length from rest of packet length if (dataLength != 0) { byte[] compressedBuffer = ReadBytes(length); buffer.AddRange(ZlibStream.UncompressBuffer(compressedBuffer)); } else { buffer.AddRange(ReadBytes(length)); } } else { buffer.AddRange(ReadBytes(length)); } packetId = VarInt.ReadNext(buffer); payload = buffer.ToArray(); } // handles some stuff during login phase if (State == ProtocolState.LOGIN) { // handle compression packet if (packetId == (int)ClientboundIDs.LogIn_SetCompression) { _compressionThreshold = VarInt.ReadNext(new List <byte>(payload)); return(ReadNextPacket()); } // handle protocol encryption packet if (packetId == (int)ClientboundIDs.LogIn_EncryptionRequest) { var encRequestPkt = new EncryptionRequestPacket() { Payload = payload }; var aesSecret = CryptoHandler.GenerateSharedSecret(); var authHash = CryptoHandler.SHAHash(Encoding.ASCII.GetBytes(encRequestPkt.ServerID).Concat(aesSecret, encRequestPkt.PublicKey)); Debug.Log($"Sending hash to Mojang servers: {authHash}"); // check session with mojang if (!MojangAPI.JoinServer(authHash)) { throw new UnityException("Invalid session. (Try restarting game or relogging into Minecraft account)"); } // use pub key to encrypt shared secret using (var rsaProvider = CryptoHandler.DecodeRSAPublicKey(encRequestPkt.PublicKey)) { byte[] encSecret = rsaProvider.Encrypt(aesSecret, false); byte[] encToken = rsaProvider.Encrypt(encRequestPkt.VerifyToken, false); // respond to server with private key var responsePkt = new EncryptionResponsePacket() { SharedSecret = encSecret, VerifyToken = encToken }; WritePacket(responsePkt); // enable aes encryption _aesStream = new AesStream(Client.GetStream(), aesSecret); _encrypted = true; // read the next packet return(ReadNextPacket()); } } } return(new PacketData { ID = packetId, Payload = payload }); }