Line 98:
Line 98:
Obviously this section is not present in TWL CIA files.
Obviously this section is not present in TWL CIA files.
+
+
+
== Title Key Encryption ==
+
+
The unencrypted Title Key is used to encrypt the data in a CIA. The encrypted Title Key of a CIA can be found at offset 0x1BF in a CIA's Ticket.
+
Each Title Key is encrypted with AES-CBC.
+
+
To encrypt an unencrypted title key, you need:
+
+
* Common key (as byte array)
+
* Title ID (as ulong)
+
* (and of course the unencrypted title key you want to encrypt) (as byte array)
+
+
The title ID encryption process starts by converting the ulong (Title ID) into a byte array using by retrieving the bytes of the Title ID using BitConverter.GetBytes().
+
If the converted bytes (title ID) are in Little Endian, reverse those bytes. (in C# it would be Array.Reverse(byte_array_from_bitconverter))
+
This process makes the Title Key encryption IV.
+
+
Next, after you've gotten your Title Key's IV, you can start your cryptography transformation. Using AESManaged, where:
+
+
Key = Common Key
+
+
IV = the byte array found in the conversion process above
+
+
Mode = CipherMode.CBC
+
+
Create the encryptor (AesManaged.CreateEncryptor(key, iv)) where the key and IV are both the same as above.
+
+
Then, create a CryptoStream and a MemoryStream. The Crypto stream should start with the arguments (memorystream, aes_transform_from_above, CryptoStreamMode.Write).
+
+
Write to the CryptoStream where buffer=unencrypted_titlekey, offset=0, and count=the length of the unencrypted title key.
+
+
Use FlushFinalBlock() on the CryptoStream.
+
+
Finally, then, the encrypted title key will be available from your memory
+
stream. (to output the calculated encrypted title key as a byte array, you can use memorystream.ToArray(), for example)
+
+
Example function: (C#)
+
+
<pre>
+
public static byte[] EncryptMyTitleKey(byte[] commonKey, byte[] titleKey, ulong titleId)
+
{
+
byte[] titleidasbytes = new byte[0x10];
+
for (int i = 0; i < 0x10; i++)
+
{
+
titleidasbytes[i] = 0;
+
}
+
byte[] bitBytes = BitConverter.GetBytes(titleId);
+
if (BitConverter.IsLittleEndian)
+
{
+
Array.Reverse(bitBytes);
+
}
+
bitBytes.CopyTo(titleidasbytes, 0);
+
ICryptoTransform transform = new AesManaged { Key = commonKey, IV = titleidasbytes, Mode = CipherMode.CBC }.CreateEncryptor(commonKey, titleidasbytes);
+
MemoryStream memstream = new MemoryStream();
+
CryptoStream cryptostream = new CryptoStream(memstream, transform, CryptoStreamMode.Write);
+
cryptostream.Write(titleKey, 0, titleKey.Length);
+
cryptostream.FlushFinalBlock();
+
return memstream.ToArray();
+
}
+
</pre>