• python 加密与解密


    加密算法分类

    对称加密算法:

    对称加密采用了对称密码编码技术,它的特点是文件加密和解密使用相同的密钥

    发送方和接收方需要持有同一把密钥,发送消息和接收消息均使用该密钥。

    相对于非对称加密,对称加密具有更高的加解密速度,但双方都需要事先知道密钥,密钥在传输过程中可能会被窃取,因此安全性没有非对称加密高。

    常见的对称加密算法:DES,AES,3DES等等

    非对称加密算法:

    文件加密需要公开密钥(publickey)和私有密钥(privatekey)。

    接收方在发送消息前需要事先生成公钥和私钥,然后将公钥发送给发送方。发送放收到公钥后,将待发送数据用公钥加密,发送给接收方。接收到收到数据后,用私钥解密。

    在这个过程中,公钥负责加密,私钥负责解密,数据在传输过程中即使被截获,攻击者由于没有私钥,因此也无法破解。

    非对称加密算法的加解密速度低于对称加密算法,但是安全性更高

    非对称加密算法:RSA、DSA、ECC等算法

    消息摘要算法:

    消息摘要算法可以验证信息是否被篡改。

    在数据发送前,首先使用消息摘要算法生成该数据的签名,然后签名和数据一同发送给接收者。

    接收者收到数据后,对收到的数据采用消息摘要算法获得签名,最后比较签名是否一致,以此来判断数据在传输过程中是否发生修改。

    加密库

    为了在 Linux 上安装它,你可以使用以下pip 命令:
    
    pip3 install -i https://pypi.douban.com/simple pycryptodome 
    
    在Windows 系统上安装则稍有不同:
    
    pip3 install -i https://pypi.douban.com/simple pycryptodomex

    DES加密

    全称为Data EncryptionStandard,即数据加密标准,是一种使用密钥加密的块算法

    入口参数有三个:Key、Data、Mode

    Key为7个字节共56位,是DES算法的工作密钥;

    Data为8个字节64位,是要被加密或被解密的数据;

    Mode为DES的工作方式,有两种:加密或解密

    3DES(即Triple DES)是DES向AES过渡的加密算法,

    使用两个密钥,执行三次DES算法,

    加密的过程是加密-解密-加密

    解密的过程是解密-加密-解密

    #coding=utf-8
    from Cryptodome.Cipher import DES
    
    key = b'abcdefgh'  # 密钥 8位或16位,必须为bytes
    
    
    def pad(text):
        """
        # 加密函数,如果text不是8的倍数【加密文本text必须为8的倍数!】,那就补足为8的倍数
        :param text: 
        :return: 
        """
        while len(text) % 8 != 0:
            text += ' '
        return text
    
    
    des = DES.new(key, DES.MODE_ECB)  # 创建一个DES实例
    text = 'Python rocks!'
    padded_text = pad(text)
    encrypted_text = des.encrypt(padded_text.encode('utf-8'))  # 加密
    print(encrypted_text)
    # rstrip(' ')返回从字符串末尾删除所有字符串的字符串(默认空白字符)的副本
    plain_text = des.decrypt(encrypted_text).decode().rstrip(' ')  # 解密
    print(plain_text)

    输出

    b'>xfcx1fx16xx87xb2x93x0exfcHx02xd59VQ'
    Python rocks!

    AES加密

    高级加密标准(英语:Advanced EncryptionStandard,缩写:AES),这个标准用来替代原先的DES

    AES的区块长度固定为128 比特,密钥长度则可以是128,192或256比特(16、24和32字节)

    大致步骤如下:

    1、密钥扩展(KeyExpansion),

    2、初始轮(Initial Round),

    3、重复轮(Rounds),每一轮又包括:SubBytes、ShiftRows、MixColumns、AddRoundKey,

    4、最终轮(Final Round),最终轮没有MixColumns。

    普通方式

    #coding=utf-8
    from Cryptodome.Cipher import AES
    from binascii import b2a_hex, a2b_hex
    #秘钥,此处需要将字符串转为字节
    key = 'abcdefgh'
    #加密内容需要长达16位字符,所以进行空格拼接
    def pad(text):
        while len(text) % 16 != 0:
            text += ' '
        return text
    #加密秘钥需要长达16位字符,所以进行空格拼接
    def pad_key(key):
        while len(key) % 16 != 0:
            key += ' '
        return key
    #进行加密算法,模式ECB模式,把叠加完16位的秘钥传进来
    aes = AES.new(pad_key(key).encode(), AES.MODE_ECB)
    #加密内容,此处需要将字符串转为字节
    text = 'hello'
    #进行内容拼接16位字符后传入加密类中,结果为字节类型
    encrypted_text = aes.encrypt(pad(text).encode())
    encrypted_text_hex = b2a_hex(encrypted_text)
    print(encrypted_text_hex)
    
    
    # #此处是为了验证是否能将字节转为字符串后,进行解密成功
    # #实际上a 就是 encrypted_text ,也就是加密后的内容
    # #用aes对象进行解密,将字节类型转为str类型,错误编码忽略不计
    de = str(aes.decrypt(a2b_hex(encrypted_text_hex)), encoding='utf-8',errors="ignore")
    # #获取str从0开始到文本内容的字符串长度。
    print(de[:len(text)])

    输出:

    b'c9f9f942485373f113dc07443ca8f2bf'
    hello

    面向对象方式

    #coding=utf-8
    from Cryptodome.Cipher import AES
    from binascii import b2a_hex, a2b_hex
    
    AES_LENGTH = 16
    
    class prpcrypt():
        def __init__(self, key):
            self.key = key
            self.mode = AES.MODE_ECB
            self.cryptor = AES.new(self.pad_key(self.key).encode(), self.mode)
    
        # 加密函数,如果text不是16的倍数【加密文本text必须为16的倍数!】,那就补足为16的倍数
        # 加密内容需要长达16位字符,所以进行空格拼接
        def pad(self,text):
            while len(text) % AES_LENGTH != 0:
                text += ' '
            return text
    
        # 加密密钥需要长达16位字符,所以进行空格拼接
        def pad_key(self,key):
            while len(key) % AES_LENGTH != 0:
                key += ' '
            return key
    
        def encrypt(self, text):
    
            # 这里密钥key 长度必须为16(AES-128)、24(AES-192)、或32(AES-256)Bytes 长度.目前AES-128足够用
            # 加密的字符需要转换为bytes
            # print(self.pad(text))
            self.ciphertext = self.cryptor.encrypt(self.pad(text).encode())
            # 因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
            # 所以这里统一把加密后的字符串转化为16进制字符串
            return b2a_hex(self.ciphertext)
    
            # 解密后,去掉补足的空格用strip() 去掉
    
        def decrypt(self, text):
            plain_text = self.cryptor.decrypt(a2b_hex(text)).decode()
            return plain_text.rstrip(' ')
    
    
    if __name__ == '__main__':
        pc = prpcrypt('abcdef')  # 初始化密钥
        e = pc.encrypt("0123456789ABCDEF")
        d = pc.decrypt(e)
        print(e, d)
        e = pc.encrypt("00000000000000000000000000")
        d = pc.decrypt(e)
        print(e, d)

    输出:

    b'011704c9ca48ae83fe63c9b245a48cde' 0123456789ABCDEF
    b'efabdcfe552e429226b1d0a88e7fa19cd21c7524b38d9122a5fe0c967ce07409' 00000000000000000000000000

    RSA加密

    公钥加密算法,一种非对称密码算法

    公钥加密,私钥解密

    3个参数:

    rsa_n, rsa_e,message

    rsa_n, rsa_e 用于生成公钥

    message: 需要加密的消息

    安装 pip install rsa

    使用

    import rsa
    from binascii import b2a_hex, a2b_hex
    
    
    
    class rsacrypt():
        def __init__(self, pubkey, prikey):
            self.pubkey = pubkey
            self.prikey = prikey
    
        def encrypt(self, text):
            self.ciphertext = rsa.encrypt(text.encode(), self.pubkey)
            # 因为rsa加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
            # 所以这里统一把加密后的字符串转化为16进制字符串
            return b2a_hex(self.ciphertext)
    
        def decrypt(self, text):
            decrypt_text = rsa.decrypt(a2b_hex(text), prikey)
            return decrypt_text
    
    
    if __name__ == '__main__':
        pubkey, prikey = rsa.newkeys(256)
        rs_obj = rsacrypt(pubkey,prikey)
        text='hello'
        ency_text = rs_obj.encrypt(text)
        print(ency_text)
        print(rs_obj.decrypt(ency_text))

    输出:

    b'923af53dbc976be4c727589bddd66ffd981120d1b230de4075cc3e06bca4e4f6'
    b'hello'

  • 相关阅读:
    CentOS
    Docker
    Chart的简单使用
    DataGridView中间插入数据行
    获取每个月的固定的第n个星期几
    设置只能开启一个程序实例
    DataContext与实体类
    Attribute
    Delegate
    Event
  • 原文地址:https://www.cnblogs.com/sea-stream/p/10266110.html
Copyright © 2020-2023  润新知