
Windows XP Keygen
Um gerador de chaves VLK para Windows XP / Windows Server 2003. Esta ferramenta permite gerar chaves válidas do Windows XP com base na Raw Product Key, que pode ser aleatória.
A Raw Product Key (RPK) é fornecida na forma de 9 dígitos XXX-YYYYYY e só é necessária para gerar uma chave do Windows XP.

Vá até a aba Releases e baixe a versão mais recente de lá.
Este projeto não está morto — farei o meu melhor para torná-lo realidade.
De modo geral, a única coisa que nos separa de gerar chaves válidas do Windows XP para TODA EDIÇÃO e TODA COMPILAÇÃO é a falta das respectivas chaves privadas geradas a partir de suas contrapartes públicas dentro de pidgen.dll. Não há código amplamente disponível online para a função de logaritmo discreto de curva elíptica; há apenas informação vaga sobre como fazer isso.
Com o passar do tempo, o problema foi parcialmente resolvido.
O recurso BINK não foi codificado de nenhuma forma e os dados foram simplesmente gravados sequencialmente no recurso. sk00ter também explicou completamente o formato BINK nos fóruns da MDL. Utilizando o conhecimento comunitário anterior sobre o assunto, escrevi um Leitor de BINK em Python 3. O arquivo é público neste repositório; clique aqui para ver o código-fonte.
A solução do logaritmo discreto é a área de pesquisa mais inexplorada em 28 de maio de 2023. No entanto, meu amigo nephacks encontrou aquela ferramenta elusiva para resolver esse difícil problema nos cantos mais obscuros da internet. Chama-se ECDLP (Elliptic Curve Discrete Logarithm Problem) Solver, do Sr. HAANDI. Como foi extremamente frustrante encontrá-lo online, eu o reenviei no meu site. Você pode baixar a ferramenta aqui.
O arquivo ReadMe que acompanha a versão 0.2a do solucionador é suficientemente bom por si só, então qualquer pessoa com um mínimo de inteligência conseguirá configurar essa ferramenta. No entanto, ela não é open-source, então integrá-la ao meu keygen é comprovadamente impossível.
No cenário ideal, o keygen pediria um recurso BINK extraído de pidgen.dll, que então desmembraria nos seguintes segmentos:
pubX; pubY)genX; genY)a; b)pSabendo desses segmentos, o keygen descobriria por força bruta a ordem do gerador genOrder usando o algoritmo de Schoof, seguido pela chave privada privateKey, aproveitando o genOrder calculado para usar o algoritmo mais otimizado de Rho de Pollard. Não há dúvida de que podemos quebrar qualquer chave privada em cerca de 20 minutos usando o poder computacional moderno, desde que tenhamos o algoritmo funcional.
Quando o keygen terminar de quebrar por força bruta a chave privada correta, a tarefa se resume a realmente gerar uma chave, o que este keygen faz. Para dar uma melhor perspectiva, posso fornecer o fluxo do keygen ideal. O que está riscado é o que o meu keygen implementa:
Precisamos usar uma Raw Product Key aleatória como base para gerar um ID do Produto no formato AAAAA-BBB-CCCCCCS-DDEEE.
A constante da família do SO AAAAA é diferente para cada série do Windows XP. Por exemplo, é 76487 para o SP3.
As seções BBB e CCCCCC essencialmente codificam a Raw Product Key. Por exemplo, se a primeira seção for igual a XXX e a segunda seção for igual a YYYYYY, a Raw Product Key será codificada como XXX-YYYYYY.
O dígito verificador S é escolhido de modo que a soma de todos os dígitos C com ele incluso seja um número divisível por 7.
O índice da chave pública DD nos informa qual chave pública foi usada para verificar com sucesso a autenticidade da nossa Chave do Produto.
Por exemplo, é 22 para chaves Professional e 23 para chaves VLK.
Um número aleatório EEE é usado para gerar um ID de instalação diferente a cada vez.
A própria Chave do Produto (não confundir com a RPK) tem o formato FFFFF-GGGGG-HHHHH-JJJJJ-KKKKK, codificada em Base-24 com o alfabeto BCDFGHJKMPQRTVWXY2346789 para excluir quaisquer caracteres que possam ser facilmente confundidos, como I e 1 ou O e 0.
De acordo com a fórmula de capacidade do alfabeto, a chave pode conter no máximo 114 bits de informação. $$N = \log_2(24^{25}) \approx 114$$
Com base nesse cálculo, desmembramos a Chave do Produto de 114 bits em 4 segmentos ordenados:
Por uma questão de simplicidade, combinaremos os segmentos Upgrade e Serial em um único segmento chamado Data. Com essa lógica, poderemos extrair a RPK deslocando Data para a direita e empacotá-la novamente deslocando bits para a esquerda, porque a maioria das chaves de produto a priori válidas que verifiquei tinha o bit de Upgrade definido como 1.
A Microsoft reformulou o formato da Chave do Produto com o Windows Server 2003 para incluir uma chave de autenticação de servidor backend, que era uma abordagem realmente segura para validação de licenças, pois ninguém poderia adivinhar qual algoritmo de validação eles haviam empregado em seu servidor privado. Além de adicionar o mecanismo de validação online, eles também aumentaram a aritmética geral de 384 para 512 bits e o escalar da assinatura para 62 bits de informação.
No entanto, se gerássemos uma chave sem pensar na ativação online, ainda poderíamos gerar chaves válidas que nos permitiriam passar pela instalação do sistema operacional. E é exatamente isso que o código faz — gera uma chave de autenticação aleatória de 10 bits. Hoje em dia isso não importa em nada, pois os servidores de ativação estão fora do ar e o Server 2003 é considerado abandonware, assim como este projeto inteiro não deveria ser considerado pirataria.
A Criptografia de Curva Elíptica (ECC) é um tipo de sistema criptográfico de chave pública. Essa classe de sistemas depende de problemas matemáticos desafiadores de "mão única" — fáceis de computar em um sentido e intratáveis de resolver no sentido "oposto". Às vezes, são chamadas de funções de "alçapão" — fáceis de cair, complicadas de escapar.[5]
A ECC depende de resolver equações da forma $$y^2 = x^3 + ax + b$$
Em geral, existem 2 casos especiais para a curva elíptica utilizada em criptografia — F2m e Fp. Eles diferem apenas ligeiramente. Ambas as curvas são definidas sobre o corpo finito; Fp usa um parâmetro primo maior que 3, e F2m assume $p = 2m$. A Microsoft usou o último em seu algoritmo.
Uma curva elíptica sobre o corpo finito Fp consiste em:
Uma curva elíptica sobre F17 teria a seguinte aparência:

