zoukankan      html  css  js  c++  java
  • 加密和解密的总结

    一.加密算法的分类

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

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

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

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

      3.利用字典的格式转换加密

        MAKETRANS()

    二.详细分析

      1.DES加密

        即数据加密标准,是一种使用秘钥加密的块算法

        入口参数有三个:key, Data,  Mode

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

          Data为DES的工作方式,有两种:加密和解密

        3DES是DES向AES过渡的加密算法,使用两个秘钥,执行三次DES算法,

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

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

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

      2.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。

    普通方式

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

    面向对象方式

     1 from Cryptodome.Cipher import AES
     2 from binascii import b2a_hex, a2b_hex
     3  
     4 AES_LENGTH = 16
     5  
     6 class prpcrypt():
     7   def __init__(self, key):
     8     self.key = key
     9     self.mode = AES.MODE_ECB
    10     self.cryptor = AES.new(self.pad_key(self.key).encode(), self.mode)
    11  
    12   # 加密函数,如果text不是16的倍数【加密文本text必须为16的倍数!】,那就补足为16的倍数
    13   # 加密内容需要长达16位字符,所以进行空格拼接
    14   def pad(self,text):
    15     while len(text) % AES_LENGTH != 0:
    16       text += ' '
    17     return text
    18  
    19   # 加密密钥需要长达16位字符,所以进行空格拼接
    20   def pad_key(self,key):
    21     while len(key) % AES_LENGTH != 0:
    22       key += ' '
    23     return key
    24  
    25   def encrypt(self, text):
    26  
    27     # 这里密钥key 长度必须为16(AES-128)、24(AES-192)、或32(AES-256)Bytes 长度.目前AES-128足够用
    28     # 加密的字符需要转换为bytes
    29     # print(self.pad(text))
    30     self.ciphertext = self.cryptor.encrypt(self.pad(text).encode())
    31     # 因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
    32     # 所以这里统一把加密后的字符串转化为16进制字符串
    33     return b2a_hex(self.ciphertext)
    34  
    35     # 解密后,去掉补足的空格用strip() 去掉
    36  
    37   def decrypt(self, text):
    38     plain_text = self.cryptor.decrypt(a2b_hex(text)).decode()
    39     return plain_text.rstrip(' ')
    40  
    41  
    42 if __name__ == '__main__':
    43   pc = prpcrypt('abcdef') # 初始化密钥
    44   e = pc.encrypt("0123456789ABCDEF")
    45   d = pc.decrypt(e)
    46   print(e, d)
    47   e = pc.encrypt("00000000000000000000000000")
    48   d = pc.decrypt(e)
    49   print(e, d)

      3.RSA加密

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

        公钥加密,私钥解密

        公有三个参数:rsa_n, rsa_e, message

        rsa_n, rsa_e 用于生成公钥

        message:需要加密的消息

     1 import rsa
     2 from binascii import b2a_hex, a2b_hex
     3  
     4  
     5  
     6 class rsacrypt():
     7   def __init__(self, pubkey, prikey):
     8     self.pubkey = pubkey
     9     self.prikey = prikey
    10  
    11   def encrypt(self, text):
    12     self.ciphertext = rsa.encrypt(text.encode(), self.pubkey)
    13     # 因为rsa加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
    14     # 所以这里统一把加密后的字符串转化为16进制字符串
    15     return b2a_hex(self.ciphertext)
    16  
    17   def decrypt(self, text):
    18     decrypt_text = rsa.decrypt(a2b_hex(text), prikey)
    19     return decrypt_text
    20  
    21  
    22 if __name__ == '__main__':
    23   pubkey, prikey = rsa.newkeys(256)
    24   rs_obj = rsacrypt(pubkey,prikey)
    25   text='hello'
    26   ency_text = rs_obj.encrypt(text)
    27   print(ency_text)
    28   print(rs_obj.decrypt(ency_text))
    29  
    30 """
    31 b'7cb319c67853067abcd16aad25b3a8658e521f83b1e6a6cf0c4c2e9303ad3e14'
    32 b'hello'
    33 """

      4.使用base64或pycrypto模块

        1.使用base64

    1 s1 = base64.encodestring('hello world')
    2 s2 = base64.decodestring(s1)
    3 print s1, s2
    4 
    5 #  结果
    6 #  aGVsbG8gd29ybGQ=
    7 #  hello world

          优点:方法简单

          缺点:不保险,别人拿到密文可以解密出明文

          编码原理:将3个字节转换成4个字节((3 X 8)=24=(4X6)),先读入3个字节,每读一个字节,左移8位,再右移四次,每次6位,这样就有4个字节了。

          解密原理:将4个字节转换成3个字节,先读入4个6位(用或运算),每次左移6位,再右移3次,每次8位,这样就还原了。

        2.使用pycrypto模块

     1 from Crypto.Cipher import AES
     2 obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
     3 message = "The answer is no"
     4 ciphertext = obj.encrypt(message)
     5 print(ciphertext)
     6 #   'xd6x83x8dd!VTx92xaa`Ax05xe0x9bx8bxf1'
     7 obj2 = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
     8 decryptext = obj2.decrypt(ciphertext)
     9 print(decryptext)
    10 #  'The answer is no'

          AES只是个基本算法,实现AES有若干模式。其中的CBC模式因为其安全性而被TLS(就是https的加密标准)和IPSec(win采用的)作为技术标准。

          简单地说,CBC使用密码和salt(起扰乱作用)按固定算法(md5)产生key和iv。然后用key和iv(初始向量,加密第一块明文)加密(明文)和解密(密文)。

     1 import sys
     2 from Crypto.Cipher import AES
     3 from binascii import b2a_hex, a2b_hex
     4   
     5 class prpcrypt():
     6   def __init__(self, key):
     7     self.key = key
     8     self.mode = AES.MODE_CBC
     9     
    10   #加密函数,如果text不是16的倍数【加密文本text必须为16的倍数!】,那就补足为16的倍数
    11   def encrypt(self, text):
    12     cryptor = AES.new(self.key, self.mode, self.key)
    13     #这里密钥key 长度必须为16(AES-128)、24(AES-192)、或32(AES-256)Bytes 长度.目前AES-128足够用
    14     length = 16
    15     count = len(text)
    16     add = length - (count % length)
    17     text = text + ('' * add)
    18     self.ciphertext = cryptor.encrypt(text)
    19     #因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
    20     #所以这里统一把加密后的字符串转化为16进制字符串
    21     return b2a_hex(self.ciphertext)
    22     
    23   #解密后,去掉补足的空格用strip() 去掉
    24   def decrypt(self, text):
    25     cryptor = AES.new(self.key, self.mode, self.key)
    26     plain_text = cryptor.decrypt(a2b_hex(text))
    27     return plain_text.rstrip('')
    28   
    29 if __name__ == '__main__':
    30   pc = prpcrypt('keyskeyskeyskeys')   #初始化密钥
    31   e = pc.encrypt("00000")
    32   d = pc.decrypt(e)           
    33   print(e, d)
    34   e = pc.encrypt("00000000000000000000000000")
    35   d = pc.decrypt(e)         
    36   print(e, d)

      5.Python  maketrans()方法  也可以用来进行加密

        描述:用于创建字符串映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标

        注:两个字符串的长度必须相同,为一一对应的关系

        语法: str.maketrans(in_tab, out_tab)

        参数:in_tab - 字符串中要替换的字符串组成的字符串

            out_tab - 相应的映射字符的字符串

    1 from string import maketrans   # 必须调用 maketrans 函数。
    2 
    3 intab = "aeiou"
    4 outtab = "12345"
    5 trantab = maketrans(intab, outtab)
    6 
    7 str = "this is string example....wow!!!"
    8 print(str.translate(trantab))

    参考链接:https://www.jb51.net/article/152209.htm

  • 相关阅读:
    POJ 1936 All in All
    POJ 2305 Basic remains
    POJ 2081 Recaman's Sequence
    MFC MDI 窗口函数执行顺序
    decompose
    不新建一个文档
    code mistake
    ...
    paper
    stereo
  • 原文地址:https://www.cnblogs.com/chenxi67/p/11611923.html
Copyright © 2011-2022 走看看