Sealedkey / pfsSKKey: Difference between revisions
Jump to navigation
Jump to search
Cfwprophet (talk | contribs) (Undo revision 276284 by Red-EyeX32 (talk)) |
mNo edit summary |
||
(27 intermediate revisions by 8 users not shown) | |||
Line 1: | Line 1: | ||
This key can be found on different places and will be used for eg. | This key can be found on different places and will be used for eg. Save Data or Trophy Data decryption and encryption. | ||
==== | |||
==== Flags ==== | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Kind !! Path | ! Kind !! Path | ||
|- | |- | ||
| | | Trophy || /user/home/[[User ID|user Id]]/trophy/data/[[sce_trop]]/sealedkey | ||
|- | |- | ||
| | | Save Data || /user/home/[[User ID|user Id]]/[[NP Title ID|title Id]]/[[save data directory]]/[[sce_sys]]/ | ||
|} | |} | ||
== Structure == | == Structure == | ||
- size always 96 bytes | |||
- size is always 96 bytes | |||
{| class="wikitable" | {| class="wikitable" | ||
Line 17: | Line 20: | ||
! From !! To !! Description | ! From !! To !! Description | ||
|- | |- | ||
| 00 || 07 || | | 00 || 07 || MAGIC ("pfsSKKey") (?playstation file system sealed key key?) | ||
|- | |||
| 08 || 09 || KeySet for getSealedKeySecret (changed beyond kernel 1.73) | |||
|- | |- | ||
| | | 0A || 0F || Just 0x00 Bytes | ||
|- | |- | ||
| 10 || 1F || IV (16 bytes) | | 10 || 1F || IV (16 bytes) | ||
|- | |- | ||
| 20 || 3F || | | 20 || 3F || Encrypted key (32 bytes) | ||
|- | |- | ||
| 40 || 5F || SHA-256 (32 bytes) | | 40 || 5F || SHA-256 (32 bytes) | ||
Line 30: | Line 35: | ||
'''C''' | '''C''' | ||
<source lang="c"> | <source lang="c"> | ||
typedef struct | typedef struct sealedkey_t { | ||
const unsigned char MAGIC; | const unsigned char MAGIC[8]; | ||
const unsigned char | const unsigned char KEYSET[2]; // short | ||
const unsigned char IV; | const unsigned char ALIGN0Bytes[6]; | ||
const unsigned char KEY; | const unsigned char IV[16]; | ||
const unsigned char SHA256; | const unsigned char KEY[32]; | ||
} | const unsigned char SHA256[32]; | ||
} PfsSKKey; | |||
</source> | </source> | ||
Line 43: | Line 49: | ||
protected internal struct sealedkey { | protected internal struct sealedkey { | ||
internal static byte[] MAGIC = new byte[8]; | internal static byte[] MAGIC = new byte[8]; | ||
internal static byte[] | internal static short KeySet; | ||
internal static byte[] AlignBytes = new byte[6]; | |||
internal static byte[] IV = new byte[16]; | internal static byte[] IV = new byte[16]; | ||
internal static byte[] KEY = new byte[32]; | internal static byte[] KEY = new byte[32]; | ||
Line 50: | Line 57: | ||
</source> | </source> | ||
Note: You | Note: You cannot use a const byte[] definition in C#. It needs to be a static byte[]. | ||
== De/En -Crypting == | == De/En -Crypting == | ||
Can be decrypted by | |||
Can be decrypted by friendly asking the OS to do it for you. You will need kernel rights to be able to ask the PS4 for it. | |||
<source lang="c"> | <source lang="c"> | ||
/* Decryption */ | /* Decryption */ | ||
#define | #define foreach(item, array) \ | ||
for (int keep = 1, \ | |||
count = 0, \ | |||
size = sizeof(array) / sizeof*(array); \ | |||
keep && count != size; \ | |||
keep = !keep, count++) \ | |||
for (item = (array) + count; keep; keep = !keep) | |||
typedef unsigned char byte; /* byte defination for c/c++ */ | typedef unsigned char byte; /* byte defination for c/c++ */ | ||
byte PFSK_IDENT[8] = "pfsSKKey"; | |||
byte VERSION[8] = "\x01\x00\x00\x00\x00\x00\x00\x00" | |||
const char USER1 = "10000000"; | |||
const char usb0 = "/mnt/usb0/"; | |||
const char usb1 = "/mnt/usb1/"; | |||
const char pfs = "dec_pfsSK.Key"; | |||
const char home = "/user/home/"; | |||
const char tropkey = "/trophy/data/sce_trop/sealedkey"; | |||
char usb_error = "[-] ERROR: Can't access usb0 nor usb1!\n[-] Will return now to caller.\n" | char usb_error = "[-] ERROR: Can't access usb0 nor usb1!\n[-] Will return now to caller.\n" | ||
char usb0path | char usb0path[(strlen(usb0) + strlen(pfs))]; | ||
char usb1path[strlen(usb0path)]; | |||
/* Get's the encrypted sealed key based on user id */ | /* Get's the encrypted sealed key based on user id */ | ||
int get_pfsSKKey(byte *buffer, const char *userID, char path) { | |||
FILE *pfskey = fopen( | char toOpen[(strlen(home) + strlen(userID) + strlen(path))]; | ||
if (pfskey | |||
sprintf(toOpen, home, userID, path) | |||
FILE *pfskey = fopen(toOpen, "r"); | |||
if (!pfskey) return NULL; | |||
fread(buffer, 96, 1, pfskey); | |||
fread( | |||
fclose(pfskey); | fclose(pfskey); | ||
return | return 1; | ||
} | } | ||
/* Dump the sealedkey. Send over tcp and save to file */ | /* Dump the sealedkey. Send over tcp and save to file */ | ||
int dumpDecryptedSealedKey(int to) { | int dumpDecryptedSealedKey(int to) { | ||
if (to | if (to < 0 || to > 1) return -2; | ||
/* First load the sealedkey into a buffer */ | |||
if ( | PfsSKKEy enc; | ||
if (!get_pfsSKKey(&enc, USER1, tropkey)) { | |||
printf("[-] Can not load the sealed key!\n"); | |||
return -1; | return -1; | ||
} | } | ||
/* Now | /* Let's check the pfsSKKEy */ | ||
byte | if (enc->MAGIC == PFSK_IDENT && enc->CAT == VERSION) { | ||
int i = kernel.sceSblSsDecryptSealedKey( | printf("[+] Magic and version ok!\n[+] sk IV = "); | ||
foreach(byte *val, &enc->IV) printf("%02X", *val); | |||
printf("\n[+] sk KEY = "); | |||
foreach(byte *val, enc->KEY) printf("%02X", *val); | |||
printf("\n[+] sk Key-SHA256 = "); | |||
foreach(byte *val, sk->SHA256) printf("%02X", *val); | |||
printf("\n"); | |||
} | |||
else return -4; | |||
/* Now decrypt it */ | |||
byte dec[16]; | |||
int i; | |||
if (!(i = kernel.sceSblSsDecryptSealedKey(&enc, &dec))) { | |||
printf("[-] Error!\n[-] sceSblSsDecryptSealedKey returned %d\n", i); | |||
return -1; | |||
} | |||
printf("[+] sceSblSsDecryptSealedKey returned %d\n", i); | |||
/* | if (!to) { /* Print it out */ | ||
printf("[+] Your decrypted sealedkey = "); | |||
foreach(byte *val, &dec) printf("%02X", *val); | |||
} /* Saving to file */ | printf("\n"); | ||
return 1; | |||
} | |||
else { /* Saving to file */ | |||
printf("[+] Will try to save to file..."); | |||
sprintf(usb0path, usb0, pfs); | |||
sprintf(usb1path, usb1, pfs); | |||
FILE *dump = fopen(usb0path, "w"); | |||
if (!dump) { | |||
dump = fopen(usb1path, "w"); | |||
if (!dump) { | |||
printf("fail!\n%s", usb_error); | |||
return -3; | |||
} | } | ||
} | } | ||
fwrite(&dec, 16, 1, dump); | |||
printf("done!\n"); | |||
fclose(dump); | |||
return 1; | |||
} | } | ||
} | } | ||
</source> | </source> | ||
{{File Formats}} | |||
<noinclude>[[Category:Main]]</noinclude> |
Latest revision as of 21:56, 24 May 2024
This key can be found on different places and will be used for eg. Save Data or Trophy Data decryption and encryption.
Flags[edit | edit source]
Kind | Path |
---|---|
Trophy | /user/home/user Id/trophy/data/sce_trop/sealedkey |
Save Data | /user/home/user Id/title Id/save data directory/sce_sys/ |
Structure[edit | edit source]
- size is always 96 bytes
From | To | Description |
---|---|---|
00 | 07 | MAGIC ("pfsSKKey") (?playstation file system sealed key key?) |
08 | 09 | KeySet for getSealedKeySecret (changed beyond kernel 1.73) |
0A | 0F | Just 0x00 Bytes |
10 | 1F | IV (16 bytes) |
20 | 3F | Encrypted key (32 bytes) |
40 | 5F | SHA-256 (32 bytes) |
C
typedef struct sealedkey_t {
const unsigned char MAGIC[8];
const unsigned char KEYSET[2]; // short
const unsigned char ALIGN0Bytes[6];
const unsigned char IV[16];
const unsigned char KEY[32];
const unsigned char SHA256[32];
} PfsSKKey;
CSharp
protected internal struct sealedkey {
internal static byte[] MAGIC = new byte[8];
internal static short KeySet;
internal static byte[] AlignBytes = new byte[6];
internal static byte[] IV = new byte[16];
internal static byte[] KEY = new byte[32];
internal static byte[] SHA256 = new byte[32];
}
Note: You cannot use a const byte[] definition in C#. It needs to be a static byte[].
De/En -Crypting[edit | edit source]
Can be decrypted by friendly asking the OS to do it for you. You will need kernel rights to be able to ask the PS4 for it.
/* Decryption */
#define foreach(item, array) \
for (int keep = 1, \
count = 0, \
size = sizeof(array) / sizeof*(array); \
keep && count != size; \
keep = !keep, count++) \
for (item = (array) + count; keep; keep = !keep)
typedef unsigned char byte; /* byte defination for c/c++ */
byte PFSK_IDENT[8] = "pfsSKKey";
byte VERSION[8] = "\x01\x00\x00\x00\x00\x00\x00\x00"
const char USER1 = "10000000";
const char usb0 = "/mnt/usb0/";
const char usb1 = "/mnt/usb1/";
const char pfs = "dec_pfsSK.Key";
const char home = "/user/home/";
const char tropkey = "/trophy/data/sce_trop/sealedkey";
char usb_error = "[-] ERROR: Can't access usb0 nor usb1!\n[-] Will return now to caller.\n"
char usb0path[(strlen(usb0) + strlen(pfs))];
char usb1path[strlen(usb0path)];
/* Get's the encrypted sealed key based on user id */
int get_pfsSKKey(byte *buffer, const char *userID, char path) {
char toOpen[(strlen(home) + strlen(userID) + strlen(path))];
sprintf(toOpen, home, userID, path)
FILE *pfskey = fopen(toOpen, "r");
if (!pfskey) return NULL;
fread(buffer, 96, 1, pfskey);
fclose(pfskey);
return 1;
}
/* Dump the sealedkey. Send over tcp and save to file */
int dumpDecryptedSealedKey(int to) {
if (to < 0 || to > 1) return -2;
/* First load the sealedkey into a buffer */
PfsSKKEy enc;
if (!get_pfsSKKey(&enc, USER1, tropkey)) {
printf("[-] Can not load the sealed key!\n");
return -1;
}
/* Let's check the pfsSKKEy */
if (enc->MAGIC == PFSK_IDENT && enc->CAT == VERSION) {
printf("[+] Magic and version ok!\n[+] sk IV = ");
foreach(byte *val, &enc->IV) printf("%02X", *val);
printf("\n[+] sk KEY = ");
foreach(byte *val, enc->KEY) printf("%02X", *val);
printf("\n[+] sk Key-SHA256 = ");
foreach(byte *val, sk->SHA256) printf("%02X", *val);
printf("\n");
}
else return -4;
/* Now decrypt it */
byte dec[16];
int i;
if (!(i = kernel.sceSblSsDecryptSealedKey(&enc, &dec))) {
printf("[-] Error!\n[-] sceSblSsDecryptSealedKey returned %d\n", i);
return -1;
}
printf("[+] sceSblSsDecryptSealedKey returned %d\n", i);
if (!to) { /* Print it out */
printf("[+] Your decrypted sealedkey = ");
foreach(byte *val, &dec) printf("%02X", *val);
printf("\n");
return 1;
}
else { /* Saving to file */
printf("[+] Will try to save to file...");
sprintf(usb0path, usb0, pfs);
sprintf(usb1path, usb1, pfs);
FILE *dump = fopen(usb0path, "w");
if (!dump) {
dump = fopen(usb1path, "w");
if (!dump) {
printf("fail!\n%s", usb_error);
return -3;
}
}
fwrite(&dec, 16, 1, dump);
printf("done!\n");
fclose(dump);
return 1;
}
}