程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> vc教程 >> 利用硬件信息實現共享軟件的安全注冊

利用硬件信息實現共享軟件的安全注冊

編輯:vc教程

  一、 引言

  但現有共享軟件的許多注冊方法是存在漏洞的,不少破解網站通過正常渠道購買回一個注冊碼之後將其公布在其網站之上,更有甚者還提供生成注冊碼的注冊機。以上的行為侵犯了軟件開發者的知識產權,干擾了共享軟件的正常發布。雖然國家也有保知識產權的相關法律條文,但顯然在執行起來存在一定的難度。因此作為程序員的軟件開發者應當具有自我保護意識,利用自己的專業特長,通過程序控制來確保自己的每一個注冊碼只對於一個軟件拷貝。本文將根據筆者的實際編程經驗,結合物理硬件信息的安全的注冊方法實現過程進行較全面的介紹。

  二、 注冊源的采集

  為了確保注冊碼的唯一性,在注冊源的采集上應當盡量選取一些唯一的、不易復制的軟、硬件信息作為原始信息。硬件由於其不可復制性和物理唯一性成為了我們的首選目標,而且多數計算機配件在出廠時都有一個唯一的標識號,可以將其作為識別的依據。符合上述條件的標識號大致有硬盤的序列號、網卡的序列號、BIOS中的主版序列號或出廠日期和標志等幾種,考慮到硬件通用性、實現起來的難易程度以及系統安全性等多種因素以硬盤序列號為佳,因網卡雖說唯一性最好但不能保證每台計算機都裝有網卡,而ROM BiOS中F000H-FFFFH區域雖存有與硬件配置有關的信、F000H:FFF5H-F000H:FFFFH存有主機出廠日期和主機標志值等參數,但在Windows 9x的保護模式下編程實現是比較困難的。雖然在Windows 9x保護模式下對硬盤序列號也不能按通常在DOS模式下的通過硬盤端口1F6H和1F7H直接讀取,但Windows API函數中提供的下面這個函數可以非常簡單的獲取到指定磁盤驅動器的序列號:

GetVolumeInformation("C:\",NULL,NULL,&dwIDESerial,NULL,NULL,NULL,NULL);

  第一個參數設為"C:\"表示我們要讀取C盤驅動器的序列號。之所以選C盤,是因為我們不能保證用戶有多個分區,而C盤卻是每一個用戶都具有的。該函數成功調用完畢後,在DWord型的變量dwIDESerial中就存儲了獲取到的32位長的磁盤序列號。注冊信息采集到後,關鍵的問題就是如何讓用戶將其返回給開發者。一種較簡單的方法是把采集到的硬盤序列號與用戶輸入的注冊名經過位操作的簡單加密後存放到一個文本中通過郵件傳送給開發者。

  三、 注冊機的設計

  開發人員得到從用戶返回的由硬盤序列號構成的注冊原始信息後就要利用注冊機生成注冊碼並反饋給用戶。一般說,注冊機要利用既定的位操作和不可逆算法,生成用戶比較容易操作的字符串注冊碼。在用戶方面的共享軟件裡也有一個具有相同算法的注冊機用以動態計算以當前注冊名進行注冊的正確的注冊碼,然後對用戶輸入的注冊碼進行檢測,如果不匹配則不予注冊。如果是從開發者反饋來的正確注冊碼,則通過標記配置文件或是往注冊表中寫入特定內容鍵值以表明當前軟件是經過注冊的。而且共享軟件在每次運行時都要對用戶注冊碼進行實時檢測與判斷,這樣才能實注冊限制功能。如果應用程序被拷貝到其他計算機上則會由於硬盤序列號的改變而導致注冊信息的不匹配,因此仍然要重新注冊,從而達到共享軟件的發布目的。下面就是一段非常簡單的注冊機實現代碼:

  開發者方:

//strSerial是由用戶返回的同注冊名進行過位運算的注冊源信息
::strcpy(buf1,strSerial);
::strcpy(buf2,strName);
//再次進行位運算,取得硬盤序列號
for(int I=0;I<8;I++)
input[I]=buf1[I]^buf2[I];
//錯序與位操作,產生與注冊名有關的注冊碼
int Index[8]={7,5,3,1,6,4,2,0};
char Mask[8]={'Z','H','U','C','E','J','I','0'};
for(I=0;I<8;I++)
{
result[I]=input[Index[I]]^buf2[I];
result[I]=result[I]^Mask[I];
}
……

  用戶方:

//根據輸入的字串計算出硬盤序列號
int Index[8]={7,5,3,1,6,4,2,0};
char Mask[8]={'Z','H','U','C','E','J','I','0'};
for(int I=0;I<8;I++)
{
input[I]=input[I]^buf2[I];
ouput[Index[I]]=input[I]^Mask[I];
}
dwSerialID=::atoll(output);//將序列號恢復成數值
//動態提取硬盤序列號
GetVolumeInformation("C:\",NULL,NULL,&dwIDESerial,NULL,NULL,NULL,NULL);
If(dwSerialID==dwIDESerial)
{
……//注冊成功
}
else
{
……//注冊失敗
}

  以上兩段代碼僅用於舉例說明實現的方法,並未進行復雜的邏輯運算,在實際應用中應視共享軟件的自身價值、軟件實現的復雜程度等多種因素來決定采取多大的加密深度。即使對於一般的注冊機也應加以2層以上的函數邏輯運算。對於共享軟件,不管其實現何種功能,最好采取在線注冊的方式,而且在同一個軟件系統中應有若干個注冊入口,只要一處注冊成功整個軟件就算注冊成功了。為了清晰的了解整個注冊過程,流程圖可以大致如下,並可根據具體做適當的調整:

  小結:本文主要對共享軟件的安全注冊進行了討論。為了更方便、安全地實現對共享軟件的注冊可以大致遵循這樣幾個原則:選准注冊源、經常變動注冊算法、加密注冊碼、管理好注冊機防止外流、采用在線式的注冊方法。以上所述基本筆者自己的實際經驗總結

  1. 上一頁:
  2. 下一頁:
欄目導航
Copyright © 程式師世界 All Rights Reserved