Skip to main content

Cryptography library for authenticating with World of Warcraft 1.2-3.3.5 clients.

Project description

wow_srp for Python

SRP6 library for Python that supports WoW version 1.2 through to 3.3.5.

This is just a Python wrapper around the original wow_srp library.

Installation

Install from PyPI with pip:

pip install wow-srp

Usage

Authentication

The module is split into functionality used by a server implementation and a client implementation.

Server

SrpVerifier -> SrpProof -> SrpServer

You will only want to save the username, salt, and password verifier for an account. Do not save the raw passwords on the server.

Construct an SrpVerifier through

>>> username = "A"
>>> password = "A"
>>> server = SrpVerifier.from_username_and_password(username, password)
>>> salt = server.salt()
>>> password_verifier = server.password_verifier()

Save the username, salt, and password_verifier in your database.

When a client connects, retrieve the username, salt, and password_verifier from your database and create an SrpVerifier through the constructor and convert it to an SrpProof:

>>> server = SrpVerifier(username, password_verifier, salt)
>>> server = server.into_proof()

The salt, server_public_key, generator, and large_safe_prime can then be sent to the client: The internal calculations use the generator and large safe prime from the functions, and these MUST be the ones sent to the client.

>>> salt = server.salt()
>>> server_public_key = server.server_public_key()
>>> generator = generator()
>>> large_safe_prime = large_safe_prime()

After receiving the client_public_key and client_proof, the proof can be attempted converted to an SrpServer.

>>> client_public_key = [1] * 32 # Arbitrary data to show usage
>>> client_proof = [0] * 20 # Arbitrary data to show usage
>>> try:
...    # Returns tuple of server, proof, but doctest will fail
...    server = server.into_server(client_public_key, client_proof)
... except:
...    print("Public key is invalid")
>>> if server is None:
...     print("Password was incorrect")
Password was incorrect

The client is now logged in and can be sent the realm list.

If the client loses connection it will attempt to reconnect. This requires a valid SrpServer to exist. In my opinion the reconnect method is insecure since it uses the session key that can easily be deduced by any third party and it should not be implemented in a production auth server.

>>> client_challenge_data = [0] * 16 # Arbitrary data to show usage
>>> client_proof = [0] * 20 # Arbitrary data to show usage
>>> # reconnect_valid = server.verify_reconnection_attempt(client_challenge_data, client_proof)

Client

SrpClientUser -> SrpClientChallenge -> SrpClient | -> SrpClientReconnection

The SrpClientReconnection is just a data struct that contains reconnection values.

The client does not have to save any values except for the username and password.

>>> username = "A"
>>> password = "A"
>>> client = SrpClientUser(username, password)

After getting the generator, large_safe_prime, server_public_key, and salt from the server, the SrpClientUser can be converted into an SrpClientChallenge.

>>> generator = 7
>>> large_safe_prime = [1] * 32
>>> server_public_key = [1] * 32
>>> salt = [0] * 32
>>> client = client.into_challenge(generator, large_safe_prime, server_public_key, salt)

The client can then verify that the server also has the correct password through the server_proof: This creates an SrpClient.

>>> server_proof = [0] * 20
>>> client = client.verify_server_proof(server_proof)
>>> if client is None:
...     print("Invalid password")
Invalid password

The SrpClient can attempt to reconnect using the server_reconnect_data:

>>> server_reconnect_data = [0] * 16
>>> # reconnect_data = client.calculate_reconnect_values(server_reconnect_data)

And then access the reconnect values from reconnect_data:

>>> # challenge_data = reconnect_data.challenge_data()
>>> # client_proof = reconnect_data.client_proof()

Header Encryption

Server

First, create a ProofSeed from for the version that you need:

>>> server_seed = VanillaProofSeed()
>>> server_seed_value = server_seed.seed()

Then send the value to the client in SMSG_AUTH_CHALLENGE.

After receiving CMSG_AUTH_SESSION from the client, convert the proof to a HeaderCrypto.

>>> # server_crypto = server_seed.into_server_header_crypto(username, session_key, client_proof, client_seed)

You can then encrypt and decrypt message headers with

>>> # data = server_crypto.encrypt_server_header(size, opcode)
>>> # size, opcode = server_crypto.decrypt_client_header(data)

Client

First, create a ProofSeed from for the version that you need:

>>> client_seed = VanillaProofSeed()
>>> client_seed_value = client_seed.seed()

Then convert the seed to a HeaderCrypto using the seed received from SMSG_AUTH_CHALLENGE.

>>> # client_proof, client_crypto = client_seed.into_client_header_crypto(username, session_key, server_seed)

Then send the client_proof and client_seed_value to the server through CMSG_AUTH_SESSION.

You can then encrypt and decrypt message headers with

>>> # data = client_crypto.encrypt_client_header(size, opcode)
>>> # size, opcode = client_crypto.decrypt_server_header(data)

Development

pip install maturin
curl https://pyenv.run | bash

# For fish
set -U PYENV_ROOT "$HOME/.pyenv"
fish_add_path "$PYENV_ROOT/bin"

pyenv init - | source
pyenv install 3.10
pyenv virtualenv 3.10 pyo3
pyenv activate pyo3
maturin develop

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wow_srp-0.4.0.tar.gz (18.1 kB view details)

Uploaded Source

File details

Details for the file wow_srp-0.4.0.tar.gz.

File metadata

  • Download URL: wow_srp-0.4.0.tar.gz
  • Upload date:
  • Size: 18.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.7.4

File hashes

Hashes for wow_srp-0.4.0.tar.gz
Algorithm Hash digest
SHA256 d568cbbb195885803bb25514f0b87935eb37e02cec5af9652ba475eb8273ae84
MD5 a870f054fcd5ed16fe4ca01fb08f9a52
BLAKE2b-256 70ddc267a7e1901e25ac18ec36d17077ebcd4e1d0472a3034d108e30113db691

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page