给软件加验证

要实现软件注册功能,首先需要知道实现注册机制要涉及到的几个问题:1、如何加入注册检测,判断软件是否注册;2、如何生成注册码,如何保证一个用户名只生成与之唯一对应的注册码;3、在软件不注册情况下,如何限制软件功能的局限性;4、对已经负费使用用户而言,不应造成使用不便。

 

首先,应该有一个生成注册码的算法,以下是我简单的一个生成15位注册码的算法:

//该函数返回一个CSTRING类型的15位注册码,入口参数为用户名

CString GetRegPasswd(CString &DirName)

{

//将用户名换算成15位注册码

long Num1,Num2,Num3;

 

char sn[16]={0};

CString p;

int i,len;

 

Num1=0;

Num2=0;

Num3=0;

 

len=int(strlen(DirName));

if(len!=0)

{

for( i=1;i<=len;i++)

{

//第一步算法

Num1=(long(Num1+(int(DirName[i-1])*i*i)*(i*sqrt(DirName[i-1])+1)))%100000;

//第二步算法

Num2=(Num2*i+(long(pow((int)DirName[i-1],2)*i)))%100000;

//第三步算法

Num3=(Num2+(long)sqrt(Num1))%100000;

}

//以下把三个算法结果分别生成5个字符,共有15个

for(i=0;i<5;i++)

sn[i]=(int)(Num1+31+i*i*i)%128;

for(i=5;i<10;i++)

sn[i]=(int)(Num2+31+i*i*i)%128;

for(i=10;i<15;i++)

sn[i]=(int)(Num3+31+i*i*i)%128;

sn[15]=0;

//以下循环把所有生成的字符转换为0---9,A---Z,a----z

for(i=0;i<15;i++)

{

while((sn[i]<'0' || sn[i]>'9') && (sn[i]<'A' || sn[i]>'Z') &&(sn[i]<'a' || sn[i]>'z') )

{

sn[i]=(sn[i]+31+7*i)%128;

}

}

//赋值给一个CSTRING变量,用做函数返回值

p.Format("%s",sn);

}

return p;

}

//检查软件是否注册的函数

 

BOOL GetRegFlag(void)

{

HKEY hKey = NULL;

BYTE i;

 

CString str;

str.LoadString(IDS_REG_KEY);// IDS_REG_KEY为在注册表中的子目录字符串

 

if (RegCreateKey(HKEY_CURRENT_USER, str, &hKey) != ERROR_SUCCESS) return false;

 

DWORD cbA;

cbA=sizeof(int);

if( RegQueryValueEx(hKey, "SzMima",NULL,NULL, &i,&cbA) != ERROR_SUCCESS)

return false;

 

BYTE j=i;

if(j==0)//0代表软件已经注册,可以正常使用

{

RegCloseKey(hKey);

return true;

}

else

{

RegCloseKey(hKey);

return false;

}

 

return false;

};

//设置软件已经注册标志的函数

 

BOOL SetRegFlag(void)

{

HKEY hKey = NULL;

BYTE i;

 

CString str;

str.LoadString(IDS_REG_KEY);// IDS_REG_KEY为在注册表中的子目录字符串

 

if (RegCreateKey(HKEY_CURRENT_USER, str, &hKey) != ERROR_SUCCESS) return false;

 

BYTE j=0;//0代表已经注册

if(RegSetValueEx(hKey, "SzMima", 0, REG_BINARY, &j,4) != ERROR_SUCCESS)

{

AfxMessageBox("设置注册表数据失败!");

return FALSE;

}

return false;

};

以上三个函数即可实现软件注册机制,只需要在程序初始化的时候加入以下几句代码即可

BOOL bReg= GetRegFlag ();

if(!bReg)

{

//在此加入限制功能或者拒绝是使用的代码

}

如果用户注册只需要加入以下代码即可

//这是我的程序中的一个注册界面,输入用户名和注册码提交后检验注册码是否正确的代码

void CRegEdit::OnBnClickedOk()

{

if(!UpdateData()) return;//取得编辑框的内容,并赋值到类变量中

 

m_RegUser.TrimLeft();//m_RegUser是用户名

m_RegUser.TrimRight();

if(m_RegUser.IsEmpty())

{

AfxMessageBox("用户名不能为空,请重新输入。");

GetDlgItem(IDC_REGUSER)->SetFocus();

return;

}

m_RegPasswd.TrimLeft();m_RegPasswd是注册码

m_RegPasswd.TrimRight();

if(m_RegPasswd.IsEmpty())

{

AfxMessageBox("注册码不能为空,请重新输入。");

GetDlgItem(IDC_REGPASSWD)->SetFocus();

return;

}

CString Passwd;

Passwd=GetRegPasswd(m_RegUser);//调用算法取得该用户名的注册码

if(Passwd==m_RegPasswd)//与用户输入的注册进行比较

{

SetRegFlag();//设置注册标志

OnOK();

}

else

AfxMessageBox("注册码错误,请重新输入。");

UpdateData(false);

}

 

