WinRar授权生成工具

原创软件 · 昨天 · 8 人浏览
WinRar授权生成工具

说明

支持当前WinRar7.23最新版本

使用说明

打开软件,输入自己需要的用户名,然后点击生成授权,生成授权成功之后,点击保存授权,软件将会自动寻找Winrar的安装目录,自动替换授权文件。

截图

e38dc3a93f635e26c1778effc7cf6bae.png

下载地址

WinRar授权生成

生成核心算法来源于网络!

命令行C#源码

using System;
using System.IO;
using System.Text;
using System.Numerics;
using System.Security.Cryptography;

public class WinRARDynamicKeygen
{
    public struct Point { public ushort[] x; public ushort[] y; public bool infinity; }
    static ushort[] gfLog = new ushort[32768];
    static ushort[] gfExp = new ushort[32768];
    static RandomNumberGenerator rng = RandomNumberGenerator.Create();
    static readonly Point BASE_POINT = new Point{
        infinity=false,
        x=new ushort[]{0x38CC,0x052F,0x2510,0x45AA,0x1B89,0x4468,0x4882,0x0D67,0x4FEB,0x55CE,0x0025,0x4CB7,0x0CC2,0x59DC,0x289E,0x65E3,0x56FD},
        y=new ushort[]{0x31A7,0x65F2,0x18C4,0x3412,0x7388,0x54C1,0x539B,0x4A02,0x4D07,0x12D6,0x7911,0x3B5E,0x4F0E,0x216F,0x2BF2,0x1974,0x20DA}
    };
    static readonly BigInteger ORDER = ParseHex("1026dd85081b82314691ced9bbec30547840e4bf72d8b5e0d258442bbcd31");
    static readonly BigInteger PRIVATE_KEY = ParseHex("59fe6abcca90bdb95f0105271fa85fb9f11f467450c1ae9044b7fd61d65e");
    static readonly uint[] CrcTable = BuildCrcTable();

    static WinRARDynamicKeygen(){ InitGf15(); }

    static void InitGf15(){
        gfExp[0]=1;
        for(int i=1;i<32767;i++){ uint t=(uint)gfExp[i-1]*2; gfExp[i]=(ushort)(t>=0x8000 ? (t^0x8003) : t); }
        gfExp[32767]=1;
        for(int i=0;i<32767;i++) gfLog[gfExp[i]]= (ushort)i;
    }
    static ushort Gf15Mul(ushort a, ushort b){ if(a==0||b==0)return 0; uint g=(uint)gfLog[a]+gfLog[b]; if(g>=32767)g-=32767; return gfExp[g]; }
    static ushort Gf15Inv(ushort a){ if(a==0) throw new DivideByZeroException(); uint g=32767u-gfLog[a]; return gfExp[g]; }
    static ushort Gf15Div(ushort a, ushort b){ return Gf15Mul(a,Gf15Inv(b)); }

