Recuperar / descifrar la clave de producto de Windows 7 de Linux

19

Accidentalmente desconecté mi disco duro mientras aún se estaba ejecutando y corrompió mi instalación de Windows 7; Ahora soy completamente incapaz de iniciar Windows. He intentado todo para intentar reparar la instalación: Reparación de inicio de Windows, chkdsk / r, SFC / scannow, bootrec / rebuildbcd, etc. y no tuve suerte. Solo quiero realizar una instalación nueva, pero mi problema es que no tengo mi clave de producto de Windows escrita en ningún lado, y no puedo usar ningún script o utilidades para recuperarla del registro porque no puedo iniciar Windows.

Las claves de producto de Windows 7 se almacenan, encriptadas, en el valor "DigitalProductId" de la clave de registro HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion. Pude montar la partición corrupta de Windows de solo lectura desde un CD en vivo de Ubuntu y copiar la sección del registro Windows \ System32 \ config \ SOFTWARE, que contiene la clave y el valor en cuestión, en una unidad flash, pero cargando esta sección en regedit en una instalación de Windows que funcione y luego intente usar scripts o utilidades para descifrar el valor "DigitalProductId" cargado, solo devuelve la clave del producto de la instalación de Windows del host, sin importar cuánto intento. Intenté contactar al soporte de Microsoft y no me han ayudado. ¿Alguien podría guiarme más? ¿Quizás si hay una forma diferente de recuperar la clave de producto de Linux?

Si alguien más familiarizado con las secuencias de comandos / criptografía estaría dispuesto a intentar y seguir la secuencia de comandos de descifrado para descifrar la clave del producto a mano, podría enviarle un correo electrónico con el valor exportado "DigitalProductId", la sección de registro SOFTWARE y la secuencia de comandos de descifrado.

sundiata
fuente
Esto no suena bien. Si compró una licencia, debe tener la clave. Ahora, por otro lado, si tiene en sus manos la imagen de otra persona y desea extraer su clave, ese no es realmente el punto de este sitio.
JasonXA
Compré una licencia. Tengo el DVD de instalación pero no puedo encontrar la clave de producto que vino con él. Pero creo que he encontrado una solución aquí: dagondesign.com/articles/windows-xp-product-key-recovery/…
sundiata
Sí, eso parece funcionar. Usando el método logré reproducir mi clave.
JasonXA
Si su firmware está basado en UEFI, la clave de licencia se almacena realmente en la tabla ACPI MSDM, por lo que persiste durante un reinicio. Si es así, visite blog.fpmurphy.com para obtener detalles sobre cómo recuperarlo.
fpmurphy

Respuestas:

30

Hay una gran herramienta disponible para Linux llamada chntpw. Puede obtenerlo fácilmente en Debian / Ubuntu a través de:

sudo apt install chntpw

Para buscar en el archivo de registro relevante, monte el disco de Windows y ábralo así:

chntpw -e /path/to/windisk/Windows/System32/config/software

Ahora para obtener la decodificación, DigitalProductIdingrese este comando:

dpi \Microsoft\Windows NT\CurrentVersion\DigitalProductId
Thomas
fuente
55
La ruta al archivo de registro relevante está en / path / to / windisk / Windows / System32 / config / RegBack / SOFTWARE
Mohamed EL HABIB
2
Esta es una gran respuesta, la cité
Mark Kirby
Gracias por esto. Tome nota para verificar el caso de la carpeta y los nombres de los archivos. En mi caso, tuve que usar mayúsculas SOFTWAREpara el nombre del archivo.
Paddy Landau
Si tiene problemas para leer la carpeta system32, intente hacer una copia y proporcione la ruta de la copia al chntpw.
Markus von Broady
2

Para aquellos que no son tímidos para hacer un poco de codificación.

Encontré un algoritmo hace unos 10 años y lo implementé en C # (ver más abajo)


Si solo quieres ejecutarlo en Windows

Me tomé la libertad de convertirlo en un script de PowerShell:

$dpid = Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name "DigitalProductId"

# Get the range we are interested in
$id = $dpid.DigitalProductId[52..(52+14)]

# Character table
$chars = "BCDFGHJKMPQRTVWXY2346789"

# Variable for the final product key
$pkey = ""