A curva consiste nos pontos azuis na imagem acima. Na prática, as "curvas elípticas" usadas em criptografia são "conjuntos de pontos em uma matriz quadrada".
A curva acima é "educacional". Ela fornece um comprimento de chave muito pequeno (4-5 bits). Em situações do mundo real, os desenvolvedores normalmente usam curvas de 256 bits ou mais.
Como é um sistema criptográfico de chave pública, a Microsoft teve que compartilhar a chave pública com seu lançamento do Windows XP para verificar as chaves de produto inseridas.
Ela é armazenada dentro de pidgen.dll na forma de um recurso BINK. O primeiro conjunto de dados BINK existe para validar chaves de varejo (retail), e o segundo é para as chaves OEM, respectivamente.
A estrutura do recurso BINK para Windows 98 e Windows XP é a seguinte:
Cada segmento é marcado com uma cor diferente; os valores do cabeçalho BINK são os mesmos.

Windows Server 2003 e Windows XP x64 implementam isso de forma diferente:
E aqui estão meus protótipos de estrutura feitos para o Leitor de BINK em C:```c typedef struct _EC_BYTE_POINT { CHAR x[256]; // x-coordinate of the point on the elliptic curve. CHAR y[256]; // y-coordinate of the point on the elliptic curve. } EC_BYTE_POINT;
typedef struct _BINKHDR { // BINK version - not stored in the resource. ULONG32 dwVersion;
// Original BINK header.
ULONG32 dwID;
ULONG32 dwSize;
ULONG32 dwHeaderLength;
ULONG32 dwChecksum;
ULONG32 dwDate;
ULONG32 dwKeySizeInDWORDs;
ULONG32 dwHashLength;
ULONG32 dwSignatureLength;
// Extended BINK header. (Windows Server 2003+)
ULONG32 dwAuthCodeLength;
ULONG32 dwProductIDLength;
} BINKHDR;
typedef struct _BINKDATA { CHAR p[256]; // Finite Field order p. CHAR a[256]; // Elliptic Curve parameter a. CHAR b[256]; // Elliptic Curve parameter b.
EC_BYTE_POINT G; // Base point (Generator) G.
EC_BYTE_POINT K; // Public key K.
} BINKDATA;
typedef struct _BINKEY { BINKHDR header; BINKDATA data; } BINKEY;
Caso queira explorar mais, o código-fonte de `pidgen.dll` e todas as suas funções está disponível neste repositório, na pasta "pidgen".
### Revertendo a chave privada
Se quisermos gerar chaves de produto válidas para o Windows XP, devemos calcular a chave privada correspondente usando a chave pública fornecida com `pidgen.dll`,
o que significa que temos que resolver inversamente a tarefa ECC de via única.
A julgar pela chave localizada no BINK, a ordem da curva tem **384 bits** de comprimento no Windows XP e **512 bits** no Server 2003 / XP x64, respectivamente.
A dificuldade de cálculo usando o algoritmo mais eficiente de Pollard's Rho com complexidade assintótica $O(\sqrt{n})$ seria de pelo menos $O(2^{168})$ para o Windows XP, e $O(2^{256})$ para o Windows Server 2003, mas, para nossa sorte,
a Microsoft limitou o valor da assinatura a 55 bits no Windows XP e 62 bits no Windows Server 2003, a fim de reduzir a quantidade de chaves de produto correspondentes, diminuindo a dificuldade para um valor muito mais gerenciável de $O(2^{28})$ / $O(2^{31})$.
Como mencionado anteriormente, há apenas uma ferramenta pública que atende às nossas necessidades atuais, que é o solucionador de ECDLP do Sr. HAANDI.<br>
Para calcular a chave privada, precisaremos fornecer à ferramenta os valores ECC públicos localizados no recurso BINK, bem como a ordem `genOrder` do ponto base `G(Gx; Gy)`.
A ordem do ponto base pode ser calculada usando o SageMath.
**Aqui está o algoritmo básico que usei para reverter a chave privada do Windows 98:**
1. Calcule a ordem do ponto base usando **SageMath**. No SageMath, execute os seguintes comandos:
1) `E = EllipticCurve(GF(p), [0, 0, 0, a, b])`, onde `p`, `a` e `b` são parâmetros da curva elíptica representados em decimal, extraídos do recurso BINK.
2) `G = E(Gx, Gy)`, onde `Gx` e `Gy` são coordenadas do ponto base representadas em decimal, extraídas do recurso BINK.
3) `K = E(Kx, Ky)`, onde `Kx` e `Ky` são coordenadas da chave pública representadas em decimal, extraídas do recurso BINK.
4) `n = G.order()`, `n` será a ordem calculada do ponto base. **Pode levar algum tempo para calcular, mesmo nas versões mais recentes.**
5) Fatore a ordem usando `factor(n)`. A Microsoft usou números primos para as ordens dos pontos, portanto, se retornar o próprio número, é completamente normal.
6) Salve os fatores resultantes da ordem em algum lugar.
7) `-K` fornecerá o inverso da chave pública em um plano projetivo com coordenadas `(x : y : z)`. Salve a coordenada `y` em algum lugar, pois ela é necessária para gerar uma chave privada correta.
2. Calcule a chave privada usando o **ECDLP Solver v0.2a**.
1) A ferramenta vem com um trabalho modelo `job_template.txt` e um arquivo ReadMe. É necessário entender como a ferramenta funciona para usá-la.
2) Insira todos os valores públicos da curva elíptica do recurso BINK, **exceto a coordenada `Ky`**. Para gerar uma chave privada correta, **você deve usar a coordenada inversa `-Ky` que você calculou anteriormente no SageMath.**
3) Insira os fatores da ordem do ponto base `n` e especifique a contagem de fatores. Muito provavelmente será `1`, pois a Microsoft usa principalmente números primos para suas ordens de gerador.
4) Execute a ferramenta `<arch> ECDLP Solver.exe <job_name>.txt` e aguarde até que ela calcule a chave privada `k = %d` para você.
**Aqui está um exemplo do trabalho do Windows XP `job_xp.txt` que produz a chave privada correta para o ECDLP Solver.**```pascal
GF := GF(22604814143135632990679956684344311209819952803216271952472204855524756275151440456421260165232069708317717961315241);
E := EllipticCurve([GF|1,0]);
G := E![10910744922206512781156913169071750153028386884676208947062808346072531411270489432930252839559606812441712224597826,19170993669917204517491618000619818679152109690172641868349612889930480365274675096509477191800826190959228181870174];
K := E![14399230353963643339712940015954061581064239835926823517419716769613937039346822269422480779920783799484349086780408,17120082747148185997450361756610881166187863099877353630300913555824935802439591336620545428308962346299700128114607];
/*
FactorCount:=1;
61760995553426173
*/
E a saída do ECDLP Solver para isso:

