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

信息加密

  信息加密技术是利用数学或物理手段,对电子信息在传输过程中和存储体内进行保护,以防止泄漏的技术。 从信息结果来讲,加密就是通过密码算术对数据进行转化,将明文通过密钥(私钥)转换成密文,使之成为没有正确密钥任何人都无法读懂的报文。
  比较著名的公钥密码算法有: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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容