美文网首页
如何实现信息加密及其在邮件发送中的应用

如何实现信息加密及其在邮件发送中的应用

作者: 不二小张 | 来源:发表于2021-12-22 14:36 被阅读0次

    信息加密

      信息加密技术是利用数学或物理手段,对电子信息在传输过程中和存储体内进行保护,以防止泄漏的技术。 从信息结果来讲,加密就是通过密码算术对数据进行转化,将明文通过密钥(私钥)转换成密文,使之成为没有正确密钥任何人都无法读懂的报文。
      比较著名的公钥密码算法有:RSA、EIGamal算法等,其中最有影响的公钥密码算法是RSA,从类型上讲油分为私钥加密算法和公钥加密算法,相比于私钥加密算法,公钥加密实现了接收者与发送者的密钥互不相同,无法通过其中一个密钥进行密文破译,更加具有信息安全性。
      实际情况里,局域网中对于信息安全等级要求没有那么高,且强调信息传输效率,一般采用私钥加密算法进行实现,以下我们通过pythonpycryptodome包的使用方法进行阐述,实现私钥加密算法。

    1. pycryptodome
      pycryptodome是对pycrypto(2013年停止更新)的继承和发展,可以实现包括SHA1、MD5在内的多种加密方式,详细请访问pycryptodome官网
      • 包安装
      pip3 install pycryptodome
      
    2. 官网使用示例
      • 信息加密
        通过随机函数生成密钥,加密得到cipher.nonce, tag, ciphertext三类信息写入到文件中,将密钥写入文件。实际应用中可以书写到不同文件中,实现密钥分发。
      from Crypto.Cipher import AES
      from Crypto.Random import get_random_bytes
      
      key = get_random_bytes(16)
      cipher = AES.new(key, AES.MODE_EAX)
      ciphertext, tag = cipher.encrypt_and_digest(data)
      
      file_out = open("encrypted.bin", "wb")
      file_key = open("encrypted.key", "wb")
      [ file_out.write(x) for x in (cipher.nonce, tag, ciphertext) ]
      file_key.write(key)
      file_out.close()
      file_key.close()
      
      • 信息解密
        将加密过程中生成的的密钥文件和密文信息读入,进行信息解密
      from Crypto.Cipher import AES
      
      file_in = open("encrypted.bin", "rb")
      file_key = open("encrypted.key", "rb")
      nonce, tag, ciphertext = [ file_in.read(x) for x in (16, 16, -1) ]
      key = file_key.read()
      # let's assume that the key is somehow available again
      cipher = AES.new(key, AES.MODE_EAX, nonce)
      data = cipher.decrypt_and_verify(ciphertext, tag)
      
    3. 推荐使用方式
      根据官网使用示例,我们可以把方式整理成一个类,在加密的时候保存密钥和密文,在解密的时候读取密钥和密文,实现解密。
      • 首先我们定义二进制文件的写入和读入
      ####  byte data 
      def read_file(one_file):
          with open(one_file,'rb') as file_byte:
              file_hex = file_byte.read()
              return file_hex
      
      def write_file(one_file, file_hex):
          with open(one_file,'wb') as new_file:
              new_file.write(file_hex)
      
      • 方式一:保存AES返回的所有信息,并用于密文解密,需要注意的是,这里的密钥和密文都需要以bytes数据类型写入文件
      class EncryptStr(object):
          def __init__(self, key=None):
              self.length = 16
              self.key = key if key else get_random_bytes(self.length)
              self.mode = AES.MODE_EAX
      
          def encrypt(self, text):
              #cryptor = AES.new(self.key, self.mode)
              cipher = AES.new(self.key, self.mode)
              ciphertext, tag = cipher.encrypt_and_digest(text.encode('utf-8'))
              #[ print(x) for x in (cipher.nonce, tag, ciphertext)]
              #self.ciphertext = cryptor.encrypt(text)
              return cipher.nonce, tag, ciphertext
      
          # 解密后,去掉补足的空格用strip() 去掉
          def decrypt(self, nonce, text, tag):
              cryptor = AES.new(self.key, self.mode, nonce)
              plain_text = cryptor.decrypt_and_verify(text, tag)
              return plain_text.decode('utf-8').strip('\0')
      
      • 方式二 ,将返回的信息处理整合,形成加密后的密文,并以字符串的形式写入文件;密钥以bytes数据类型写入文件
      class AESEncrypter(object):
          def __init__(self, key=None, iv=None):
              self.length = 16
              if isinstance(key, str) or not key:
                  self.key = key.encode('utf8') if key else get_random_bytes(self.length)
              elif isinstance(key, bytes):
                  self.key = key
              self.iv = iv if iv else self.key[0:self.length]
          def _pad(self, text):
              text_length = len(text)
              padding_len = AES.block_size - int(text_length % AES.block_size)
              if padding_len == 0:
                  padding_len = AES.block_size
              t2 = chr(padding_len) * padding_len
              t2 = t2.encode('utf8')
              # print('text ', type(text), text)
              # print('t2 ', type(t2), t2)
              t3 = text + t2
              return t3
          def _unpad(self, text):
              pad = ord(text[-1])
              return text[:-pad]
          def encrypt(self, raw):
              raw = raw.encode('utf8')
              raw = self._pad(raw)
              cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
              encrypted = cipher.encrypt(raw)
              return base64.b64encode(encrypted).decode('utf8')
          def decrypt(self, enc):
              print(self.key,type(self.key))
              enc = enc.encode('utf8')
              enc = base64.b64decode(enc)
              cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
              decrypted = cipher.decrypt(enc)
              return self._unpad(decrypted.decode('utf8'))
      

    邮件的发送规范

    1. 邮件的书写
      我们使用python内置的emailsmtplib包实现邮件的发送,在邮件文本中我们需要定义以下的属性
      • 最大发送次数
      • 最大间隔时间
      • 邮件发送者
      • 发送者邮箱密码
      • 邮箱服务器地址
      • 接收者
      • 抄送者
      • 邮件主题
      • 邮件正文
      • 邮件附件
    2. 邮件的发送
      一般过程如下:
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    from email import utils
    import mimetypes, sys,smtplib
    #初始化服务器链接
    smtp=smtplib.SMTP()
    smtp.connect(server, port)
    #服务器登录
    smtp.login( addressor , password )
    #构造邮寄正文
    msginfo=MIMEMultipart()
    msginfo['From'] = addressor
    msginfo['To'] = receiver
    msginfo['Message-ID'] = utils.make_msgid()
    msginfo['Subject'] = subject
    msginfo.attach(MIMEText( body , 'html' , 'utf-8' ))
    # 邮件发送
    smtp.sendmail( addressor , receiver.split(';') , msginfo.as_string())
    

    加密技术在邮件发送的应用方式

      这里我们应用前文的方式二进行示例,首先密文是字符串可以直接读入,密钥是bytes,需要使用上文的函数read_file进行读入。

    with open('encrypted.bin','r') as f_bin:
        Encrypted = f_bin.readline()
    Key = read_file('encrypted.key')
    data = AESEncrypter(Key).decrypt(Encrypted)
    #这里得到的data就是邮箱密码了,填充至上文smtp.login( addressor , password )的password里,即:
    password = data
    

    相关文章

      网友评论

          本文标题:如何实现信息加密及其在邮件发送中的应用

          本文链接:https://www.haomeiwen.com/subject/olmqqrtx.html