RSA做软件的注册功能,如果密钥设置的比较大位数的话,基本别人是无法写出注册机的,但是防止别人暴破你的程序又是另一回事了。

Imports System.Security.Cryptography

Imports System.Text

Imports System.IO

Imports System.Xml

 

Public Class FrmReg

    Inherits System.Windows.Forms.Form

 

    'Dim xmlKeys As String 'A combination of both the public and     'private keys 

    'Dim xmlPublicKey As String 'The public key only

    ''The plaintext message in a byte array

    'Dim PlainTextBArray As Byte()

    ''The cyphertext message in a byte array

    'Dim CypherTextBArray As Byte()

 

#Region " Windows 窗体设计器生成的代码 "

 

    Public Sub New()

        MyBase.New()

 

        '该调用是 Windows 窗体设计器所必需的。

        InitializeComponent()

 

        '在 InitializeComponent() 调用之后添加任何初始化

 

    End Sub

 

    '窗体重写 dispose 以清理组件列表。

    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

        If disposing Then

            If Not (components Is Nothing) Then

                components.Dispose()

            End If

        End If

        MyBase.Dispose(disposing)

    End Sub

 

    'Windows 窗体设计器所必需的

    Private components As System.ComponentModel.IContainer

 

    '注意: 以下过程是 Windows 窗体设计器所必需的

    '可以使用 Windows 窗体设计器修改此过程。

    '不要使用代码编辑器修改它。

    Friend WithEvents btnReg As System.Windows.Forms.Button

    Friend WithEvents btnexit As System.Windows.Forms.Button

    Friend WithEvents Label1 As System.Windows.Forms.Label

    Friend WithEvents Label2 As System.Windows.Forms.Label

    Friend WithEvents txtRegCode As System.Windows.Forms.TextBox

    Friend WithEvents txtRegName As System.Windows.Forms.TextBox

    Friend WithEvents LinkLabel1 As System.Windows.Forms.LinkLabel

     Private Sub InitializeComponent()

        Me.btnReg = New System.Windows.Forms.Button

        Me.btnexit = New System.Windows.Forms.Button

        Me.txtRegName = New System.Windows.Forms.TextBox

        Me.Label1 = New System.Windows.Forms.Label

        Me.Label2 = New System.Windows.Forms.Label

        Me.txtRegCode = New System.Windows.Forms.TextBox

        Me.LinkLabel1 = New System.Windows.Forms.LinkLabel

        Me.SuspendLayout()

        '

        'btnReg

        '

        Me.btnReg.FlatStyle = System.Windows.Forms.FlatStyle.Flat

        Me.btnReg.Location = New System.Drawing.Point(64, 192)

        Me.btnReg.Name = "btnReg"

        Me.btnReg.Size = New System.Drawing.Size(75, 24)

        Me.btnReg.TabIndex = 0

        Me.btnReg.Text = "注册(&R)"

        '

        'btnexit

        '

        Me.btnexit.FlatStyle = System.Windows.Forms.FlatStyle.Flat

        Me.btnexit.Location = New System.Drawing.Point(168, 192)

        Me.btnexit.Name = "btnexit"

        Me.btnexit.Size = New System.Drawing.Size(75, 24)

        Me.btnexit.TabIndex = 1

        Me.btnexit.Text = "取消(&C)"

        '

        'txtRegName

        '

        Me.txtRegName.Location = New System.Drawing.Point(8, 24)

        Me.txtRegName.Name = "txtRegName"

        Me.txtRegName.Size = New System.Drawing.Size(296, 21)

        Me.txtRegName.TabIndex = 2

        Me.txtRegName.Text = ""

        '

        'Label1

        '

        Me.Label1.Location = New System.Drawing.Point(8, 0)

        Me.Label1.Name = "Label1"

        Me.Label1.Size = New System.Drawing.Size(48, 16)

        Me.Label1.TabIndex = 3

        Me.Label1.Text = "注册名:"

        '

        'Label2

        '

        Me.Label2.Location = New System.Drawing.Point(8, 56)

        Me.Label2.Name = "Label2"

        Me.Label2.Size = New System.Drawing.Size(56, 16)

        Me.Label2.TabIndex = 4

        Me.Label2.Text = "注册码:"

        '

        'txtRegCode

        '

        Me.txtRegCode.Location = New System.Drawing.Point(8, 80)

        Me.txtRegCode.Multiline = True

        Me.txtRegCode.Name = "txtRegCode"

        Me.txtRegCode.Size = New System.Drawing.Size(296, 104)

        Me.txtRegCode.TabIndex = 5

        Me.txtRegCode.Text = ""

        '

        'LinkLabel1

        '

        Me.LinkLabel1.Location = New System.Drawing.Point(128, 56)

        Me.LinkLabel1.Name = "LinkLabel1"

        Me.LinkLabel1.Size = New System.Drawing.Size(128, 16)

        Me.LinkLabel1.TabIndex = 6

        Me.LinkLabel1.TabStop = True

        Me.LinkLabel1.Text = "http://Testbug.Net"

        '

        'FrmReg

        '

        Me.AutoScaleBaseSize = New System.Drawing.Size(6, 14)

        Me.ClientSize = New System.Drawing.Size(306, 223)

        Me.Controls.Add(Me.LinkLabel1)

        Me.Controls.Add(Me.txtRegCode)

        Me.Controls.Add(Me.txtRegName)

        Me.Controls.Add(Me.Label2)

        Me.Controls.Add(Me.Label1)

        Me.Controls.Add(Me.btnexit)

        Me.Controls.Add(Me.btnReg)

        Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle

        Me.MaximizeBox = False

        Me.Name = "FrmReg"

        Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen

        Me.Text = "RSA&MD5注册例子程序 by www.TestBug.net"

        Me.TopMost = True

        Me.ResumeLayout(False)

 

    End Sub

 

