Sealedkey / pfsSKKey
Jump to navigation
Jump to search
This key can be found on different places and will be used for eg. Save Data or Trophy Data decryption and encryption.
Flags
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
- 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
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;
}
}