# Calculate the product key
for ($i=0; $i -le 24; $i++) {
    $c = 0

    for($j=14; $j -ge 0; $j--) {
        $c = ($c -shl 8) -bxor $id[$j]

        $id[$j] = [Math]::Floor($c / 24) -band 255

        $c = $c % 24
    }
    $pkey = $chars[$c] + $pkey
}
# Insert some dashes
for($i = 4; $i -gt 0; $i--) {
    $pkey = $pkey.Insert($i * 5, "-")
}
$pkey

Ejecute esto y obtendrá su clave de producto. (Así que no hay codificación para ti después de todo)


Publicación original

Así que este es el código C # real que desenterré y comenté.

public static string ConvertDigitalProductID(string regPath, string searchKey = "DigitalProductID") {
    // Open the sub key i.E.: "Software\Microsoft\Windows NT\CurrentVersion"
    var regkey = Registry.LocalMachine.OpenSubKey(regPath, false);
    // Retreive the value of "DigitalProductId"
    var dpid = (byte[])regkey.GetValue(searchKey);
    // Prepare an array for the relevant parts
    var idpart = new byte[15];

    // Copy the relevant parts of the array
    Array.Copy(dpid, 52, idpart, 0, 15);

    // Prepare the chars that will make up the key
    var charStore = "BCDFGHJKMPQRTVWXY2346789";

    // Prepare a string for the result
    string productkey = "";

    // We need 24 iterations (one for each character)
    for(int i = 0; i < 25; i++) {

        int c = 0;
        // Go through each of the 15 bytes of our dpid
        for(int j = 14; j >= 0; j--) {
            // Shift the current byte to the left and xor in the next byte
            c = (c << 8) ^ idpart[j];

            // Leave the result of the division in the current position
            idpart[j] = (byte)(c / 24);

            // Take the rest of the division forward to the next round
            c %= 24;
        }
        // After each round, add a character from the charStore to our key
        productkey = charStore[c] + productkey;
    }

    // Insert the dashes
    for(int i = 4; i > 0; i--) {
        productkey = productkey.Insert(i * 5, "-");
    }

    return productkey;
}

Tendrás que pasarlo Software\Microsoft\Windows NT\CurrentVersioncomo una clave, donde encontrará elDigitalProductId

En ese momento, MS Office Products usaba el mismo algoritmo, por lo que al proporcionar la función con la clave de registro relevante, también podía calcular esas claves de producto.

Por supuesto, puede refactorizar la función para que tome una matriz de bytes como entrada.

En cuanto a hoy. Lo acabo de probar en mi máquina con Windows 10 y todavía funciona.

MrPaulch
fuente
Esta es una buena respuesta, pero la pregunta es muy antigua y es posible que no reciba muchas opiniones. Como miembro, considere agregar su respuesta a nuestra publicación actual de Ask Ubuntu askubuntu.com/questions/953126/…
Mark Kirby
Gracias. Pero creo que estaría fuera de tema allí. Puedo juntar una implementación de pseudocódigo. Y refiérase a esta publicación como una implementación real.
MrPaulch
No hay problema, haz lo que creas que es mejor
Mark Kirby
2

Aquí hay un puerto Python de la otra respuesta (adaptado para Windows 8.1). La ventaja de esto chntpwes que funcionará incluso con unidades en estado de solo lectura.

Requisitos:

pip install python-registry

Código:

#!/usr/bin/env python
import sys
from Registry import Registry
reg = Registry.Registry("/path/to/drive/Windows/System32/config/RegBack/SOFTWARE")
# Uncomment for registry location for Windows 7 and below:
#reg = Registry.Registry("/path/to/drive/Windows/system32/config/software")
key = reg.open("Microsoft\Windows NT\CurrentVersion")
did = bytearray([v.value() for v in key.values() if v.name() == "DigitalProductId"][0])
idpart = did[52:52+15]
charStore = "BCDFGHJKMPQRTVWXY2346789";
productkey = "";
for i in range(25):
  c = 0
  for j in range(14, -1, -1):
    c = (c << 8) ^ idpart[j]
    idpart[j] = c // 24
    c %= 24
  productkey = charStore[c] + productkey
print('-'.join([productkey[i * 5:i * 5 + 5] for i in range(5)]))
Lenar Hoyt
fuente
El bucle interno era una iteración demasiado corta. Debería funcionar ahora.
Lenar Hoyt
0

Aquí está mi implementación bash. Lo llamo get_windows_key.sh funciona bien desde clonezilla. Originalmente lo publiqué aquí https://sourceforge.net/p/clonezilla/discussion/Open_discussion/thread/979f335385/