#End Region

 

    Private Sub btnexit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnexit.Click

        Application.Exit()

    End Sub

 

    Private Sub btnReg_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReg.Click

        If txtRegName.Text = "" Then

            MessageBox.Show("注册名不能为空", "提示")

            Return

        Else

            If txtRegCode.Text = "" Then

                MessageBox.Show("注册码不能为空", "提示")

                Return

            Else

                If txtRegCode.Text.Length <> 172 Then

                    MessageBox.Show("注册码长度不对", "提示")

                    Return

                End If

            End If

        End If

        Try

            Dim RSA As System.Security.Cryptography.RSACryptoServiceProvider = New System.Security.Cryptography.RSACryptoServiceProvider

            '公钥

            RSA.FromXmlString("xzALwAOqEcj8jWrKXyaecAhyz9W+wH26K8ZcMv9ZFYDJeR5jMhK7AhNbwn+q1mAH7VV146v6S2SlJeErEvTXS3dJR0pjaED0R2JSf0FwrWP6CDsKREQC803E+Faaw/Kou134K6mejPg16dxYfcIlJgoWRqn58qnjo6g87XlUMUs=AQAB")

            Dim RSADeformatter As System.Security.Cryptography.RSAPKCS1SignatureDeformatter = New System.Security.Cryptography.RSAPKCS1SignatureDeformatter(RSA)

            '指定解密的时候HASH算法为MD5

            RSADeformatter.SetHashAlgorithm("MD5")

            Dim Regcode As Byte() = Convert.FromBase64String(txtRegCode.Text)

            Dim RegName As Byte() = (New System.Text.ASCIIEncoding).GetBytes(txtRegName.Text)

            Dim dataToHash As Byte() = (New System.Text.ASCIIEncoding).GetBytes(txtRegName.Text)

            Dim hash As Byte() = CType(System.Security.Cryptography.CryptoConfig.CreateFromName("MD5"), System.Security.Cryptography.HashAlgorithm).ComputeHash(dataToHash)

            '验证签名

            If RSADeformatter.VerifySignature(hash, Regcode) Then

                '注册通过的话就写入注册文件

                Dim textWriter As XmlTextWriter = New XmlTextWriter("reg.xml", Nothing)

                textWriter.WriteStartElement("RegInfo")

                textWriter.WriteStartElement("RegName")

                textWriter.WriteString(txtRegName.Text)

                textWriter.WriteEndElement()

                textWriter.WriteStartElement("RegCode")

                textWriter.WriteString(txtRegCode.Text)

                textWriter.WriteEndElement()

                textWriter.Close()

                MessageBox.Show("注册正确,谢谢注册本软件,请重新启动程序完成注册", "提示")

                Application.Exit()

            Else

                MessageBox.Show("错误的注册码", "提示")

            End If

        Catch ex As Exception

            'MessageBox.Show(ex.Message())

            MessageBox.Show("错误的注册码", "提示")

        End Try

    End Sub

 

    Private Sub FrmReg_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed

        Application.Exit()

    End Sub

 

    Private Sub LinkLabel1_LinkClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles LinkLabel1.LinkClicked

        System.Diagnostics.Process.Start("http://testbug.net")

    End Sub

End Class

参考资料:http://www.sowto.com/Article/cxsj/200602/Article_5362.html

 

posted on 2011-11-04 15:03  IT小小小鸟  阅读(746)  评论(0编辑  收藏  举报