Beispiel #1
0
        private static EncryptionKeyRequestPacket CreateEncryptionRequest(RemoteClient client, Proxy proxy)
        {
            var verifyToken = new byte[4];
            var csp         = new RNGCryptoServiceProvider();

            csp.GetBytes(verifyToken);
            client.VerificationToken = verifyToken;

            var encodedKey = AsnKeyBuilder.PublicKeyToX509(proxy.ServerKey);
            var request    = new EncryptionKeyRequestPacket(client.AuthenticationHash, encodedKey.GetBytes(), verifyToken);

            return(request);
        }
Beispiel #2
0
        private static EncryptionKeyRequestPacket CreateEncryptionRequest(MinecraftClient client, MinecraftServer server)
        {
            var verifyToken = new byte[4];
            var csp         = new RNGCryptoServiceProvider();

            csp.GetBytes(verifyToken);
            // verifyToken = server.CryptoServiceProvider.Encrypt(verifyToken, false);
            // TODO: I think I'm encrypting that wrong
            // TODO: Confirm verify token validity

            var encodedKey = AsnKeyBuilder.PublicKeyToX509(server.ServerKey);
            var request    = new EncryptionKeyRequestPacket(client.AuthenticationHash,
                                                            encodedKey.GetBytes(), verifyToken);

            return(request);
        }
Beispiel #3
0
        private void InitializeEncryption(EncryptionKeyRequestPacket packet)
        {
            // We have to hijack the encryption here to be able to sniff the
            // connection. What we do is set up two unrelated crypto streams,
            // one for the server, one for the client. We actually act a bit
            // more like a real client or a real server in this particular
            // stage of the connection, because we generate a shared secret
            // as a client and a public key as a server, and liase with each
            // end of the connection without tipping them off to this. After
            // this is done, we wrap the connection in an AesStream and
            // everything works fine.

            // Interact with the server (acting as a client)

            // Generate our shared secret
            var secureRandom = RandomNumberGenerator.Create();

            ServerSharedKey = new byte[16];
            secureRandom.GetBytes(ServerSharedKey);

            // Parse the server public key
            var parser = new AsnKeyParser(packet.PublicKey);
            var key    = parser.ParseRSAPublicKey();

            // Encrypt shared secret and verification token
            var crypto = new RSACryptoServiceProvider();

            crypto.ImportParameters(key);
            byte[] encryptedSharedSecret = crypto.Encrypt(ServerSharedKey, false);
            byte[] encryptedVerification = crypto.Encrypt(packet.VerificationToken, false);

            // Create an 0xFC response to give the server
            ServerEncryptionResponse = new EncryptionKeyResponsePacket
            {
                SharedSecret      = encryptedSharedSecret,
                VerificationToken = encryptedVerification
            };

            // Authenticate with minecraft.net if need be
            if (packet.ServerId != "-")
            {
                try
                {
                    var session = Session.DoLogin(Settings.Username, Settings.Password);
                    // Generate session hash
                    byte[] hashData = Encoding.ASCII.GetBytes(packet.ServerId)
                                      .Concat(ServerSharedKey)
                                      .Concat(packet.PublicKey).ToArray();
                    var    hash      = Cryptography.JavaHexDigest(hashData);
                    var    webClient = new WebClient();
                    string result    = webClient.DownloadString("http://session.minecraft.net/game/joinserver.jsp?user="******"&sessionId=" + Uri.EscapeUriString(session.SessionId) +
                                                                "&serverId=" + Uri.EscapeUriString(hash));
                    if (result != "OK")
                    {
                        Console.WriteLine("Warning: Unable to login as user " + Settings.Username + ": " + result);
                    }
                    Console.WriteLine("(Session ID is {0})", session.SessionId);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Warning: Unable to login as user " + Settings.Username + ": " + e.Message);
                }
            }

            // Interact with the client (acting as a server)

            // Generate verification token
            ClientVerificationToken = new byte[4];
            secureRandom.GetBytes(ClientVerificationToken);
            // Encode public key as an ASN X509 certificate
            var encodedKey = AsnKeyBuilder.PublicKeyToX509(ServerKey);

            if (Settings.AuthenticateClients)
            {
                ClientAuthenticationHash = CreateHash();
            }
            else
            {
                ClientAuthenticationHash = "-";
            }

            ClientEncryptionRequest = new EncryptionKeyRequestPacket
            {
                VerificationToken = ClientVerificationToken,
                ServerId          = ClientAuthenticationHash,
                PublicKey         = encodedKey.GetBytes()
            };
            FinializeClientEncryption(new EncryptionKeyResponsePacket());
        }
Beispiel #4
0
        private static EncryptionKeyRequestPacket CreateEncryptionRequest(MinecraftClient client, MinecraftServer server)
        {
            var verifyToken = new byte[4];
            var csp = new RNGCryptoServiceProvider();
            csp.GetBytes(verifyToken);
            // verifyToken = server.CryptoServiceProvider.Encrypt(verifyToken, false);
            // TODO: I think I'm encrypting that wrong
            // TODO: Confirm verify token validity

            var encodedKey = AsnKeyBuilder.PublicKeyToX509(server.ServerKey);
            var request = new EncryptionKeyRequestPacket(client.AuthenticationHash,
                encodedKey.GetBytes(), verifyToken);
            return request;
        }