Dieser Artikel betrifft den Nintendo DSi
Dieser Artikel betrifft die Nintendo Wii
Dieser Artikel betrifft die Nintendo Wii U

TMD: Unterschied zwischen den Versionen

Aus WiiDatabase Wiki
Zur Navigation springenZur Suche springen
Zeile 90: Zeile 90:
Die Signatur beinhaltet den SHA1-Hash der TMD (vom Aussteller bis zum Ende der Inhalte), welcher mit dem Private-Key verschlüsselt ist. Um diesen zu entschlüsseln, muss der Public-Key aus dem CP-Zertifikat (welches üblicherweise das erste angehängte Zertifikat ist) [[w:RSA-Kryptosystem#Erzeugung_des_öffentlichen_und_privaten_Schlüssels|gebildet]] und die Signatur entschlüsselt werden (nur die Daten, ohne Signatur-Typ und Padding). Stimmt der gebildete SHA1-Hash der TMD mit dem entschlüsselten Hash aus der Signatur überein, ist die TMD valide und von Nintendo signiert.
Die Signatur beinhaltet den SHA1-Hash der TMD (vom Aussteller bis zum Ende der Inhalte), welcher mit dem Private-Key verschlüsselt ist. Um diesen zu entschlüsseln, muss der Public-Key aus dem CP-Zertifikat (welches üblicherweise das erste angehängte Zertifikat ist) [[w:RSA-Kryptosystem#Erzeugung_des_öffentlichen_und_privaten_Schlüssels|gebildet]] und die Signatur entschlüsselt werden (nur die Daten, ohne Signatur-Typ und Padding). Stimmt der gebildete SHA1-Hash der TMD mit dem entschlüsselten Hash aus der Signatur überein, ist die TMD valide und von Nintendo signiert.


Wenn der SHA1-Hash nicht übereinstimmt und der gebildete SHA1-Hash der TMD mit `00` beginnt, ist diese [[Fakesigning|fakesigned]].
Wenn der SHA1-Hash nicht übereinstimmt und der gebildete SHA1-Hash der TMD mit <code>00</code> beginnt, ist diese [[Fakesigning|fakesigned]].


Das CP-Zertifikat ist von dem CA-Zertifikat signiert, welches wiederum mit dem Wii Root-Zertifikat signiert ist.
Das CP-Zertifikat ist von dem CA-Zertifikat signiert, welches wiederum mit dem Wii Root-Zertifikat signiert ist.

Version vom 28. November 2018, 11:14 Uhr

In den Title-Metadaten (Title Metadata) werden Informationen über einen Titel (Spiele, Kanäle, IOS, Systemsoftware, etc.) und alle installierten Inhalte gespeichert. Sie dient vereinfacht gesagt auch als eine Art Inhaltsverzeichnis, denn sie zeigt alle zugehörigen Inhalte inklusive ihrer Position, Größe und SHA1-Hash an. Sie können vom Nintendo-Update-Server heruntergeladen werden (bspw. http://nus.cdn.shop.wii.com/ccs/download/000000010000003A/tmd für die TMD des IOS58).

Struktur

Header

Start Länge Beschreibung
0x000 4 Signaturtyp
0x004 256 Signatur
0x104 60 Padding modulo 64
0x140 64 Aussteller
0x180 1 Version
0x181 1 ca_crl_version
0x182 1 signer_crl_version
0x183 1 Padding modulo 64
0x184 8 Benötigter Titel (bspw. benötigtes IOS)
0x18C 8 Title ID
0x194 4 Title-Typ
0x198 2 Gruppen-ID
0x19A 62 reserviert
0x1D8 4 Zugriffsrechte (Flags für DVD-Video- und vollem PPC-Hardware-Zugriff)
0x1DC 2 Version
0x1DE 2 Anzahl der Inhalte
0x1E0 2 Boot-Index
0x1E2 2 Padding modulo 64
0x1E4 36*Anzahl der Inhalte Inhalte

Signatur

Die Signatur beinhaltet den SHA1-Hash der TMD (vom Aussteller bis zum Ende der Inhalte), welcher mit dem Private-Key verschlüsselt ist. Um diesen zu entschlüsseln, muss der Public-Key aus dem CP-Zertifikat (welches üblicherweise das erste angehängte Zertifikat ist) gebildet und die Signatur entschlüsselt werden (nur die Daten, ohne Signatur-Typ und Padding). Stimmt der gebildete SHA1-Hash der TMD mit dem entschlüsselten Hash aus der Signatur überein, ist die TMD valide und von Nintendo signiert.

Wenn der SHA1-Hash nicht übereinstimmt und der gebildete SHA1-Hash der TMD mit 00 beginnt, ist diese fakesigned.

Das CP-Zertifikat ist von dem CA-Zertifikat signiert, welches wiederum mit dem Wii Root-Zertifikat signiert ist.

Inhalt

Start Länge Beschreibung
0x00 4 Inhalts-ID
0x04 2 Index
0x06 2 Typ
0x08 8 Größe
0x10 20 SHA1-Hash

Zertifikate

Start Länge Beschreibung
0x000 4 Signatur-Typ
0x004 256 Signatur
0x104 64 Aussteller
0x124 4 Tag
0x128 64 Name
0x168 Schlüssel

Anwendungsbeispiel

Dieses Code-Beispiel in Python 3 parst eine TMD.

from binascii import hexlify
from struct import unpack

def parse_tmd(tmd):
    # Title ID
    tmd.seek(0x18C)
    titleid = tmd.read(8)
    print("Title ID: " + hexlify(titleid).decode())

    # Title Version
    tmd.seek(0x1DC)
    tmd_title_version = unpack('>H', tmd.read(2))[0]
    print("Title version: " + str(tmd_title_version))

    # Number of Contents
    tmd.seek(0x1DE)
    count = unpack(">H", tmd.read(2))[0]
    print("Content count: " + str(count))

    # Contents
    tmd.seek(0x1E4)
    # Loop over every content
    info = []
    for i in range(count):
        # This will extract content id, index, type, size and SHA1 hash and store them in a list
        # https://docs.python.org/3/library/struct.html#format-characters ("IHHQ": 4, 2, 2, 8)
        data = [a for a in unpack(">IHHQ", tmd.read(16))]
        data.append(hexlify(tmd.read(20)))
        info.append(data)

        print("%08X" % data[0] + ": " + str(data[3]) + " bytes")
    return info  # List with every content

Gibt für das IOS58 auf der Konsole aus:

Title ID: 000000010000003A
Title version: 6176
Content count: 19
00000018: 64 bytes
...

Gibt die info-Liste zurück:

[24, 0, 1, 64, b'bcd51d83d9479e44c622c92ebf49bb2c6529d695']
...

wobei 24 im Hexadezimalsystem = 18, durch "%08X" % 24 werden Nullen vorangestellt (das X bedeutet Hexadezimal, vgl. StackOverflow).