    static ushort[] Zero(){ return new ushort[17]; }
    static bool IsZero(ushort[] a){ for(int i=0;i<17;i++) if(a[i]!=0) return false; return true; }
    static ushort[] Add(ushort[] a, ushort[] b){ var r=(ushort[])a.Clone(); for(int i=0;i<17;i++) r[i]^=b[i]; return r; }
    static ushort[] Mul(ushort[] a, ushort[] b){ var t=new ushort[33]; for(int i=0;i<17;i++){ if(a[i]==0)continue; for(int j=0;j<17;j++) if(b[j]!=0) t[i+j]^=Gf15Mul(a[i],b[j]); } Reduce33(t); var r=new ushort[17]; Array.Copy(t,r,17); return r; }
    static void Reduce33(ushort[] t){ for(int i=32;i>=17;i--){ if(t[i]!=0){ ushort v=t[i]; t[i-17]^=v; t[i-14]^=v; t[i]=0; } } }
    static ushort[] Square(ushort[] a){ var t=new ushort[33]; for(int i=0;i<17;i++){ if(a[i]!=0){ uint g=((uint)gfLog[a[i]]*2)%32767; t[2*i]=gfExp[g]; } } Reduce33(t); var r=new ushort[17]; Array.Copy(t,r,17); return r; }
    static ushort[] Inv(ushort[] a){
        if(IsZero(a)) throw new DivideByZeroException();
        var f=new ushort[34]; var g=new ushort[34]; var b=new ushort[34]; var c=new ushort[34]; int degF=0;
        for(int i=0;i<17;i++){ f[i]=a[i]; if(a[i]!=0) degF=i; }
        g[0]=1; g[3]=1; g[17]=1; int degG=17; b[0]=1; int degB=0, degC=0;
        while(true){
            if(degF==0){ ushort invF0=Gf15Inv(f[0]); var res=new ushort[17]; for(int i=0;i<=degB && i<17;i++) res[i]=Gf15Mul(b[i],invF0); return res; }
            if(degF<degG){ var tmp=f; f=g; g=tmp; int ti=degF; degF=degG; degG=ti; tmp=b; b=c; c=tmp; ti=degB; degB=degC; degC=ti; }
            int j=degF-degG; ushort alpha=Gf15Div(f[degF],g[degG]);
            for(int i=0;i<=degG;i++) if(g[i]!=0) f[i+j]^=Gf15Mul(alpha,g[i]);
            int maxBC=degC+j; for(int i=0;i<=degC;i++) if(c[i]!=0) b[i+j]^=Gf15Mul(alpha,c[i]); if(maxBC>degB) degB=maxBC;
            while(degF>0 && f[degF]==0) degF--; while(degB>0 && b[degB]==0) degB--;
        }
    }
    static ushort[] Div(ushort[] a, ushort[] b){ return Mul(a,Inv(b)); }
    static byte[] DumpBytes(ushort[] a){
        byte[] outb=new byte[32]; int wp=0; uint left=8;
        for(int i=0;i<17;i++){
            byte low=(byte)(a[i]&0xff); byte high=(byte)((a[i]>>8)&0x7f);
            if(left==8){ outb[wp++]=low; } else { outb[wp]|=(byte)(low << (int)(8-left)); wp++; outb[wp]=(byte)(low >> (int)left); }
            if(left==8){ outb[wp]=high; left=1; }
            else if(left==7){ outb[wp]|=(byte)(high<<1); wp++; left=8; }
            else { outb[wp]|=(byte)(high << (int)(8-left)); wp++; if(wp<32) outb[wp]=(byte)(high >> (int)left); left=8-(7-left); }
        }
        return outb;
    }
    static Point Infinity(){ return new Point{x=Zero(),y=Zero(),infinity=true}; }
    static Point Double(Point p){ if(p.infinity) return Infinity(); var invX=Inv(p.x); var lam=Add(p.x,Mul(p.y,invX)); var x3=Add(Square(lam),lam); var y3=Add(Add(Square(p.x),Mul(lam,x3)),x3); return new Point{x=x3,y=y3,infinity=false}; }
    static Point AddPoints(Point p, Point q){ if(p.infinity)return q; if(q.infinity)return p; var dx=Add(p.x,q.x); if(IsZero(dx)){ var dy=Add(p.y,q.y); return IsZero(dy)?Double(p):Infinity(); } var dy2=Add(p.y,q.y); var lam=Div(dy2,dx); var x3=Add(Add(Add(Square(lam),lam),p.x),q.x); var y3=Add(Add(Mul(lam,Add(p.x,x3)),x3),p.y); return new Point{x=x3,y=y3,infinity=false}; }
    static Point ScalarMul(Point p, ushort[] k){ var result=Infinity(); for(int limb=14;limb>=0;limb--){ for(int bit=15;bit>=0;bit--){ result=Double(result); if(((k[limb]>>bit)&1)==1) result=AddPoints(result,p); } } return result; }