#!/bin/bash
# written by Jeff Sadowski
# credit
###################################################
# Pavel Hruška, Scott Skahht, and Philip M for writting
# https://github.com/mrpeardotnet/WinProdKeyFinder/blob/master/WinProdKeyFind/KeyDecoder.cs
# that I got my conversion code from
#
# I used the comments on the sudo code from
# /ubuntu/953126/can-i-recover-my-windows-product-key- from-ubuntu
# by MrPaulch
#
# and the creator of chntpw
#
# Petter Nordahl-Hagen
# without which I would not be able to get the key in linux
#
# also the creators of ntfs-3g, linux and bash

parted -l 2>/dev/null |grep -e ntfs -e fat -e Disk|grep -v Flags
#get the first mac address that isn't a loopback address
# loopback will have all zeros
MAC=$(cat /sys/class/net/*/address|grep -v 00:00:00:00:00:00|head -n 1|sed "s/:/-/g")
if [ "$1" = "" ];then
 echo "mount the Windows share then give this script the path where you mounted it"
 exit
fi
cd $1
#
# This way will work no matter what the capitalization is
next=$(find ./ -maxdepth 1 -iname windows);cd ${next}
next=$(find ./ -maxdepth 1 -iname system32);cd ${next}
next=$(find ./ -maxdepth 1 -iname config);cd ${next}
file=$(find ./ -maxdepth 1 -iname software)
#echo $(pwd)${file:1}
#Get the necissary keys
#get the version key
VERSION=$((16#$(echo -e "cat \\Microsoft\\Windows NT\\CurrentVersion\\CurrentMajorVersionNumber\nq\n" | chntpw -e ${file}|grep "^0x"|cut -dx -f2)))
hexPid_csv_full=$(echo $(echo -e "hex \\Microsoft\\Windows NT\\CurrentVersion\\DigitalProductId\nq\n" | chntpw -e ${file}|grep "^:"|cut -b 9-55)|sed 's/ /,/g' | tr '[:u>
# get the subset 53 to 68 of the registry entry
hexPid_csv=$(echo $(echo -e "hex \\Microsoft\\Windows NT\\CurrentVersion\\DigitalProductId\nq\n" | chntpw -e ${file}|grep "^:"|cut -b 9-55)|sed 's/ /,/g' | tr '[:upper:>
echo "${hexPid_csv_full}" > /custom/DigitalProductId_${MAC}.txt
#formatted output
spread()
{
 key=$1
 echo ${key:0:5}-${key:5:5}-${key:10:5}-${key:15:5}-${key:20:5}
}
# almost a direct conversion of c# code from
# https://github.com/mrpeardotnet/WinProdKeyFinder/blob/master/WinProdKeyFind/KeyDecoder.cs
# however most of this looks similar to sudo code I found
# /ubuntu/953126/can-i-recover-my-windows-product-key-from-ubuntu
DecodeProductKey()
{
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)
for j in {0..15};do
#Populate the Pid array from the values found in the registry
 Pid[$j]=$((16#$(echo ${hexPid_csv}|cut -d, -f $(($j+1)))))
done
if [ "$1" = "8+" ];then
# modifications needed for getting the windows 8+ key
 isWin8=$(($((${Pid[14]}/6))&1))
 Pid[14]=$(( $(( ${Pid[14]}&247 )) | $(( $(( ${isWin8} & 2 )) * 4 )) ))
fi
key=""
last=0
for i in {24..0};do
 current=0
 for j in {14..0};do
  # Shift the current contents of c to the left by 1 byte 
  # and add it with the next byte of our id
  current=$((${current}*256))
  current=$((${Pid[$j]} + current))
  # Put the result of the divison back into the array
  Pid[$j]=$((${current}/24))
  # Calculate remainder of c
  current=$((${current}%24))
  last=${current}
 done
 # Take character at position c and prepend it to the ProductKey
 key="${digits[${current}]}${key}"
done
if [ "$1" = "8+" ];then
# another modification needed for a windows 8+ key
 key="${key:1:${last}}N${key:$((${last}+1)):24}"
 echo -n "Windows 8+ key: "
else
 echo -n "Windows 7- key: "
fi
spread "${key}"
}
if [ "$VERSION" -gt "7" ];then
 DecodeProductKey 8+
else
 DecodeProductKey
fi
penguinjeff
fuente