Gamecards
- If you are playing a gamecard, your certification is your gamecard's unique certificate. This is signed by Nintendo using RSA-2048-PCKS#1 at the time your gamecard is written, and contains encrypted information about your gamecard (this includes what game is on the gamecard, among other, unknown details).
- In the gamecard case, the data uploaded to aauth is "application_id=%016llx&application_version=%08x&device_auth_token=%.*s&media_type=GAMECARD&cert=%.*s", formatted with the title ID for the game being played, the version of the game being played, the token retrieved from dauth, and the gamecard's certificate (retrieved from FS via the "GetGameCardDeviceCertificate" command), formatted as url-safe base64.
- This code lives at .text+0x7DE1C for 5.0.0 account.
Digital games
- Your certification for a digital title is your console's ticket. For more technical details on what's inside a ticket, see my previous post on the eShop/CDN (linked up above). The important details are that tickets contain the Title ID of the game they certify, the Device ID of the console they authorize, the Nintendo Account ID used to purchase them, and are signed by Nintendo using RSA-2048 (cannot be forged).
- In this case, your console talks to the "es" service, and sends a command to retrieve an encrypted copy of the relevant ticket along with the encryption key. This encryption is AES-128 CBC, using a key randomly generated via cryptographically-secure random number generation. The key itself is encrypted using RSA-OAEP 2048. To skip over some technical details, this is a one-way encryption which only Nintendo can reverse, so even if you obtained the output of the es command you would not be able to determine the encryption key being used (and thus couldn't decrypt the ticket).
- The data uploaded to aauth in this case is "application_id=%016llx&application_version=%08x&device_auth_token=%.*s&media_type=DIGITAL&cert=%.*s&cert_key=%.*s", formatted with the title ID for the game being played, the version of the game being played, the token retrieved from dauth, the encrypted ticket encoded with url-safe base64, and the encrypted key encoded with url-safe base64.
- This code lives at .text+0x7DE98 for 5.0.0 account.
And that's that (with the additional case where if the console fails to find a certificate, a special "NO_CERT" request is sent, but this is pretty irrelevant because sending a NO_CERT request gets your console banned). In both relevant cases, aauth validates the certification, and returns a token only if the certification is valid.
Practical Impact
These are
extremely strong anti-piracy measures -- Nintendo did a great job, here.
In the gamecard case, Nintendo can detect whether or not the user connecting has data from a Nintendo-authorized gamecard for the correct title. This solves the 3ds-era issue of gamecard header data being shared between games. Additionally, there's a fair amount of other, unknown (encrypted) data in a certificate being uploaded -- and certificates are also linked to Nintendo Accounts when gold points are redeemed. Sharing of certificates should be fairly detectable, for Nintendo.
In the digital game case, Nintendo actually
perfectly prevents online piracy here. Tickets cannot be forged, and Nintendo can verify that the device ID in the ticket matches the device ID for the client cert connecting (banning on a mismatch), as well as that the account ID for the ticket matches the Nintendo Account authorizing to log in. Users who pirate games definitionally cannot have well-signed tickets for their consoles, and thus cannot connect online without getting an immediate ban -- this is exactly how I would have implemented authorization for digital games, if I were them.