-
Notifications
You must be signed in to change notification settings - Fork 63
Open
Labels
questionFurther information is requestedFurther information is requested
Description
It would be pretty useful to know how Windows 98 (and all its editions) verifies its product keys. At first glance, it seems to be a pretty similar system to XP's. 98 seems to be an outlier in the retro Windows scene, as nobody has come up with a generator yet, whereas XP has this one and the versions before 98 use a simple algorithm with many GitHub repos implementing it, some in creative ways.
Neo-Desktop
Metadata
Metadata
Assignees
Labels
questionFurther information is requestedFurther information is requested
Projects
Milestone
Relationships
Development
Select code repository
Activity
Endermanch commentedon Apr 13, 2023
There is a 5-in-1 generator from MSKey for Windows 95, Windows 95 / NT 4 OEM, Windows 98, Windows 98 OEM and Windows 98 Upgrade. Even if I theoretically implemented Windows 98 generation, that would be a job for a different keygen.
grechnik commentedon May 19, 2023
The check is exactly the same as in XP, only parameters are different:
for Retail keys,
for OEM keys.
As far as I know, these parameters are the same for all editions except betas. (Upgrade keys differ from normal keys by the lower bit of Product Key.)
CONIGUERO commentedon May 20, 2023
Woah, that's amazing! Thank you!
Also, how did you calculate
pri? Or did you just extract it from MSKey4in1?grechnik commentedon May 20, 2023
No. MSKey4in1 knows nothing about Win98, and mskey.exe from the second comment just prints some hardcoded keys for Win98 (and some of them are not even valid, using '1' or 'A').
In fact, I have implemented and run Pollard's rho for these points and curve, but I don't want to share the code.
Endermanch commentedon May 20, 2023
I don't remember getting any garbage keys from the mskey.exe I sent.
Why would you not want to share the code? It would be helpful, especially that you seem to know what you're talking about.
Endermanch commentedon May 20, 2023
Acquiring the private key and the order of the curve isn't sufficient but necessary to the generation process. Surely, though, the generation algorithm itself is different.
Besides, I don't expect the Raw Product Key format to be the same either in Windows 98.
Addressing the OP's question, you clearly must have extracted the pubkey from the pIDgen.dll, which you also should have the code for.
That would be excellent learning material!
grechnik commentedon May 20, 2023
well, mskey.exe has 47 keys in "Windows 98 OEM" group and maybe five of them are not valid win98 keys, and "Full"/"Upgrade" groups are much smaller and fully correct, so it does take some luck (misfortune?) to get one
Yet, it is literally the same except that different behaviour for ChannelID has only appeared in XP, so one does not need to worry about setting a "correct" BBB (in terms of README.md). Even the BINK resources have the same format, except that pidgen.dll was 16-bit back then, so finding the blob in the file is different - but once one finds the blob, its structure is the same (already with 32-bit fields).
Rewind to 1995. Windows 95 has just been released, product keys have no cryptographic protection, and that is sort of bad. Elliptic-curve cryptography is either a thing from frontiers of science or some lunatic math depending on your point of view. Given a problem of protecting product keys that should nevertheless be reasonably short, Microsoft Research develops a cryptographic scheme that we all know. For 1995, it makes some sense.
Fast-forward three years. Windows 98 incorporates the new scheme of cryptographically-signed product keys. Nobody cares because everyone just uses the same key. MS takes it as a sign that the scheme is good; everything else (Office/WinME/Win2k) uses the same scheme, only concrete numbers are changed (a key from win98 shouldn't be valid for win2k).
Fast-forward another three years. XP introduces WPA, nobody wants to share keys anymore (okay, that is not exactly true, but it is true enough to make a pressure to find alternate ways; and "Devil's Own" VL key was banned after all), so people actually try to make keygens. Moore's law is good, ECC slowly expands its usage and becomes better known. The scheme is still cryptographically secure in the sense that nobody knows better-than-generic-blackbox-attacks, but suddenly it turns out that the parameters are just too small, and the generic attacks are within the reach, and even in two different ways. (One way is what this repository does: blackbox discrete logarithm for n-bit groups uses O(2^(n/2)) operations, it is not too much for n=55. Another way uses the fact that the check field is 28-bit, so a random key with a correct ChannelId has probability 2^(-28) to pass the check; just keep checking random keys until one of them passes, that requires 2^28 checks per key on average - I think computers from 2001 could do that in maybe several hours per key.)
MS has noticed the keygens, but it is hard to totally redesign a cryptographic scheme on a short notice. For 2003 Server (and XP64 which is essentially 2003 Server with repainted wallpapers), they raised parameters as much as they could (and also introduced 10-bit server-auth field at expense of ChannelId that is encoded in more complicated way), which may have stopped keygenners for some time, but not forever.
In Vista, the product keys are finally checked in entirely different way, it marks the end of this story. (I have not seen any discussion on how Vista does this.) (And in Win8, MS has entirely dropped client-side crypto checks for product keys, leaving only 10-bit CRC to prevent typos and hoping for server-side checks during activation.) But before that, everything used one of two variations (XP vs 2003Server) of the same scheme where the only things that differ are concrete numbers to plug in.
CONIGUERO commentedon May 20, 2023
That's a nice bit of history and explanation, I appreciate the in-depth look.
However, why couldn't you want to release the code so that we can all generate keys for all editions? It would greatly improve the field and preservation ease, not having to rely on keys posted all over the place and having everything documented and easily accessible is always a plus.
Endermanch commentedon May 20, 2023
Could you elaborate on the server-auth (prefix) field and how it's related to the ChannelID? What exactly do you mean by more complicated encoding? I searched enough, but I couldn't find the Product ID <-> Raw Product Key relation for Server 2003, so it's still kind of a mystery. You very likely know much more.
But most importantly, Server 2003 seems to be oblivious to the prefix (that server-auth field). I tested the code with that field generated with RNG and it works about half of the times, given the high bits are set.
At first, I thought it was a SHA prefix, but if it actually serves a real purpose other than being salt, it might explain why the generation fails sometimes.
Vista abandoned the initial activation mechanism, it uses SLP 2.0 exclusively, which is rather easy to crack. People moved on from using keygens to instead emulating ACPI SLIC tables to trick Windows into thinking its activated.
//
Are there any papers/resources you could suggest on this particular topic, asides from the known MSKey 4-in-1 ReadMe? The code would MARGINALLY help too. You don't have to share it, but if you did it really would help everyone with understanding how to approach this task. Any help is appreciated!
grechnik commentedon May 21, 2023
That's the point. The client never checks this field. That field exists so that MS servers (mainly activation servers, maybe update center servers) can distinguish between a true key and a generated one: if there is no code in the OS, then nobody can reverse-engineer how the field is checked, so any keygen can not do better than a random guess.
On the other hand, if you don't care about MS servers, this field doesn't matter at all.
XP keys don't have this field. In the initial release of XP, activation servers happily proceeded with anything that the OS itself accepted. First keygens have shown the weakness. Then, MS presumably has built a database of MS-generated keys - maybe only new ones starting from some moment? - and made activation servers contact this database; this closed the weakness, but presumably MS wasn't too happy - maybe maintaining such a database is a pain? - and decided to implement other measures.
You don't check the return value of
BN_sqrt_mod. Half of numbers modulo a prime are not squares, soBN_sqrt_modfails about half of the times, you should just restart with a different seed ifBN_sqrt_modreturnsNULL.Patent US7512232: https://patents.google.com/patent/US7512232B2/en . XP keys have bitfields 1+30+28+55 for UpgradeOnly+SerialNumber+r+s, where SerialNumber is later split as
ChannelId*1000000+CCCCCC, and r,s form a ECC signature. 2k3 keys have larger ECC signature and additional server-auth field, but the same length, so MS had to get creative with SerialNumber field; 2k3 bitfields are 1+10+31+62+10 for UpgradeOnly+ChannelId+r+s+ServerAuth, and the CCCCCC part is encoded inside r,s. For the details, see the patent or https://github.com/Endermanch/XPKeygen/blob/main/server.cpp in this repository.Endermanch commentedon May 21, 2023
That's what MSKey 4-in-1 stated, and that's exactly why I rerun the generator function if it returns an invalid point. Thanks for clarifying! I'm rather new to cryptography, so my intuition failed me when I thought squares should appear more often than not.
I guess I just didn't get what you meant by "encoding".
A rather credible source I found today explained everything. It makes much, much more sense now.
MSKey 4in1 Readme is just completely wrong. But that's what I assumed anyway.
Thank you for explaining everything in detail. Not too happy though - I'll have to completely rewrite my Readme on the subject. Haha
The final thing I don't entirely understand is how the signature scalar cap affects the discrete logarithm computation time despite the 512-bit curve parameters. It's relatively tangent to key generation, but it might help if you do know that as well.
29 remaining items
Hackerpcs commentedon Jun 3, 2023
Let me post my findings:
Using the method from here
https://forums.mydigitallife.net/threads/elliptic-curve-product-keys.84765/page-4#post-1791679
that uses the said tool from the topic:
What works:
Win98 SE Memphis beta
Win98 SE
WinME beta
WinME
Win 2000 beta -- no key required
Win2000
win2000 Datacenter -- no key required
Neptune -- no key required
WinXP Whistler 2250 -- Same BINK as Win 2000
winXP home
winXP Pro
winXP Pro VL
winXP MCE
winXP Tablet
WinXP Fundamentals for Legacy PCs 2006
WinXP POSReady 2009
Win2k3 x86 SP3
Win2k3 x64 SP3
WinXP x64
What doesn't:
WinXP Whistler 2428 -- fails to login with both Retail/VL and also xp_activate32 with a valid key from the internet doesn't work (button and manually typing it)
WinXP Whistler 2504 -- fails to login with both Retail/VL and also xp_activate32 with a valid key from the internet doesn't work (button and manually typing it)
Longhorn everything from 3683 to before Omega 13 reset --- fails to login with both Retail/VL
More detailed:
ISOs with "=" in same line have SHA512 hash equal PIDGEN files, different lines mean different PIDGEN files but same parameters. Hash is the "p" parameter of the BINK, first one is the first one of the PIDGEN, second from OEM
Win 98 SE Memphis Win ME beta Win XP Whistler BINK ID00.ks2
Win 98 SE Memphis Win ME beta Win XP Whistler BINK ID01.ks2
93F34FD7BDC8DF <rest of it redacted>
OEM: 8CED085EB6834E <rest of it redacted>
Microsoft Windows 98 Second Edition (''Memphis'' 4.10.2120) (beta).7z
Microsoft Windows 98 Second Edition (''Memphis'' 4.10.2183A) (beta).7z
Microsoft Windows 98 Second Edition (''Memphis'' 4.10.2185) (beta).7z
Microsoft Windows ME (''Millennium'' 4.90.2380.2 B1)
Microsoft Windows ME (''Millennium'' 4.90.2419 B2)
Microsoft Windows ME (''Millennium'' 4.90.2499.3 B3)
Microsoft Windows ME (''Millennium'' 4.90.2525 RC0)
Microsoft Windows XP (''Whistler'' 5.1.2428.1 Professional B1)
Microsoft Windows XP (''Whistler'' 5.1.2504.0 Professional RC1)
Win 98 SE BINK1 ID02
Win 98 SE BINK2 ID00
F2F1C54EB7F01D <rest of it redacted>
OEM: EC224FF2613A9F <rest of it redacted>
Microsoft Windows 98 Second Edition [Greek] (OEM) (ISO)
Win Me BINK1 ID1C
Win Me BINK2 ID00
F1AF939098E965 <rest of it redacted>
OEM: B4EAB97C6DEB7D <rest of it redacted>
Microsoft Windows ME [Greek] (OEM) (ISO)
Win 2000 Pro SP3 BINK ID12.ks2
Win 2000 Pro SP3 OEM BINK ID13.ks2
85FC84B75ACF83 <rest of it redacted>
OEM: D33D46BCF4B09C <rest of it redacted>
Windows 2000 Professional With Service Pack 3 OEM Greek (FFFFFFFF) = Windows 2000 Professional (OEM) [Greek] (ISO) SP0 (FFFFFFFF) win 2000 pro GR PIDGEN
Win 2000 Datacenter BINK ID0A.ks2
F197163D2F8C82 <rest of it redacted>
OEM: same as "Win 2000 Pro SP3 OEM BINK ID13.ks2"
Microsoft Windows 2000 Datacenter (5.00.2195.6717.sp4)5.00.2195.6717_x86fre_DTCServer_en-us PIDGEN.DLL
Win XP Home SP3 BINK ID2A.ks2
Win XP Home SP3 OEM BINK ID2B.ks2
C6DF4AADAD63FC <rest of it redacted>
OEM: 991C0E04D13B28 <rest of it redacted>
en_windows_xp_home_with_service_pack_3_x86_cd_x14-92413 = el_windows_xp_home_with_service_pack_3_x86_cd_x14-92417
Win XP Pro SP3 BINK ID2C.ks2
Win XP Pro SP3 OEM BINK ID2D.ks2
9E9C1B126AF9F2 <rest of it redacted>
OEM: DFB971F2B49B5E <rest of it redacted>
en_windows_xp_professional_with_service_pack_3_x86_cd_x14-80428 PIDGEN.DLL
el_windows_xp_professional_with_service_pack_3_x86_cd_x14-80448 PIDGEN.DLL
en_winxp_mce_2005_cd1 = en_winxp_tablet_2005_cd1 PIDGEN
Win XP Pro SP3 VL BINK ID2E.ks2
Win XP Pro SP3 VL OEM BINK ID2F.ks2
92DDCF14CB9E71 <rest of it redacted>
OEM: B211C74AF6A89D <rest of it redacted>
en_windows_xp_professional_with_service_pack_3_x86_cd_vl_x14-73974 PIDGEN.DLL
el_windows_xp_professional_with_service_pack_3_x86_cd_vl_x14-73988 PIDGEN.DLL
en_win_xp_tabletpc_2005_disc1_vl PIDGEN
SW_CD_SA_Win_Fundamentals_LPC_2006_English_MultiLang_WinFLp_Core_CD_MLF_X12-27765
Win XP POSReady 2009 Product ID 620 BINK ID0D
8A257D5BD5C995 <rest of it redacted>
OEM: no OEM, it only contains one BINK
en_windows_embedded_posready_2009_x86_dvd_283454 pidgen
WitherOrNot commentedon Jun 5, 2023
I generated an interesting key for Longhorn 4074:
CB2DK-H2CFP-WY9YK-X4C7H-QV4B3Supposedly, this key has an "infinite" evaluation period (pid 105):
{ "index": 7, "bink": "00000074", "pid_range": [ 105, 105 ], "type": "Evaluation", "days_to_activate": 0, "days_evaluation": 2147483647 }I set the date a year forward and I can still login, but I have no idea if this is because of the key or not.
MeowTechOpenSource commentedon Jun 5, 2023
How do you generate LH keys?
WitherOrNot commentedon Jun 5, 2023
I will PR support for x64/Longhorn/Server key generation to Neo-Desktop/WindowsXPKg once @Endermanch finishes refactoring.
For the impatient, here is my testing Jupyter notebook:
https://gist.github.com/WitherOrNot/e2f1f4a6b17a7ffcd7e2426c75bc2278
You will need an installation of SageMath to use it.
MeowTechOpenSource commentedon Jun 5, 2023
Thanks. I would like to know is k and n value Found by the solver app? We can extract the other value but not these.
Neo-Desktop commentedon Jun 5, 2023
For the record, none of these keys are unsolvable
They may take up to about 20 minutes
But if there are any that are more intensive, version 0.3a of the solver is GPU/CUDA assisted
WitherOrNot commentedon Jun 6, 2023
v0.3a CUDA is not usable, its CUDA SDK is too old for modern GPUs...
Endermanch commentedon Jun 6, 2023
Read the README file.
Neo-Desktop commentedon Jun 6, 2023
unrelated and off topic:
@WitherOrNot: I went ahead and sent you a signed email regarding communication outside of GitHub
just wondering if you got it and if you're interested feel free to respond to it (:
WitherOrNot commentedon Jun 6, 2023
Thanks! Just sent my response
Hackerpcs commentedon Jun 7, 2023
This is correct, Server 2003 R2 x86 worked in ~5-10 minutes with ECDLP Solver v0.2a on a 5600x with PBO on, to be honest I saw
in the readme and didn't even try. I will try more "unsolvable" from above and will edit my comment
Neo-Desktop commentedon Jun 7, 2023
For what its worth,
keys.jsonin the WindowsXPKg repo has everything precalculated, if we're missing BINKs just tell us where to find them and we'll get them calculatedess7 commentedon Apr 15, 2024
I can't prove it but I'm the author of
xpkeyandwin2k3keyon AntiWPA.Back in 2002 there was a Slashdot article about a Windows XP keygen by TheBlueList. Someone posted a base64 encoded .zip of the .exe if you want to try it out (good old days when a keygen can fit in a comment and not removed as spam). It was slow so I figured it was using some kind of brute force.
I eventually reversed the keygen (found the IDA .idb created Aug 2003). I was studying elliptic curves at that time so it was nice to find ECC in the XP product key. The signature verification was not something familiar, it probably took a week before I found it by chance in the Handbook of Applied Cryptography as the Schnorr signature. At that time they did not know the private key, thus the brute force approach. It was done by fixing a random signature then trying different PID values until the 28-bit hash matched.
At this point I had a clone of TheBlueList keygen using my own ECC library and GMP.
The private key seemed feasible to solve given the small order of the subgroup. The basic (non-parallel) Pollard's rho algorithm is simpler than the keygen, just 114 SLOC excluding the ECC library. The group order was found on my home PC; the private key on an internet cafe where I left the program running and got the result the next day (sorry). My keygen was updated to use the private key for signing instead of bruteforcing the hash.
I sat on this for ~3 years until around 2006 when I first discussed my work on the AntiWPA forum. The old forum is gone but some of it got archived. That was the first time I became aware of MSKey4in1. My 2003 keygen was based on the README (I probably copied the EC parameters/private key from the .exe). I got in contact with cw2k who suggested to upload the XP and 2003 keygen sources on AntiWPA. I rewrote it to use OpenSSL instead of my ECC library.
cw2k was also working on the beta version of Vista's pidgenx.dll but it was obfuscated. Speculation from PDB strings suggest the algorithm is a pairing-based short signature, confirmed here.
If you read this thread, apologies for the unreadable code that looks like compiler optimizations.
qtqgyt commentedon Nov 18, 2024
Can someone help a simple minded idiot like me EXACTLY understand the 98 key algorithm?
BlackAnt1968601851 commentedon Dec 17, 2024
Hey does anyone know where the trial license is stored at for windows xp? so I want to try to backup that location and create a infinite loop by setting the date back to the date of install.