    static byte[] Sha1(byte[] data){ using(var sha=SHA1.Create()) return sha.ComputeHash(data); }
    static byte[] Sha1OfWords(uint[] words){ byte[] bytes=new byte[words.Length*4]; for(int i=0;i<words.Length;i++){ var le=BitConverter.GetBytes(words[i]); Array.Copy(le,0,bytes,4*i,4); } return Sha1(bytes); }
    static uint BeU32(byte[] b,int off){ return ((uint)b[off]<<24)|((uint)b[off+1]<<16)|((uint)b[off+2]<<8)|b[off+3]; }
    static void PutLeU32(byte[] b,int off,uint v){ b[off]=(byte)v; b[off+1]=(byte)(v>>8); b[off+2]=(byte)(v>>16); b[off+3]=(byte)(v>>24); }

    static ushort[] GeneratePrivateKey(byte[] seed){
        uint[] gen;
        if(seed.Length==0) gen=new uint[]{0xeb3eb781,0x50265329,0xdc5ef4a3,0x6847b9d5,0xcde43b4c};
        else { var d=Sha1(seed); gen=new uint[5]; for(int i=0;i<5;i++) gen[i]=BeU32(d,4*i); }
        var output=new ushort[15];
        for(int i=0;i<15;i++){ uint[] input=new uint[]{(uint)(i+1),gen[0],gen[1],gen[2],gen[3],gen[4]}; var d=Sha1OfWords(input); output[i]=(ushort)(BeU32(d,0)&0xffff); }
        return output;
    }
    static string GeneratePublicKeySm2(string message){
        var priv=GeneratePrivateKey(Encoding.UTF8.GetBytes(message)); var pt=ScalarMul(BASE_POINT,priv);
        var xInt=FromLittleUnsigned(DumpBytes(pt.x)); xInt <<= 1; if((Div(pt.y,pt.x)[0]&1)==1) xInt += 1;
        string hex=ToHex(xInt).PadLeft(64,'0'); return hex.Substring(hex.Length-64);
    }
    static BigInteger HashInteger(byte[] data){ var d=Sha1(data); uint[] all=new uint[10]; for(int i=0;i<5;i++) all[i]=BeU32(d,4*i); uint[] tail={0x0ffd8d43,0xb4e33c7c,0x53461bd1,0x0f27a546,0x1050d90d}; Array.Copy(tail,0,all,5,5); byte[] bytes=new byte[30]; for(int i=0;i<10;i++){ byte[] tmp=BitConverter.GetBytes(all[i]); for(int j=0;j<4 && 4*i+j<30;j++) bytes[4*i+j]=tmp[j]; } return FromLittleUnsigned(bytes); }
    static Tuple<BigInteger,BigInteger> Sign(byte[] data){
        BigInteger hash=HashInteger(data);
        while(true){ byte[] kb=new byte[30]; rng.GetBytes(kb); ushort[] limbs=new ushort[15]; for(int i=0;i<15;i++) limbs[i]=(ushort)(kb[2*i] | (kb[2*i+1]<<8)); BigInteger k=FromLittleUnsigned(kb); if(k.IsZero) continue; var kg=ScalarMul(BASE_POINT,limbs); if(kg.infinity) continue; BigInteger rx=FromLittleUnsigned(DumpBytes(kg.x)); BigInteger r=(rx+hash)%ORDER; if(r.IsZero || r+k==ORDER) continue; BigInteger dr=(PRIVATE_KEY*r)%ORDER; BigInteger s=(k>=dr)?((k-dr)%ORDER):((k+ORDER-dr)%ORDER); if(s.IsZero || BitLen(r)>240 || BitLen(s)>240) continue; return Tuple.Create(r,s); }
    }
    public static string GenerateLicenseText(string username,string licenseType){
        string[] items=new string[4]; string temp=GeneratePublicKeySm2(username); items[3]="60"+temp.Substring(0,48); items[0]=GeneratePublicKeySm2(items[3]); string uid=temp.Substring(48,16)+items[0].Substring(0,4);
        foreach(var pair in new[]{Tuple.Create(1,licenseType),Tuple.Create(2,username+items[0])}){
            while(true){ var sig=Sign(Encoding.UTF8.GetBytes(pair.Item2)); string r=ToHex(sig.Item1).PadLeft(60,'0'); string s=ToHex(sig.Item2).PadLeft(60,'0'); if(r.Length==60 && s.Length==60){ items[pair.Item1]="60"+s+r; break; } }
        }
        uint crc=0xffffffff; UpdateCrc(ref crc, Encoding.UTF8.GetBytes(licenseType)); UpdateCrc(ref crc, Encoding.UTF8.GetBytes(username)); foreach(string it in items) UpdateCrc(ref crc, Encoding.ASCII.GetBytes(it)); uint checksum = crc; // equivalent to !crc32fast::finalize()
        string hexData=String.Format("{0}{1}{2}{3}{4}{5}{6}{7}{8:0000000000}", items[0].Length,items[1].Length,items[2].Length,items[3].Length,items[0],items[1],items[2],items[3],checksum);
        if(hexData.Length%54!=0) throw new Exception("InternalError: The length of register data is not correct.");
        var sb=new StringBuilder(); sb.Append("RAR registration data\r\n").Append(username).Append("\r\n").Append(licenseType).Append("\r\nUID=").Append(uid).Append("\r\n"); for(int i=0;i<hexData.Length;i+=54) sb.Append(hexData.Substring(i,54)).Append("\r\n"); return sb.ToString();
    }

