Refactor NpTicket parser and add NpTicket signature documentation (#784)

* Refactor NpTicket parser and add NpTicket signature documentation

* Update TickerBuilder chaining style

* Fix SectionHeader position returning wrong value

* Don't attempt to parse ticket if it is less than 8 bytes
This commit is contained in:
Josh 2023-06-07 00:16:29 -05:00 committed by GitHub
commit 2f11731a8e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 506 additions and 247 deletions

57
Documentation/Tickets.md Normal file
View file

@ -0,0 +1,57 @@
# PS3 Authentication Tickets
Authentication tickets, commonly referred to as NpTickets or X-I-5 tickets are binary blobs used by third-party game servers
to identify and authenticate users.
For more information about the format of tickets see either the [article written by the psdevwiki](https://www.psdevwiki.com/ps3/X-I-5-Ticket)
or the write-up done by the [Skate 3 server team](https://github.com/hallofmeat/Skateboard3Server/blob/master/docs/PS3Ticket.md)
PSN uses ECDSA for securely verifying that a ticket was indeed generated by PSN and hasn't been tampered with
The exact specifics of the system are unknown but it's believed that each game or in some instances groups of games (The LBP series for example)
are given a single unique identifier such that any tickets with that identifier are guaranteed to be signed
using the same private key. Therefore, with that identifier in hand you can determine what public
key you should use to verify a ticket.
## ECDSA specifics
The PSN implementation of ECDSA signing uses the `secp192r1` curve also known as `nistp192`. The hashing algorithm used is `SHA-1`.
The message is the entire ticket sans the signature (the last 56 bytes).
The RPCN implementation of ECDSA signing uses the `secp224k1` curve. The hashing algorithm used is `SHA-224`.
The message for RPCN is the body section of the ticket including the body header.
The public key for RPCN is available on [the RPCN repo](https://github.com/RipleyTom/rpcn/blob/master/ticket_public.pem) or in the [known keys section](#known-public-keys).
## Finding public keys
Without going into the specifics of ECDSA it's possible to derive the public key given that you have the original message and know the curve
parameters and hashing algorithm.
A C# program has been written that can parse tickets and give the public keys that correspond to the private key used to sign the message.
The project is available on GitHub at https://github.com/Slendy/PubKeyFinder
While it's possible to find the public key given a single ticket, due to the way ECDSA works there are always 2 possible
points that can validate a signature. If you have more than one ticket though then each ticket will have at least
one matching point which can be used to identify the actual public key.
## Known Public Keys
### RPCN (All Games)
```
identifier: 5250434E (RPCN in ASCII)
x: b07bc0f0addb97657e9f389039e8d2b9c97dc2a31d3042e7d0479b93
y: d81c42b0abdf6c42191a31e31f93342f8f033bd529c2c57fdb5a0a7d
```
### LittleBigPlanet Series (PSN)
```
identfier: 719F1D4A
x: 39c62d061d4ee35c5f3f7531de0af3cf918346526edac727
y: a5d578b55113e612bf1878d4cc939d61a41318403b5bdf86
```
### Skate 3 (PSN)
```
identifier: 382DE58D
x: a93f2d73da8fe51c59872fad192b832f8b9dabde8587233
y: 93131936a54a0ea51117f74518e56aae95f6baff4b29f999
```