Ticket: Unterschied zwischen den Versionen
ICON (Diskussion | Beiträge) K (Textersetzung - „{{WiiTopicon}}“ durch „{{Top Icon Wii}}“) |
ICON (Diskussion | Beiträge) K (Textersetzung - „{{DSiTopicon}}“ durch „{{Top Icon DSi}}“) |
||
Zeile 178: | Zeile 178: | ||
<pre>b'\xd5e\xf8\x92+\xe6`[0$\t_\xe3\x8b\x0e%'</pre> | <pre>b'\xd5e\xf8\x92+\xe6`[0$\t_\xe3\x8b\x0e%'</pre> | ||
{{Top Icon Wii}} | {{Top Icon Wii}} | ||
{{ | {{Top Icon DSi}} |
Version vom 25. März 2018, 12:30 Uhr
Tickets sind in vielen verschlüsselten Dateien, die von der Wii genutzt werden, vorhanden (wie WADs oder Wii-Discs). Sie enthalten den verschlüsselten AES "Title-Key" und die Title ID der Daten und sind mit einem Zertifikat einer Zertifikatskette (welche für alle Titel gleich und im NAND gespeichert ist) signiert. Es gibt nur Tickets mit einer RSA-2048-Signatur. Tickets können bei freien, nicht konsolengebundenen Titeln vom Nintendo-Update-Server heruntergeladen werden (bspw. http://nus.cdn.shop.wii.com/ccs/download/000000010000003A/cetk für das Ticket vom IOS58).
Dateistruktur
Start | Ende | Länge | Beschreibung |
---|---|---|---|
0x0000 | 0x0003 | 4 | Signatur-Typ (immer 0x10001 für RSA-2048) |
0x0004 | 0x0103 | 256 | Signatur eines Zertifikatsschlüssels |
0x0104 | 0x013F | 60 | Padding (Immer 0 - alles nach diesem Feld wird von der obigen Signatur abgedeckt) |
0x0140 | 0x017F | 64 | Aussteller |
0x0180 | 0x01BB | 60 | ECDH-Daten; benutzt, um einen einmaligen Schlüssel während der Installation von konsolenspezifischen Titeln zu erstellen |
0x01BC | 0x01BE | 3 | Ungenutzt/Padding |
0x01BF | 0x01CE | 16 | Verschlüsselter Title-Key |
0x01CF | 0x01CF | 1 | Unbekannt |
0x01D0 | 0x01D7 | 8 | Ticket-ID (genutzt als Initialisierungsvektor für die Entschlüsselung des Title-Keys von konsolenspezifischen Titeln) |
0x01D8 | 0x01DB | 4 | Konsolen-ID |
0x01DC | 0x01E3 | 8 | Title ID / Initialisierungsvektor für die AES-CBC-Verschlüsselung |
0x01E4 | 0x01E5 | 2 | Unbekannt, meistens 0xFFFF |
0x01E6 | 0x01E7 | 2 | Ticket-Version |
0x01E8 | 0x01EB | 4 | Permitted Titles Mask |
0x01EC | 0x01EF | 4 | Permit mask. The current disc title is ANDed with the inverse of this mask to see if the result matches the Permitted Titles Mask |
0x01F0 | 0x01F0 | 1 | Title-Export per PRNG-Schlüssel erlaubt (1 = erlaubt, 0 = nicht erlaubt) |
0x01F1 | 0x01F1 | 1 | Common-Key-Index (0 = "Normaler" Common-Key, 1 = Koreanischer Common-Key) |
0x01F2 | 0x0221 | 48 | Unbekannt. 0 für nicht-VC, für VC alles 0, letztes Byte 1 |
0x0222 | 0x0261 | 64 | Inhaltszugriffsberechtigungen (ein Bit für jeden Inhalt) |
0x0262 | 0x0263 | 2 | Padding (Immer 0) |
0x0264 | 0x0267 | 4 | Zeitlimit aktivieren (1 = aktiviert, 0 = deaktiviert) |
0x0268 | 0x026B | 4 | Zeitlimit (Sekunden) |
0x026C | 0x02A3 | 56 | 7 mehr Zeitlimit-Strukturen wie oben |
Um an den entschlüsselten Title-Key zu kommen, müssen die 16 Byte beim Offset 0x1BF mit dem Common-Key entschlüsselt werden, wobei die Title ID (Offset 0x1DC) als Initialisierungsvektor genutzt wird (die letzten 8 Byte des IV sind 0).
Anwendungsbeispiel
Dieses Code-Beispiel in Python 3 entschlüsselt den Title-Key mithilfe des Common-Keys.
from binascii import hexlify
from io import BytesIO
from Crypto.Cipher import AES # https://pypi.python.org/pypi/pycryptodome
def decrypt_ticket(cetk):
# Read cetk into a BytesIO() object
ticket = BytesIO()
with open(cetk, "rb") as ticket_file:
ticket.write(ticket_file.read())
# Get Encrypted Title Key
ticket.seek(0x01BF)
encrypted_titlekey = ticket.read(16)
print('Encrypted Titlekey: ' + hexlify(encrypted_titlekey).decode())
# Get Initialization Vector (Title ID plus 8 zero-bytes)
ticket.seek(0x01DC)
tid = ticket.read(8)
print('Title ID: ' + hexlify(tid).decode())
iv = tid + b"\x00\x00\x00\x00\x00\x00\x00\x00"
print('Initialization Vector: ' + hexlify(iv).decode())
# Get Common Key
ticket.seek(0x01F1)
commonkey_index = unpack(">B", ticket.read(1))[0]
if commonkey_index == 0:
commonkey = b"\xEB\xE4\x2A\x22\x5E\x85\x93\xE4\x48\xD9\xC5\x45\x73\x81\xAA\xF7" # ebe42a225e8593e448d9c5457381aaf7
else:
commonkey = b'"\x63\xB8\x2B\xB4\xF4\x61\x4E\x2E\x13\xF2\xFE\xFB\xBA\x4C\x9B\x7E"' # 63b82bb4f4614e2e13f2fefbba4c9b7e
print('Decrypting with Common-Key: ' + hexlify(commonkey).decode())
# Decrypt Title Key
decrypted_titlekey = AES.new(commonkey, AES.MODE_CBC, iv).decrypt(encrypted_titlekey)
print('Decrypted Titlekey: ' + hexlify(decrypted_titlekey).decode())
return decrypted_titlekey
Gibt für das IOS58 auf der Konsole aus:
Encrypted Titlekey: 81e37262c5f11a064c0419f61c8a19c3 Title ID: 000000010000003a Initialization Vector: 000000010000003a0000000000000000 Decrypting with Common-Key: ebe42a225e8593e448d9c5457381aaf7 Decrypted Titlekey: d565f8922be6605b3024095fe38b0e25
Gibt den Title-Key als Bytes-Objekt zurück:
b'\xd5e\xf8\x92+\xe6`[0$\t_\xe3\x8b\x0e%'