Introduction
The Raw Product Key is buried inside the Product Key that is printed on the sticker distributed with each Windows XP CD. It consists of five alphanumeric strings separated by '-' characters, where each string is composed of five characters, as in:
FFFFF-GGGGG-HHHHH-JJJJJ-KKKKK
Each character is one of the following 24 letters and digits:
B C D F G H J K M P Q R T V W X Y 2 3 4 6 7 8 9
Very similar to the decimal encoding of the Installation ID, the 25 characters of the Product Key form a base-24 encoding of the binary representation of the Product Key. Decoding the Product Key yields a multi-precision integer of roughly 115 bits, which is stored - again in Little Endian byte order - in an array of 15 bytes. Decoding the above Product Key results in the following byte sequence:
0x6F 0xFA 0x95 0x45 0xFC 0x75 0xB5 0x52
0xBB 0xEF 0xB1 0x17 0xDA 0xCD 0x00
Of these 15 bytes, the least significant four bytes contain the Raw Product Key in Little Endian byte order. The least significant bit is removed by shifting this 32-bit value (0x4595FA6F - remember the Little Endian byte order) to the left by one bit position, resulting in a Raw Product Key of 0x22CAFD37, or 583728439 in decimal notation.
Using the code
Using this code, you can find the product key of your Microsoft products.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
namespace MSKeyFinder
{
public class KeyDecoder
{
public enum Key { XP, Office10, Office11 };
public static byte[] GetRegistryDigitalProductId(Key key)
{
byte[] digitalProductId = null;
RegistryKey registry = null;
switch (key)
{
case Key.XP:
registry =
Registry.LocalMachine.
OpenSubKey(
@"SOFTWARE\Microsoft\Windows NT\CurrentVersion",
false);
break;
case Key.Office10:
registry =
Registry.LocalMachine.
OpenSubKey(
@"SOFTWARE\Microsoft\Office\10.0\Registration\" +
@"{90280409-6000-11D3-8CFE-0050048383C9}",
false);
break;
case Key.Office11:
break;
}
if (registry != null)
{
digitalProductId = registry.GetValue("DigitalProductId")
as byte[];
registry.Close();
}
return digitalProductId;
}
public static string DecodeProductKey(byte[] digitalProductId)
{
const int keyStartIndex = 52;
const int keyEndIndex = keyStartIndex + 15;
char[] digits = new char[]
{
'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'M', 'P', 'Q', 'R',
'T', 'V', 'W', 'X', 'Y', '2', '3', '4', '6', '7', '8', '9',
};
const int decodeLength = 29;
const int decodeStringLength = 15;
char[] decodedChars = new char[decodeLength];
ArrayList hexPid = new ArrayList();
for (int i = keyStartIndex; i <= keyEndIndex; i++)
{
hexPid.Add(digitalProductId[i]);
}
for (int i = decodeLength - 1; i >= 0; i--)
{
if ((i + 1) % 6 == 0)
{
decodedChars[i] = '-';
}
else
{
int digitMapIndex = 0;
for (int j = decodeStringLength - 1; j >= 0; j--)
{
int byteValue = (digitMapIndex << 8) | (byte)hexPid[j];
hexPid[j] = (byte)(byteValue / 24);
digitMapIndex = byteValue % 24;
decodedChars[i] = digits[digitMapIndex];
}
}
}
return new string(decodedChars);
}
}
}
Once you realize how the product keys are encoded, a search through the Registry for the values starting with DigitalProductId
indicates that many more product keys may be encoded this way.
Further information
To know more about Microsoft product keys, visit: