文/馬斌仁 范祖清
軟件狗是使用在計(jì)算機(jī)并行口或USB接口上,用于軟件保護(hù)的硬件產(chǎn)品。它是一個(gè)可編程可讀寫具有數(shù)據(jù)存儲(chǔ)區(qū)的設(shè)備。將軟件狗插在計(jì)算機(jī)上,通過相應(yīng)的接口函數(shù)或開發(fā)商工具進(jìn)行訪問。
加密方案分為兩種。一種使用外殼工具,不需對(duì)程序源代碼進(jìn)行改動(dòng),將可執(zhí)行應(yīng)用程序加一個(gè)保護(hù)層。程序開始運(yùn)行和運(yùn)行中會(huì)自動(dòng)訪問軟件狗,若軟件狗不存在,提示錯(cuò)誤且應(yīng)用程序不能運(yùn)行;另一種使用obj、dll、lib等,開發(fā)商提供接口函數(shù)或工具。應(yīng)用時(shí)在源代碼中加入接口函數(shù)對(duì)軟件狗進(jìn)行操作,并編寫加密程序?qū)崿F(xiàn)軟件保護(hù)。
為有效保護(hù)知識(shí)產(chǎn)權(quán),有利于軟件分期控制。使用單機(jī)時(shí)鐘版圣天狗對(duì)單位醫(yī)療設(shè)備應(yīng)用控制程序進(jìn)行加/解密。采用內(nèi)嵌式在源代碼VC++6.0程序中調(diào)用圣天狗接口函數(shù)并編寫程序?qū)λM(jìn)行檢測(cè)和操作。
程序中,調(diào)用接口函數(shù)進(jìn)行操作,圣天狗響應(yīng)該操作并通過API函數(shù)返回?cái)?shù)值。程序中對(duì)返回值進(jìn)行判定并采取相應(yīng)動(dòng)作。若返回值無響應(yīng)或無效,程序終止運(yùn)行或限制部分功能。
由于醫(yī)療產(chǎn)品軟件特殊性,結(jié)合單位產(chǎn)品VC++6.0應(yīng)用控制程序。將圣天狗加/解密分為軟件到期時(shí)間控制、用戶請(qǐng)求和時(shí)間延期代碼升級(jí)三部分。同時(shí),程序通過timer每隔2分鐘調(diào)用一次SFNTGetLicens檢測(cè)圣天狗,防止中途拔出。若被撥出,終止程序使用。
使用圣天狗開發(fā)商工具Sentinel Keys Toolkit,采用保護(hù)策略API特征項(xiàng)string類型(加/解密字符)和AES類型(激活、加密、解密)燒制圣天狗,并經(jīng)編譯形成頭文件。程序源代碼中引用“SentinelKeys.h”和“SentinelKeysLicense.h”;工程設(shè)置的對(duì)象/庫(kù)模塊中加入“SentinelKeyW.lib”。另外,設(shè)計(jì)加/解密字符串為圣天狗唯一ID編號(hào)(00-FF)和控制到期時(shí)間(YYYYMMDD),共十個(gè)字符。
在主程序中,先對(duì)圣天狗初始化,再定義判斷標(biāo)志位、圣天狗狀態(tài)/ID/句柄等。通過SFNTGetLicense接口函數(shù)獲取圣天狗狀態(tài)。返回值為209,驅(qū)動(dòng)程序未安裝;返回值為226,圣天狗不匹配或中途被拔出;返回值為SP_SUCCESS,獲取狀態(tài)成功,反之標(biāo)志位設(shè)為0,應(yīng)用控制程序主要功能被限制。
圖1:到期時(shí)間控制流程圖
圖2:開發(fā)商專用加密程序
獲取狀態(tài)成功后,采用SFNTGetDeviceInfo接口函數(shù)讀取圣天狗基本信息。通過deviceInfo.timeValue獲取內(nèi)部時(shí)鐘,定義年月日類型整形,如device.timeValue.year為內(nèi)部時(shí)鐘年份。通過計(jì)算年份×365+月份×30+日期,時(shí)間參數(shù)為a。
采用SFNTReadString函數(shù),返回值為SP_SUCCESS時(shí),讀取圣天狗存儲(chǔ)區(qū)的字符數(shù)組,再轉(zhuǎn)換成一個(gè)字符串。按照加/解密字符設(shè)計(jì)規(guī)則進(jìn)行字符分離,字符串第1、2位字符為圣天狗ID編號(hào);第3-6位為設(shè)定的到期年份;第7、8位為月份;第9、10位為日期。該字符串中年月日為控制程序到期時(shí)間,且作了加密算法和限制條件,經(jīng)計(jì)算為時(shí)間參數(shù)b。若不滿足條件,則數(shù)據(jù)不合法,標(biāo)志位為0。程序中,比較a和b,若a<=b,標(biāo)志位為2,應(yīng)用控制程序正常運(yùn)行;標(biāo)志位為1或0,程序主要功能被限制或終止運(yùn)行,并提示相應(yīng)信息。到期時(shí)間控制流程圖如圖1所示。
唯一ID編號(hào)和原設(shè)定的軟件到期時(shí)間。
程 序 中,引 用“SentinelKeys.h”和“SentinelKeysLicense.h”。先對(duì)圣天狗初始化,再采用SFNTGetLicense函數(shù)獲取狀態(tài),返回值為SP_SUCCESS時(shí),界面中“請(qǐng)求升級(jí)”按鈕實(shí)現(xiàn)讀取ID編號(hào)和到期時(shí)間(32位16進(jìn)制字符顯示)。
源代碼中,采用SFNTGetDeviceInfo獲取圣天狗基本信息,將deviceInfo.devSN唯一ID編號(hào)轉(zhuǎn)換成十六進(jìn)制字符,若長(zhǎng)度不足2位加0補(bǔ)位。另外,通過SFNTReadString函數(shù)讀取圣天狗內(nèi)部字符數(shù)組,經(jīng)處理變成一個(gè)字符串。按照YYYYMMDD格式分離出年月日,程序自動(dòng)檢查數(shù)據(jù)合法性。然后將ID編號(hào)和YYYYMMDD組合成一個(gè)字符串,再變成無符號(hào)的字符數(shù)組。接著采用指針方式寫入plainBuffer[]數(shù)組,程序中使用SFNTEncrypt函數(shù)加密。最后將返回值clipherBuffer[]數(shù)組轉(zhuǎn)換成16進(jìn)制,若不足兩位補(bǔ)位,即形成32位字符的用戶請(qǐng)求代碼。
為便于開發(fā)商重寫加/解密字符,對(duì)用戶圣天狗進(jìn)行確認(rèn)。用戶請(qǐng)求為32位16進(jìn)制字符串代碼,僅通過開發(fā)商專用程序獲取圣天狗
開發(fā)商采用專用加密程序,將圣天狗唯一ID編號(hào)和控制軟件下一個(gè)到期時(shí)間兩段數(shù)據(jù)拼接在一起,使用SFNTEncrypt接口函數(shù)將拼接的字符串進(jìn)行加密。由clipherBuffer[]數(shù)組生成32位16進(jìn)制字符串即為時(shí)間延期升級(jí)代碼。如圖2所示。
代碼升級(jí)的程序中,先將圣天狗初始化,將32位16進(jìn)制字符串輸入至文本框中,點(diǎn)擊“驗(yàn)證”按鈕,字符串轉(zhuǎn)換成大寫并去除所有空格,再檢查字符串長(zhǎng)度和每個(gè)字符ASC碼在48至57或65至70范圍內(nèi)。若滿足條件,時(shí)間延期代碼合法。
點(diǎn)擊“代碼升級(jí)”按鈕,程序?qū)戏ㄗ址績(jī)晌蛔址来畏蛛x成字符數(shù)組,并將16進(jìn)制轉(zhuǎn)換成字符型。采用SFNTDecrypt函數(shù)解密,將plainBuffer[]字符數(shù)組組合成一個(gè)字符串即為ID編號(hào)和預(yù)置控制軟件到期時(shí)間YYYYMMDD。程序自動(dòng)完成對(duì)字符串的拆分和數(shù)據(jù)合法性判斷。另外,通過SFNTGetDeviceInfo函數(shù)獲取圣天狗ID,與字符串中的ID比較。若匹配,采用SFNTWriteString函數(shù)將字符串YYYYMMDD(年月日)重新寫入圣天狗內(nèi)部?jī)?chǔ)存器中,存儲(chǔ)區(qū)內(nèi)部字符更新;若不匹配,代碼升級(jí)無效。
單機(jī)時(shí)鐘版圣天狗是一種智能型軟件保護(hù)工具,采用公鑰和128位AES保護(hù),自身配置電池有源時(shí)鐘,不依賴計(jì)算機(jī)系統(tǒng)時(shí)間,給我們提供了靈活的加密方案。通過提供的開發(fā)工具和文檔,操作圣天狗并將算法和限制條件融入到VC++6.0應(yīng)用控制程序中,實(shí)現(xiàn)不同代碼控制程序運(yùn)行時(shí)間和功能模塊限制,有利于軟件分期控制。
目前,市場(chǎng)上獨(dú)立的硬加密出現(xiàn)已有多年,方案很多,屬于較成熟技術(shù)。本文僅針對(duì)適合我單位產(chǎn)品軟件的簡(jiǎn)單加密,后續(xù)根據(jù)需求,可考慮時(shí)間、執(zhí)行次數(shù)和固定失效時(shí)間及外殼等多重加/解密方式。