Skip to content

Instantly share code, notes, and snippets.

@alexander-hanel
Last active October 29, 2023 22:45
Show Gist options
  • Save alexander-hanel/12ad5ea77a754ff9a31d6a53476c8920 to your computer and use it in GitHub Desktop.
Save alexander-hanel/12ad5ea77a754ff9a31d6a53476c8920 to your computer and use it in GitHub Desktop.
parse PUBLICKEYSTRUCT and RSAPUBKEY
import struct
import sys
class BLOBHEADER:
def __init__(self, data):
self.bType = None # BYTE
self.bVersion = None # BYTE
self.reserved = None # WORD
self.aiKeyAlg = None # ALG_ID
self._parse_data(data)
def get_values(self):
return {"bType": self.bType, "bVersion": self.bVersion, "reserved": self.reserved, "aiKeyAlg": self.aiKeyAlg}
def _parse_data(self, data):
cur_addr = 0
# Contains the key BLOB type.
temp_data = data[cur_addr: cur_addr + 1]
self.bType = self._get_btype(struct.unpack("<B", temp_data)[0])
cur_addr += 1
# Contains the version number of the key BLOB format.
temp_data = data[cur_addr: cur_addr + 1]
self.bVersion = struct.unpack("<B", temp_data)[0]
cur_addr += 1
# This member is reserved for future use and must be set to zero.
temp_data = data[cur_addr: cur_addr + 2]
self.reserved = struct.unpack("<H", temp_data)[0]
cur_addr += 2
# Contains one of the ALG_ID values that identifies the algorithm of the key contained by the key BLOB.
temp_data = data[cur_addr: cur_addr + 4]
self.aiKeyAlg = self._get_alg(struct.unpack("<i", temp_data)[0])
cur_addr += 4
def _get_btype(self, btype):
options = {
0xC: "KEYSTATEBLOB",
0x9: "OPAQUEKEYBLOB",
0x8: "PLAINTEXTKEYBLOB",
0x7: "PRIVATEKEYBLOB",
0x6: "PUBLICKEYBLOB",
0xA: "PUBLICKEYBLOBEX",
0x1: "SIMPLEBLOB",
0xB: "SYMMETRICWRAPKEYBLOB"
}
if btype in options:
return options[btype]
return False
def _get_alg(self, alg):
options = {
0x00006603: "CALG_3DES",
0x00006609: "CALG_3DES_112",
0x00006611: "CALG_AES",
0x0000660e: "CALG_AES_128",
0x0000660f: "CALG_AES_192",
0x00006610: "CALG_AES_256",
0x0000aa03: "CALG_AGREEDKEY_ANY",
0x0000660c: "CALG_CYLINK_MEK",
0x00006601: "CALG_DES",
0x00006604: "CALG_DESX",
0x0000aa02: "CALG_DH_EPHEM",
0x0000aa01: "CALG_DH_SF",
0x00002200: "CALG_DSS_SIGN",
0x0000aa05: "CALG_ECDH",
0x0000ae06: "CALG_ECDH_EPHEM",
0x00002203: "CALG_ECDSA",
0x0000a001: "CALG_ECMQV",
0x0000800b: "CALG_HASH_REPLACE_OWF",
0x0000a003: "CALG_HUGHES_MD5",
0x00008009: "CALG_HMAC",
0x0000aa04: "CALG_KEA_KEYX",
0x00008005: "CALG_MAC",
0x00008001: "CALG_MD2",
0x00008002: "CALG_MD4",
0x00008003: "CALG_MD5",
0x00002000: "CALG_NO_SIGN",
0xffffffff: "CALG_OID_INFO_CNG_ONLY",
0xfffffffe: "CALG_OID_INFO_PARAMETERS",
0x00004c04: "CALG_PCT1_MASTER",
0x00006602: "CALG_RC2",
0x00006801: "CALG_RC4",
0x0000660d: "CALG_RC5",
0x0000a400: "CALG_RSA_KEYX",
0x00002400: "CALG_RSA_SIGN",
0x00004c07: "CALG_SCHANNEL_ENC_KEY",
0x00004c03: "CALG_SCHANNEL_MAC_KEY",
0x00004c02: "CALG_SCHANNEL_MASTER_HASH",
0x00006802: "CALG_SEAL",
0x00008004: "CALG_SHA",
0x00008004: "CALG_SHA1",
0x0000800c: "CALG_SHA_256",
0x0000800d: "CALG_SHA_384",
0x0000800e: "CALG_SHA_512",
0x0000660a: "CALG_SKIPJACK",
0x00004c05: "CALG_SSL2_MASTER",
0x00004c01: "CALG_SSL3_MASTER",
0x00008008: "CALG_SSL3_SHAMD5",
0x0000660b: "CALG_TEK",
0x00004c06: "CALG_TLS1_MASTER",
0x0000800a: "CALG_TLS1PRF"
}
if alg in options:
return options[alg]
return False
class RSAPUBKEY:
def __init__(self, data):
self.magic = None # DWORD
self.bitlen = None # DWORD
self.pubexp = None # DWORD
self.modulus = None # size of bitlen
self._parse_data(data)
def get_values(self):
return {"magic": self.magic, "bitlen": self.bitlen,"pubexp":self.pubexp, "modulus": self.modulus}
def _parse_data(self, data):
cur_addr = 0
# Struct unpacking code. Initiate cur_addr
temp_data = data[cur_addr: cur_addr + 4]
self.magic = struct.unpack("<I", temp_data)[0]
cur_addr += 4
temp_data = data[cur_addr: cur_addr + 4]
self.bitlen = struct.unpack("<I", temp_data)[0]
cur_addr += 4
temp_data = data[cur_addr: cur_addr + 4]
self.pubexp = struct.unpack("<I", temp_data)[0]
cur_addr += 4
temp = data[cur_addr: cur_addr + self.bitlen]
self.modulus = int(temp.encode("hex"), 16)
data = open(sys.argv[1], "rb").read()
b = BLOBHEADER(data)
print b.get_values()
r = RSAPUBKEY(data[8:])
print r.get_values()
@dzervas
Copy link

dzervas commented Oct 29, 2023

Just wanted to say thank you, worked and helped a lot

Side notes for python3: replace the print with regular function calls (print()) and line 131 with self.modulus = temp.hex()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment