1. 程式人生 > >軟體註冊碼功能的實現

軟體註冊碼功能的實現

版權宣告

最近很多爬蟲來我部落格爬文章,轉載可以,但請保留原文出處及版權宣告,即便是在中國

單純的廣告

個人部落格:https://aodeng.cc
微信公眾號:低調小熊貓
QQ群:756796932

簡介

最近公司專案需要新增這個功能,聽到軟體註冊碼,我的第一反應就是破解,例如idea破解到2099年之類的(這年頭誰花錢用正版啊),其實我聽到這個功能需求是一臉懵逼的,因為我壓根沒搞過這玩意,只能到處查資料了,所幸功能還是搞出來了,苦逼的我,不bb了,寫這篇文章就當加深印象了,也方便自己以後copy,最近越來越忙了,都沒啥時間出來裝逼了:(

使用

我們先看一下執行效果圖,即便賬號密碼正確,也進不了系統,這樣別人使用我們公司的產品,就需要購買我們公司提供的註冊碼,才能使用了,還是很nice的功能呢
file

首先介紹一個註解,這個註解在這個功能實現裡面很重要了
@PostConstruct

PostConstruct 註釋用於在依賴關係注入完成之後需要執行的方法上,以執行任何初始化。此方法必須在將類放入服務之前呼叫。支援依賴關係注入的所有類都必須支援此註釋。即使類沒有請求注入任何資源,用 PostConstruct 註釋的方法也必須被呼叫。只有一個方法可以用此註釋進行註釋。應用 PostConstruct 註釋的方法必須遵守以下所有標準:該方法不得有任何引數,除非是在 EJB 攔截器 (interceptor) 的情況下,根據 EJB 規範的定義,在這種情況下它將帶有一個 InvocationContext 物件 ;該方法的返回型別必須為 void;該方法不得丟擲已檢查異常;應用 PostConstruct 的方法可以是 public、protected、package private 或 private;除了應用程式客戶端之外,該方法不能是 static;該方法可以是 final;如果該方法丟擲未檢查異常,那麼不得將類放入服務中,除非是能夠處理異常並可從中恢復的 EJB。

1.serviceimpl實現類程式碼(這裡是最重要的程式碼了)

@PostConstruct
    public void initAppRegedit() throws Exception {
        String classpath = this.getClass().getResource("/").getPath();
        File file = new File(classpath+"conf/config.properties");
        String macInfo = getMacInfo();
        if(file.exists()) {
            List<String> readLines = IOUtils.readLines(new FileInputStream(file), "utf-8");
            if(null!=readLines&&readLines.size()>0) {
                String key = readLines.get(0);
                String t = EncryptUtil.getInstance().DESdecode(key);
                if(StringUtils.equals(t, macInfo)) {
                    Const.APP_REGEDIT = true;
                }
            }
        }
        if(!Const.APP_REGEDIT) {
            List<String> lines = new ArrayList<>();
            lines.add(EncryptUtil.getInstance().DESencode(EncryptUtil.getInstance().DESencode(macInfo)));
            File outFile = new File(classpath+"conf/regedit.properties");
            IOUtils.writeLines(lines, "", new FileOutputStream(outFile), "utf-8");
        }
    }
    public static String getMacInfo() {
        String address = "";
        String os = System.getProperty("os.name");
        if (os != null && os.startsWith("Windows")) {
            try {
                String command = "cmd.exe /c ipconfig /all";
                Process p = Runtime.getRuntime().exec(command);
                BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
                String line;
                while ((line = br.readLine()) != null) {
                    if (line.indexOf("Physical Address") > 0||line.indexOf("實體地址") > 0) {
                        int index = line.indexOf(":");
                        index += 2;
                        address = line.substring(index);
                        break;
                    }
                }
                br.close();
            } catch (IOException e) {
                System.out.println("Error:" + e);
            }
        }
        return  address.trim();
    }

2.建立資原始檔
file

3.我們在登入之前新增驗證

if(!Const.APP_REGEDIT) {
            throw new InvalidRequestException(ErrorCodes.appRegeditFailed);
        }

Const是我們自定義的常量

public static boolean APP_REGEDIT = false;

ErrorCodes是我們自定義的異常

/**登入異常**/
public static String appRegeditFailed;

登入頁面新增提示資訊,這些都很簡單,我就不貼程式碼了

4.建立加密工具包EncryptUtil

public static void main(String args[]){
        String regedit_key = "";
        System.out.println("密碼:"+regedit_key);
        regedit_key = EncryptUtil.getInstance().DESdecode(regedit_key);
        System.out.println("註冊碼:"+regedit_key);
    }

這段程式碼就是將我們的密碼加密,變成註冊碼,加密方式我採用的雙向加密:DES、AES,程式碼就不貼了,百度一堆

5.執行專案之後class裡面會生成兩個檔案
file

6.使用方式
專案啟動後拷貝class/conf/regedit.properties內容到EncryptUtil中main中執行,後把註冊碼拷貝到class/conf/config.properties中即可

這樣軟體的註冊碼功能就實現了