Difference between revisions of "Protocol Encryption"

From wiki.vg
Jump to navigation Jump to search
(fixed small spelling mistake)
(Clean-up)
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
Since the pre-release 1.2.5 12w17a the network protocol is encrypted.
+
As of 12w17a, minecraft implements SSL-like encryption.
  
Totally there are two different encryption methods used. RC4 to encrypt every network packet after the login, and RSA to transfer the RC4 packet at the login.
+
== Overview ==
  
After the client connects to the server the client sends a 0x02 Handshake Request, which contains the Protocol Version (currently 31) and the username of the player connecting to the server. Now the server responds with a 0xFD Encryption Request packet, which contains the RSA Public key, the server generated at the server startup, and the serverId, which is used for the minecraft.net authentication. The client now creates a random RC4 Key for the packet encryption.
+
#Client connects to server
 +
#'''C->S''' 0x02 handshake
 +
#'''S->C''' 0xFD encryption request - server sends its public key
 +
#Client generates symmetric key (shared secret)
 +
#Client pings minecraft.net
 +
#'''C->S''' 0xFC encryption response - client encrypts shared secret with server's public key and sends
 +
#Server decrypts shared secret with its private key
 +
#Server pings minecraft.net
 +
#'''S->C''' 0xFC encryption response - empty payload
 +
#Server enables RC4 stream encryption
 +
#Client enables RC4 stream encryption
 +
#'''C->S''' 0x01 login
 +
#'''S->C''' 0x01 login
 +
#see [[Protocol FAQ]] to get information about what happens next.
  
If the server id ist not "-" (offline mode) the client hashes the serverId  from the 0x0D packet, the public RSA key from the server and the generated RC4 secret key. Now the client sends a Http Request to
+
== Key Exchange ==
  
<pre>http://session.minecraft.net/game/joinserver.jsp?user=[username]&sessionId=[user_session]&serverId=[hash]</pre>
+
The server generates a 1024-bit RSA keypair on startup. The key, when packed into a 0xFD packet, is in PKCS#1 DER format. If you're struggling to import this using a crypto library, you can convert this to common PEM by base64-encoding and wrapping in '-----BEGIN PUBLIC KEY-----' and '-----END PUBLIC KEY-----'.
  
[user_session] is the user session he got when he logged into minecraft, and the [hash] is the hash generated above.
+
== Symmetric Encryption ==
  
The client uses the rsa public key to encrypt the RC4 Key and sends it to the server using a 0xFC Encryption Key Response packet. The server answeres with a 0xFC packet, too, with a empty byte-Array as shared key. The server decrypts the RC4 key with the generated private key. After this every packet on both sides are encrypted using the RC4 Key.  
+
On receipt of a 0xFD from the server, the client will generate a 16-byte shared secret, to be used with the RC4 stream cipher. It then encrypts it with the server's public key (PKCS#1 padded), and sends it to the server with a 0xFC.
  
After this the client sends a Login Request (0x01) packet, and the server responds with a Login Response packet (0x01).
+
The server decrypts the shared secret using its private key. It then sends a 0xFC to the client with an empty payload, and enables RC4 encryption. Similarly, the client will also enable encryption upon receipt of the empty 0xFC. From this point forward, everything is encrypted.
  
See [[Protocol FAQ]] to get infos about what happens next.
+
== minecraft.net ==
 +
 
 +
Both server and client need to make a request to minecraft.net if the server is in online-mode.
 +
 
 +
=== Client ===
 +
 
 +
After generating the shared secret, the client generates the following hash:
 +
<code>
 +
    hash := sha1(concat(a, b, c))
 +
    where:
 +
      a = serverId from 0xFC
 +
      b = server's public key
 +
      c = shared secret
 +
</code>
 +
 
 +
And sends an HTTP request to
 +
 
 +
<code>
 +
    <nowiki>http://session.minecraft.net/game/joinserver.jsp?user=</nowiki>''username''&sessionId=''[[Session#Login|user_session]]''&serverId=''hash''
 +
</code>
 +
 
 +
=== Server ===
 +
 
 +
TBC.

Revision as of 05:02, 4 May 2012

As of 12w17a, minecraft implements SSL-like encryption.

Overview

  1. Client connects to server
  2. C->S 0x02 handshake
  3. S->C 0xFD encryption request - server sends its public key
  4. Client generates symmetric key (shared secret)
  5. Client pings minecraft.net
  6. C->S 0xFC encryption response - client encrypts shared secret with server's public key and sends
  7. Server decrypts shared secret with its private key
  8. Server pings minecraft.net
  9. S->C 0xFC encryption response - empty payload
  10. Server enables RC4 stream encryption
  11. Client enables RC4 stream encryption
  12. C->S 0x01 login
  13. S->C 0x01 login
  14. see Protocol FAQ to get information about what happens next.

Key Exchange

The server generates a 1024-bit RSA keypair on startup. The key, when packed into a 0xFD packet, is in PKCS#1 DER format. If you're struggling to import this using a crypto library, you can convert this to common PEM by base64-encoding and wrapping in '-----BEGIN PUBLIC KEY-----' and '-----END PUBLIC KEY-----'.

Symmetric Encryption

On receipt of a 0xFD from the server, the client will generate a 16-byte shared secret, to be used with the RC4 stream cipher. It then encrypts it with the server's public key (PKCS#1 padded), and sends it to the server with a 0xFC.

The server decrypts the shared secret using its private key. It then sends a 0xFC to the client with an empty payload, and enables RC4 encryption. Similarly, the client will also enable encryption upon receipt of the empty 0xFC. From this point forward, everything is encrypted.

minecraft.net

Both server and client need to make a request to minecraft.net if the server is in online-mode.

Client

After generating the shared secret, the client generates the following hash:

   hash := sha1(concat(a, b, c))
   where:
     a = serverId from 0xFC
     b = server's public key
     c = shared secret

And sends an HTTP request to

   http://session.minecraft.net/game/joinserver.jsp?user=username&sessionId=user_session&serverId=hash

Server

TBC.