• python实现软件的注册功能(机器码+注册码机制)


    一、前言:
    目的:完成已有python图像处理工具的注册功能
    功能:用户运行程序后,通过文件自动检测认证状态,如果未经认证,就需要注册。注册过程是用户将程序运行后显示的机器码(C盘的卷序号)发回给管理员,管理员对机器码加密后生成加密文件或字符串返回给用户。每次启动程序,在有注册文件的情况下,程序就会通过DES和base64解码,并与此刻获取到的C盘卷序列号比对,如果一致则运行主程序。如果注册文件解码后与卷序号不一致,就要提醒用户输入注册码,如果对新输入的解码后和重新获取的机器码一致,则通过认证,生成新的注册文件后进入主程序。
    库和组件:
    1、pyDes用于加密解密
    2、base64,用于pyDes加密解密后的二次加密解密
    3、win32api,用于获取C盘卷序列号
    4、pyinstaller,打包
    参考:
    1、pyDes库 实现python的des加密
    2、win32api.GetVolumeInformation
    3、pyinstaller打包文件说明
     
    二、实现
    #coding:utf8
    #register.py
    #功能说明:用户运行程序后,自动检测认证状态,如果未经认证,就需要注册。注册过程是用户将程序运行后显示的机器码(卷序号)发回给管理员,管理员通过加密后生成加密文件或字符串给回用户。
    #每次登录,在有注册文件或者注册码的情况下,软件就会通过DES和base64解码,如果解码后和重新获取的机器码一致,则通过认证,进入主程序。
    
    import base64
    import win32api
    from pyDes import *
    #from binascii import a2b_hex    #如果需要用二进制编码保存注册码和注册文件可以使用binascii转换
    
    class register:
        def __init__(self):
            self.Des_Key = "BHC#@*UM" # Key
            self.Des_IV = "x22x33x35x81xBCx38x5AxE7" # 自定IV向量
        
        #获取C盘卷序列号
        #使用C盘卷序列号的优点是长度短,方便操作,比如1513085707,但是对C盘进行格式化或重装电脑等操作会影响C盘卷序列号。
        #win32api.GetVolumeInformation(Volume Name, Volume Serial Number, Maximum Component Length of a file name, Sys Flags, File System Name)
        #return('', 1513085707, 255, 65470719, 'NTFS'),volume serial number is  1513085707.
        def getCVolumeSerialNumber(self):
            CVolumeSerialNumber=win32api.GetVolumeInformation("C:\")[1]
            #print chardet.detect(str(CVolumeSerialNumber))
            #print CVolumeSerialNumber
            if CVolumeSerialNumber:
                return str(CVolumeSerialNumber) #number is long type,has to be changed to str for comparing to content after.
            else:
                return 0
    
        #使用DES加base64的形式加密
        #考虑过使用M2Crypto和rsa,但是都因为在windows环境中糟糕的安装配置过程而放弃
        def DesEncrypt(self,str):
            k = des(self.Des_Key, CBC, self.Des_IV, pad=None, padmode=PAD_PKCS5)
            EncryptStr = k.encrypt(str)
            #EncryptStr = binascii.unhexlify(k.encrypt(str))
            return base64.b64encode(EncryptStr) #转base64编码返回
        
        #des解码
        def DesDecrypt(self,str):
            k = des(self.Des_Key, CBC, self.Des_IV, pad=None, padmode=PAD_PKCS5)
            DecryptStr = k.decrypt(str)
            #DecryptStr = a2b_hex(k.decrypt(str))
            print DecryptStr
            return DecryptStr
        
        #获取注册码,验证成功后生成注册文件
        def regist(self):
            key = raw_input('please input your register code: ')
            #由于输入类似“12”这种不符合base64规则的字符串会引起异常,所以需要增加输入判断
            #while key
            if key:
                content = self.getCVolumeSerialNumber()    //number has been changed to str type after use str() 
                #print chardet.detect(content)
                #print type(content)
                #print content
                #type(key_decrypted) is str
                key_decrypted=str(self.DesDecrypt(base64.b64decode(key)))
                #print chardet.detect(key_decrypted)
                #print key_decrypted
                #type(key_decrypted) is str
                if content!=0 and key_decrypted!=0:
                    if content != key_decrypted:
                        print "wrong register code, please check and input your register code again:"
                        self.regist()
                    elif content==key_decrypted:
                        print "register succeed."
                        #读写文件要加判断
                        with open('./register','w') as f:
                            f.write(key)
                            f.close()
                        return True
                    else:
                        return False
                else:
                    return False
            else:
                self.regist()
            return False
    
        def checkAuthored(self):
            content=self.getCVolumeSerialNumber()
            checkAuthoredResult = 0
            #读写文件要加判断
            try:
                f=open('./register','r')
                if f:
                        key=f.read()
                        if key:
                            key_decrypted=self.DesDecrypt(base64.b64decode(key))
                            if key_decrypted:
                                if key_decrypted == content:
                                    checkAuthoredResult = 1
                                else:
                                    checkAuthoredResult = -1
                            else:
                                checkAuthoredResult = -2
                        else:
                            checkAuthoredResult = -3
                else:
                    self.regist()
            except IOError:
                print IOError
            print checkAuthoredResult
            return checkAuthoredResult
    
    
    if __name__ == '__main__':
        reg=register()
        reg.regist()
     
    三、备注
    1、使用C盘卷序列号而不是硬盘号的原因是:位数短,方便操作。
    但是使用硬盘号才是更安全的做法,因为硬盘号不会因重装系统、格式化C盘或修改C盘序号而改变。
    #CVolumeSerialNumber: 1513085707
    #after encryption: ro5RVXZoP0KmnogYDeepUg==
    #the HardDiskNumber: 32535332584e4741343536393237204620202020
    #after encryption: MzI1MzUzMzI1ODRlNDc0MTM0MzUzNjM5MzIzNzIwNDYyMDIwMjAyMA==
    2、除了win32api,wmi也可以用来获取系统信息(比如硬盘号),获取完整硬盘号的过程如下:
    #虽然使用wmi可以获取磁盘序列号,可是磁盘序列号是3253533258**************3237204620202020,加密后太长,不方便操作,所以弃置
    import wmi
    def getHardDiskNumber(self):
        c = wmi.WMI()
        for physical_disk in c.Win32_DiskDrive():
        return physical_disk.SerialNumber
    https://pypi.python.org/pypi/WMI/
    3、chardet可以用来检验字符串的编码类型,可以用在检测字符串相等上
    chardet.detect(str)
    4、还存在一些逻辑上的漏洞,比如读写文件时对文件是否存在的判断,读取方式的选择等
    5、register.py,供main函数或其他需要获取认证状态的函数调用。
    main函数中使用register类的过程是:
    创建logIn函数用于获取认证结果-》如果认证结果为假则重新调用register类的regist函数,提醒用户输入注册码,只有成功输入了注册码才能创建新的注册文件-》如果认证结果为真则直接启动主程序。
    6、管理员还应该有一个encryption.py,用于使用des+base64算法对用户发过来的C盘卷序列号进行加密,加密以后生成字符串或注册文件,再返还给用户,不再赘述。

    转载请注明出处:

    http://www.cnblogs.com/cquptzzq/

  • 相关阅读:
    lix
    docker-desktop: error during connect
    安装Docker Desktop报错WSL 2 installation is incomplete.
    索引二倒排索引和正排索引
    公众号资料分享
    docker使用物理机gpu运行模型
    使用arthas定位java问题
    pytorch设置gpu
    pytorch模型初始化
    【转】OpenGL图形渲染管线、VBO、VAO、EBO、 TBO概念及用例
  • 原文地址:https://www.cnblogs.com/cquptzzq/p/5940583.html
Copyright © 2020-2023  润新知