    static uint[] BuildCrcTable(){ var tab=new uint[256]; for(uint i=0;i<256;i++){ uint c=i; for(int j=0;j<8;j++) c=((c&1)!=0)?(0xEDB88320u^(c>>1)):(c>>1); tab[i]=c; } return tab; }
    static void UpdateCrc(ref uint crc, byte[] data){ foreach(byte b in data) crc=CrcTable[(crc^b)&0xff]^(crc>>8); }
    static BigInteger FromLittleUnsigned(byte[] bytes){ byte[] tmp=new byte[bytes.Length+1]; Array.Copy(bytes,tmp,bytes.Length); return new BigInteger(tmp); }
    static BigInteger ParseHex(string hex){ if(hex.Length%2==1) hex="0"+hex; byte[] be=new byte[hex.Length/2]; for(int i=0;i<be.Length;i++) be[i]=Convert.ToByte(hex.Substring(2*i,2),16); Array.Reverse(be); return FromLittleUnsigned(be); }
    static string ToHex(BigInteger v){ if(v.IsZero) return "0"; byte[] le=v.ToByteArray(); int end=le.Length-1; while(end>0 && le[end]==0) end--; var sb=new StringBuilder(); for(int i=end;i>=0;i--) sb.Append(le[i].ToString("x2")); string s=sb.ToString().TrimStart('0'); return s.Length==0?"0":s; }
    static int BitLen(BigInteger v){ if(v.IsZero)return 0; byte[] b=v.ToByteArray(); int i=b.Length-1; while(i>0 && b[i]==0)i--; byte ms=b[i]; int bits=i*8; for(int k=7;k>=0;k--) if(((ms>>k)&1)!=0) return bits+k+1; return 0; }

    public static int Main(string[] args){ string user=args.Length>0?args[0]:"WinRAR"; string lic=args.Length>1?args[1]:"Unlimited Company License"; string outPath=args.Length>2?args[2]:"rarreg.key"; string text=GenerateLicenseText(user,lic); File.WriteAllText(outPath,text,Encoding.ASCII); Console.Write(text); Console.Error.WriteLine("Saved: "+Path.GetFullPath(outPath)); return 0; }
}