Nota importante:
Esteja ciente de que não consegui gerar uma chave correta do Windows XP x64 usando a chave privada que reverti, mesmo usando a coordenada Ky em vez do usual -Ky.
Por algum motivo, também não consegui calcular a ordem do ponto base do Windows Server 2003 usando SageMath. Deixei-o calcular por 12 horas no meu i7-12700K, mas ele ainda estava travado no cálculo.
O restante do trabalho é feito no código deste keygen.
0x40000/0x62A32, o que resultava em exatamente
0.64884, ou cerca de 65%. Minha estimativa de "2 em 3" foi incrivelmente precisa.BBB definida como 640 e a seção CCCCCC diferente de zero.Adicionarei mais leituras decentes à bibliografia em versões futuras.
Entendendo os fundamentos da ativação do Windows XP:
Entendendo a Criptografia de Curva Elíptica:
Discussões públicas:
Se você for exibir ou bifurcar este software, por favor credite Endermanch, z22 e MSKey.
Sinta-se à vontade para modificá-lo como preferir, desde que o mantenha em código aberto. Licenciado sob GNU General Public License v3.0.
Quaisquer contribuições ou perguntas são bem-vindas.
genOrder, privateKey)| Dígitos | Significado |
|---|
| AAAAA | Constante da família do SO |
| BBB | ID do canal |
| CCCCCC | Número de sequência |
| S | Dígito verificador |
| DD | Índice da chave pública |
| EEE | Número aleatório de 3 dígitos |
| Segmento | Capacidade | Dados |
|---|
| Upgrade | 1 bit | Flag de versão do Upgrade |
| Serial | 30 bits | Raw Product Key (RPK) |
| Hash | 28 bits | Hash da RPK |
| Assinatura | 55 bits | Assinatura de curva elíptica para o hash da RPK |
| Segmento | Capacidade | Dados |
|---|
| Upgrade | 1 bit | Flag de versão do Upgrade |
| ID do Canal | 10 bits | A parte BBB da RPK |
| Hash | 31 bits | Hash da RPK |
| Assinatura | 62 bits | Assinatura de curva elíptica para o hash da RPK |
| Chave de Autenticação | 10 bits | Valor de autenticação backend |
| Offset | Value |
|---|
0x0000 | BINK ID |
0x0004 | Tamanho da estrutura BINKEY em bytes (sempre 0x16C na prática) |
0x0008 | Comprimento do cabeçalho (sempre 7 na prática) |
0x000C | Checksum |
0x0010 | Data codificada numericamente - versão BINKEY (sempre 19980206 na prática) |
0x0014 | Tamanho da ordem da curva ECC (sempre 12 na prática) |
0x0018 | Comprimento do hash (sempre 28 na prática) |
0x001C | Comprimento da assinatura (sempre 55 na prática) |
0x0020 | Ordem do corpo finito p |
0x005C | Parâmetro da curva a |
0x0098 | Parâmetro da curva b |
0x00D4 | Coordenada x do ponto base Gx |
0x0110 | Coordenada y do ponto base Gy |
0x014C | Coordenada x da chave pública Kx |
0x0188 | Coordenada y da chave pública Ky |
| Offset | Value |
|---|
0x0000 | BINK ID |
0x0004 | Tamanho da estrutura BINKEY em bytes |
0x0008 | Comprimento do cabeçalho (sempre 9 na prática) |
0x000C | Checksum |
0x0010 | Data codificada numericamente - versão BINKEY (sempre 20020420 na prática) |
0x0014 | Tamanho da ordem da curva ECC (sempre 16 na prática) |
0x0018 | Comprimento do hash (sempre 31 na prática) |
0x001C | Comprimento da assinatura (sempre 62 na prática) |
0x0020 | Comprimento do valor de autenticação backend (sempre 12 na prática) |
0x0024 | Comprimento do ID do Produto (sempre 20 na prática) |
0x0028 | Ordem do corpo finito p |
0x0068 | Parâmetro da curva a |
0x00A8 | Parâmetro da curva b |
0x00E8 | Coordenada x do ponto base Gx |
0x0128 | Coordenada y do ponto base Gy |
0x0168 | Coordenada x da chave pública Kx |
0x01A8 | Coordenada y da chave pública Ky |