Récupérer / déchiffrer la clé de produit Windows 7 à partir de Linux

19

J'ai accidentellement déconnecté mon disque dur alors qu'il était encore en cours d'exécution et j'ai corrompu mon installation de Windows 7; Je suis maintenant complètement incapable de démarrer sous Windows. J'ai tout essayé pour réparer et réparer l'installation: Windows Startup Repair, chkdsk / r, SFC / scannow, bootrec / rebuildbcd, etc. et pas de chance. Je veux simplement effectuer une nouvelle installation, mais mon problème est que je n'ai pas écrit ma clé de produit Windows nulle part, et je ne peux pas utiliser de scripts ou d'utilitaires pour la récupérer dans le registre car je ne peux pas démarrer sous Windows.

Les clés de produit Windows 7 sont stockées, chiffrées, dans la valeur "DigitalProductId" de la clé de registre HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion. J'ai pu monter la partition Windows corrompue en lecture seule à partir d'un CD live Ubuntu et copier la ruche de registre Windows \ System32 \ config \ SOFTWARE, qui contient la clé et la valeur en question, sur un lecteur flash, mais en chargeant cette ruche dans regedit sur une installation Windows fonctionnelle, puis en essayant d'utiliser des scripts ou des utilitaires pour décrypter la valeur "DigitalProductId" chargée ne renvoie que la clé de produit de l'installation Windows hôte, quel que soit le nombre de manipulations que j'essaie. J'ai essayé de contacter le support Microsoft et ils ont été plutôt inutiles. Quelqu'un pourrait-il me guider davantage? Peut-être s'il existe un moyen différent de récupérer la clé de produit à partir de Linux?

Si quelqu'un plus familier avec les scripts / la cryptographie est disposé à essayer de suivre le script de décryptage pour décrypter la clé de produit à la main, je pourrais vous envoyer par e-mail la valeur "DigitalProductId" exportée, la ruche du registre LOGICIEL et le script de décryptage.

sundiata
la source
Cela ne semble pas juste. Si vous avez acheté une licence, vous devriez avoir la clé. Maintenant, d'un autre côté, si vous avez mis la main sur quelqu'un d'autre image windows et que vous voulez extraire sa clé, ce n'est pas vraiment le but de ce site.
JasonXA
J'ai acheté une licence. J'ai le DVD d'installation mais je ne trouve pas la clé de produit qui l'accompagne. Mais je pense que j'ai peut-être trouvé une solution ici: dagondesign.com/articles/windows-xp-product-key-recovery/…
sundiata
Oui, cela semble fonctionner. En utilisant la méthode, j'ai réussi à reproduire ma clé.
JasonXA
Si votre micrologiciel est basé sur UEFI, la clé de licence est réellement stockée dans la table ACPI MSDM afin qu'elle persiste pendant un redémarrage. Si c'est le cas, consultez blog.fpmurphy.com pour plus de détails sur la façon de le récupérer.
fpmurphy

Réponses:

30

Il existe un excellent outil disponible pour Linux appelé chntpw. Vous pouvez l'obtenir facilement sur Debian / Ubuntu via:

sudo apt install chntpw

Pour regarder dans le fichier de registre approprié, montez le disque Windows et ouvrez-le comme ceci:

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

Maintenant, pour obtenir le décodage, DigitalProductIdentrez cette commande:

dpi \Microsoft\Windows NT\CurrentVersion\DigitalProductId
Thomas
la source
5
Le chemin d'accès au fichier de registre correspondant se trouve dans / path / to / windisk / Windows / System32 / config / RegBack / SOFTWARE
Mohamed EL HABIB
2
C'est une excellente réponse, je l'ai citée sur Ask Ubuntu askubuntu.com/a/953130/75060
Mark Kirby
Merci pour ça. Veuillez prendre note de vérifier la casse des noms de dossier et de fichier. Dans mon cas, j'ai dû utiliser des majuscules SOFTWAREpour le nom de fichier.
Paddy Landau
Si vous rencontrez des problèmes pour lire le dossier system32, essayez de faire une copie et de fournir le chemin de la copie au chntpw.
Markus von Broady
2

Pour ceux qui n'hésitent pas à faire un peu de codage.

J'ai trouvé un algorithme il y a environ 10 ans et l'ai implémenté en C # (voir ci-dessous)


Si vous souhaitez simplement l'exécuter sous Windows

J'ai pris la liberté de le convertir en script 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

Exécutez cela et vous obtenez votre clé de produit. (Donc pas de codage pour vous après tout)


Message d'origine

C'est donc le code C # réel que j'ai déterré et commenté.

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;
}

Vous devrez le passer Software\Microsoft\Windows NT\CurrentVersioncomme une clé, où il trouvera leDigitalProductId

À cette époque, MS Office Products utilisait le même algorithme, donc en fournissant à la fonction la clé de registre appropriée, il pouvait également calculer ces clés de produit.

Vous pouvez bien sûr refactoriser la fonction pour qu'elle prenne un tableau d'octets en entrée.

Quant à aujourd'hui. Je viens de le tester sur ma machine Windows 10, et cela fonctionne toujours.

MrPaulch
la source
C'est une bonne réponse mais la question est très ancienne et peut ne pas recevoir beaucoup de points de vue. En tant que membre, pensez à ajouter votre réponse à notre message Ask Ubuntu actuel askubuntu.com/questions/953126/…
Mark Kirby
Je vous remercie. Mais je pense que ce serait hors sujet là-bas. Je peux gifler ensemble une implémentation de pseudo-code. Et référez-vous à ce post comme une mise en œuvre réelle.
MrPaulch
Pas de problème, faites ce que vous pensez être le mieux
Mark Kirby
2

Voici un port Python de l'autre réponse (adapté pour Windows 8.1). L'avantage de ceci chntpwest qu'il fonctionnera même avec des disques en lecture seule.

Exigences:

pip install python-registry

Code:

#!/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
la source
La boucle intérieure était une itération trop courte. Ça devrait marcher maintenant.
Lenar Hoyt
0

Voici mon implémentation bash. Je l'appelle get_windows_key.sh fonctionne bien avec clonezilla. Je l'ai initialement posté ici 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
pingouinjeff
la source