Giter Site home page Giter Site logo

winrar-keygen's Introduction

WinRAR-Keygen

1. What is WinRAR?

  • WinRAR is a trialware file archiver utility for Windows, developed by Eugene Roshal of win.rar GmbH.

  • It can create and view archives in RAR or ZIP file formats and unpack numerous archive file formats.

  • WinRAR is not a free software. If you want to use it, you should pay to RARLAB and then you will get a license file named "rarreg.key".

  • This repository will tell you how WinRAR license file "rarreg.key" is generated.

2. How is "rarreg.key" generated?

  • WinRAR uses a signature algorithm, which is a variant of Chinese SM2 digital signature algorithm, to process the user's name and the license type he/she got. Save the result to "rarreg.key" and add some header info, then a license file is generated.

  • The following will talk about the detail of the signature algorithm that WinRAR uses and how WinRAR process the user's name and his/her license type.

    2.1. Signature Algorithm

    • WinRAR uses ECC (Elliptic-curve Cryptography) to do signature. The elliptic curve it uses is over a composite finite field FiniteField where the primitive polynomial of base finite field is:

    • And the primitive polynomial of extend finite field is:

    • The elliptic curve equation is:

    • Let G be base point that will be used during signature. The exact value is:

      auto G = ecCurve.GetPoint({           // X, represents a polynomial 
        0x38CC, 0x052F, 0x2510, 0x45AA,   // over GF((2 ^ 15) ^ 17), the first term  
        0x1B89, 0x4468, 0x4882, 0x0D67,   // is in the front.
        0x4FEB, 0x55CE, 0x0025, 0x4CB7,
        0x0CC2, 0x59DC, 0x289E, 0x65E3,
        0x56FD
      }, {                                  // Y, represents a polynomial 
        0x31A7, 0x65F2, 0x18C4, 0x3412,   // over GF((2 ^ 15) ^ 17), the first term  
        0x7388, 0x54C1, 0x539B, 0x4A02,   // is in the front.
        0x4D07, 0x12D6, 0x7911, 0x3B5E,
        0x4F0E, 0x216F, 0x2BF2, 0x1974,
        0x20DA
      });
    • P is the order that will be used during signature. The exact value is:

      const uint64_t P[4] = {   // P = 0x1026dd85081b82314691ced9bbec30547840e4bf72d8b5e0d258442bbcd31
          0x5e0d258442bbcd31,
          0x0547840e4bf72d8b,
          0x2314691ced9bbec3,
          0x0001026dd85081b8
      };

      2.1.1 The Generation of PrivateKey PrivateKey, Random Number K and Hash e

      • To generate PrivateKey PrivateKey, random number K and hash e, we need two byte-arrays. We call them in_data and in_private. Their length is in_data_length and in_private_length respectively.

      • PrivateKey is generated by in_private.
        e is generated by in_data.
        K is generated by both in_data and in_private.

        For better understanding, here I give an case:

        byte in_private[7] = { 'P', 'h', 'a', 'n', 't', 'o', 'm' }; 
        byte in_data[9] = { 'L', 'a', 'b', 'y', 'r', 'i', 'n', 't', 'h' }; 

        where in_private_length is 7 and in_data_length is 9.

        2.1.1.1 The Generation of PrivateKey.
        • Calculate in_private's SHA-1 digest.

          In the case I give, it should be:

          byte in_private_sha1[] = {        //  standard sha-1 value is : {
              0xc0, 0x16, 0x3f, 0x02,       //      0x02, 0x3f, 0x16, 0xc0, 
              0x78, 0x4b, 0xac, 0x8c,       //      0x8c, 0xac, 0x4b, 0x78, 
              0xaf, 0x97, 0x0d, 0xe6,       //      0xe6, 0x0d, 0x97, 0xaf, 
              0xd9, 0x46, 0xa4, 0x91,       //      0x91, 0xa4, 0x46, 0xd9, 
              0xdc, 0xb3, 0xbf, 0x06        //      0x06, 0xbf, 0xb3, 0xdc
          };                                //  }

          NOTICE: Compared with standard SHA-1 calculation, WinRAR reversed each 32-bits block.

          If in_private is null, use default value:

          byte in_private_sha1[] = { 
              0x81, 0xb7, 0x3e, 0xeb, 
              0x29, 0x53, 0x26, 0x50, 
              0xa3, 0xf4, 0x5e, 0xdc, 
              0xd5, 0xb9, 0x47, 0x68, 
              0x4c, 0x3b, 0xe4, 0xcd 
          };

          It is probably the SHA-1 digest of some secret data used in RARLAB

        • To get each part of PrivateKey, do 15 rounds of SHA-1 calculation:

          1. Let i be uint32_t varing from 1 to 15.

          2. In each round, we calculate the SHA-1 digest of a 24-bytes-long byte-array which is the combination of i (little-endian) and src_data_sha1. Then take the first two bytes and append them at the end of PrivateKey.

        • After that, PrivateKey should be a 30-bytes-long and its value is:

          In the case I give, PrivateKey is:

          byte PrivateKey[30] = {       // PrivateKey = 0xb7e256217a67f14e3fb4246e889ea18b69b246616e04525e96d515831f2a  
              0x2a, 0x1f, 0x83, 0x15,   // which is a 240-bits-long integer.
              0xd5, 0x96, 0x5e, 0x52, 
              0x04, 0x6e, 0x61, 0x46, 
              0xb2, 0x69, 0x8b, 0xa1, 
              0x9e, 0x88, 0x6e, 0x24, 
              0xb4, 0x3f, 0x4e, 0xf1, 
              0x67, 0x7a, 0x21, 0x56, 
              0xe2, 0xb7 
          };

          In my code I use a uint64_t[4] array to store it.

        2.1.1.2 The Generation of K and e.
        • During the generation of PrivateKey, there is a temporary 24-bytes-long byte-array. After all of the 15 rounds, the temporary byte-array should be the combination of uint32_t(15) (little endian) and src_data_sha1.

          In the case I give, it should be:

          byte in_private_sha1_temp[] = { 
              0x0f, 0x00, 0x00, 0x00, 
              0xc0, 0x16, 0x3f, 0x02,  
              0x78, 0x4b, 0xac, 0x8c,  
              0xaf, 0x97, 0x0d, 0xe6,  
              0xd9, 0x46, 0xa4, 0x91, 
              0xdc, 0xb3, 0xbf, 0x06 
          };
        • Calculate in_data's SHA-1 digest:

          In the case I give, it should be:

          byte in_data_sha1[] = { 
              0xfc, 0x0e, 0xcd, 0xba, 
              0x12, 0xa0, 0xc6, 0x2e, 
              0x96, 0xf6, 0xbe, 0xdb, 
              0x9f, 0x89, 0x72, 0x10, 
              0x05, 0x05, 0x71, 0xe0 
          };
        • Append

          byte empty_sha1[] = { 
              0x43, 0x8d, 0xfd, 0x0f, 
              0x7c, 0x3c, 0xe3, 0xb4, 
              0xd1, 0x1b, 0x46, 0x53, 
              0x46, 0xa5, 0x27, 0x0f, 
              0x0d, 0xd9, 0x50, 0x10
          };

          at the end of in_data_sha1 so we can get byte-array (in_data_sha1 + empty_sha1). The byte-array appended is the SHA-1 digest of null while 5 SHA-1 initial constants is set 0. Then take the first 30 bytes of (in_data_sha1 + empty_sha1) as e.

        • Append (in_data_sha1 + empty_sha1) at the end of in_private_sha1_temp.

          In the case I give, it should be:

          byte in_private_sha1_temp[] = { 
              0x0f, 0x00, 0x00, 0x00,   // original in_private_sha1_temp.
              0xc0, 0x16, 0x3f, 0x02,  
              0x78, 0x4b, 0xac, 0x8c,  
              0xaf, 0x97, 0x0d, 0xe6,  
              0xd9, 0x46, 0xa4, 0x91, 
              0xdc, 0xb3, 0xbf, 0x06, 
              0xfc, 0x0e, 0xcd, 0xba,   // in_data_sha1
              0x12, 0xa0, 0xc6, 0x2e, 
              0x96, 0xf6, 0xbe, 0xdb, 
              0x9f, 0x89, 0x72, 0x10, 
              0x05, 0x05, 0x71, 0xe0,
              0x43, 0x8d, 0xfd, 0x0f,   // empty_sha1
              0x7c, 0x3c, 0xe3, 0xb4, 
              0xd1, 0x1b, 0x46, 0x53, 
              0x46, 0xa5, 0x27, 0x0f, 
              0x0d, 0xd9, 0x50, 0x10
          };
        • To get each part of red_K, do 15 rounds of SHA-1 calculation.
          In each round, do

          ++*reinterpreter_cast<uint32_t*>(in_private_sha1_temp);

          first, then calculate the SHA-1 digest of in_private_sha1_temp and append the first two bytes of the digest at the end of K.

          In the case I give, it should be:

          byte K[] = { 
              0xeb, 0xed, 0x4f, 0xba, 
              0x0b, 0x30, 0xe8, 0x26, 
              0xf4, 0xec, 0xe6, 0x92, 
              0x76, 0xcc, 0xe8, 0x0b, 
              0xa8, 0x9c, 0x6f, 0x3a, 
              0x41, 0x6d, 0x5c, 0xfe, 
              0x21, 0x42, 0x5a, 0x5a, 
              0x5d, 0xbe
          };

          In my code I use a uint64_t[4] array to store it.

      2.1.2 The Generation of Singnature rs and PublicKey PublicKey

      • Now we have PrivateKey PrivateKey, random number K, hash e, order P and base point G.

      • equation

        NOTICE:

        1. The dot in equation refers to the elliptic curve point multiplication on equation over FiniteField.

        2. equation means takeing X-axis value of a point. This value is a polynomial over FiniteField.

        3. Function T converts a polynomial over FiniteField to a integer whose bit length would not larger than 15 * 17 = 255. The detail of function T will be talked about later.

        4. equation is integer addition.

      • equation

        NOTICE:

        1. equation is integer multiplication.

      • equation

        NOTICE:

        1. equation is division over FiniteField.

        2. equation is binary AND operation.

      • About function T:
        As I said before, it converts a polynomial over FiniteField to a integer. If I use a 17-elements-long list represent a polynomial over FiniteField, whose every element represents a polynomial over equation, function T can be defined as the following Python code:

        def T(x : list):
            ret = 0
            for i in range(0, 17):
                ret += x[i] * 2 ** (15 * i)
            
            return ret

    2.2. The Generation of "rarreg.key"

    • rarreg.key consists of a header, user's name, license type, UID, registration data and checksum.

      2.2.1 Header

      • It is just a text line:

        RAR registration data

      • Actually, when WinRAR verifies user's license file, it does not care what content the header have.

      2.2.2 User's name

      • It is also just a text line. Here I give a case:

        Phantom

      2.2.3 License type

      • Also just a text line. Actually it can be any text. Here I give a case:

        Single PC usage License

      2.2.5 UID

      • It is just a join of two parts of registration data. Here I give a case:

        UID=294d3fd81ae79b20c48c

      • Actually, when WinRAR verifies user's license file, it does not case UID at all.

      2.2.5 Registration data

      • Registration data has four parts. We name them RegData0, RegData1, RegData2, RegData3 respectively.

      • If ECC signature of license type is r and s (, which means in_data = license type, in_private = null) , convert their value to hex string str_R, str_S. The max possible length of str_R and str_S is 60 because r and s are both 30 bytes long. So RegData1 is the format output of "60", str_S and str_R:

        _stprintf_s(RegData[1], TEXT("60%060s%060s"), str_S, str_R);

        In the case I give, it should be:

        char RegData[1] = "60cc0b2d34fdb287124c6ca6b4f3239d36aa3ef82a9aba3a22d45552465c93260c3f609e601c26f312c4f44e7f8773a98b078809297303f8cac4a5ff92";
      • Let str_Kpub be the hex string of PublicKey that is generated by user's name (in_private = user's name). RegData3 is:

        _stprintf_s(RegData[3], TEXT("%zd%.48s"), strlen(str_Kpub) - 4, str_Kpub);

        In the case I give, it should be:

        char RegData[3] = "6067c38462f2ff189c4b04e3c0540548d096e1068d9235023c";
      • Let str_Kpub2 be the hex string of PublicKey that is generated by RegData3 (in_private = RegData3). So:

        _stprintf_s(RegData[0], TEXT("%s"), str_Kpub2);

        In the case I give, it should be:

        char RegData[0] = "c48c1c168f2ddf266ab3c33118678236ddeb1319b06790c929a038e487c79c60";
      • UID is:

        _stprintf_s(UID, TEXT("UID=%.16s%.4s"), str_Kpub + 48, str_Kpub2);

        In the case I give, it should be:

        char UID = "UID=294d3fd81ae79b20c48c";

        which is the same as what said before.

      • If ECC signature of str_UserName_RegData0 that is the join of user's name and RegData0 is r and s (, which means in_data = user's name + RegData0, in_private = null) , convert their value to hex string str_R2, str_S2. So RegData2 is the format output of "60", str_S2 and str_R2:

        _stprintf_s(RegData[2], TEXT("60%060s%060s"), str_S2, str_R2);

        In the case I give, it should be:

        char RegData[2] = "60625690ab228461b54ab9a4c0a4cc5f7fdf47aa192f839596b1628abf1bec0f405163f46ce6a778adc398cefae18dbb0e4f46291e4d61e573ae0eaeb9";

      2.2.5 Registration data

      • TODO

    • The output:
        _tprintf_s(TEXT("RAR registration data\n%s\n%s\n%s\n"), 
               UserName,
               LicenseType,
               UID);
        
        char temp[1024] = { };
        _stprintf_s(temp, TEXT("%zd%zd%zd%zd%s%s%s%s%lu"),
                strlen(RegisterData[0]),
                strlen(RegisterData[1]),
                strlen(RegisterData[2]),
                strlen(RegisterData[3]),
                RegisterData[0],
                RegisterData[1],
                RegisterData[2],
                RegisterData[3], 
                checksum);
      
        for (int i = 0; i < 8; ++i)
            _tprintf_s(TEXT("%.54s\n"), temp + i * 54);
      is rarreg.key.

3. How to build keygen?

  • Please make sure that you have Visual Studio 2015 or the higher. Because this is a VS2015 project.

  • You can open the project by VS2015 IDE and then build it with one click. Or use VS Developer Command Prompt:

    msbuild winrar-keygen.vcxproj /p:Configuration=Release;Platform=<x86|x64>;OutputPath=<your_output_dir> /t:build
  • NOTICE: Do not use "Debug" configuration. Otherwise you may approximately wait for half a minute every time you generate a license file.

4. Example

D:\Github\winrar-keygen>msbuild winrar-keygen.vcxproj /p:Configuration=Release;Platform=x64;OutDir=D:\winrar-keygen\ /t:build
    ......
    ......

D:\Github\winrar-keygen>cd D:\winrar-keygen

D:\winrar-keygen>winrar-keygen.exe "Phantom" "Single PC License" >> rarreg.key

winrar-keygen's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.