如何實現(xiàn)信息加密及其在郵件發(fā)送中的應用

信息加密

??信息加密技術是利用數(shù)學或物理手段,對電子信息在傳輸過程中和存儲體內進行保護,以防止泄漏的技術。 從信息結果來講,加密就是通過密碼算術對數(shù)據(jù)進行轉化,將明文通過密鑰(私鑰)轉換成密文,使之成為沒有正確密鑰任何人都無法讀懂的報文。
??比較著名的公鑰密碼算法有:RSA、EIGamal算法等,其中最有影響的公鑰密碼算法是RSA,從類型上講油分為私鑰加密算法和公鑰加密算法,相比于私鑰加密算法,公鑰加密實現(xiàn)了接收者與發(fā)送者的密鑰互不相同,無法通過其中一個密鑰進行密文破譯,更加具有信息安全性。
??實際情況里,局域網(wǎng)中對于信息安全等級要求沒有那么高,且強調信息傳輸效率,一般采用私鑰加密算法進行實現(xiàn),以下我們通過pythonpycryptodome包的使用方法進行闡述,實現(xiàn)私鑰加密算法。

  1. pycryptodome
    pycryptodome是對pycrypto(2013年停止更新)的繼承和發(fā)展,可以實現(xiàn)包括SHA1、MD5在內的多種加密方式,詳細請訪問pycryptodome官網(wǎng)
    • 包安裝
    pip3 install pycryptodome
    
  2. 官網(wǎng)使用示例
    • 信息加密
      通過隨機函數(shù)生成密鑰,加密得到cipher.nonce, tag, ciphertext三類信息寫入到文件中,將密鑰寫入文件。實際應用中可以書寫到不同文件中,實現(xiàn)密鑰分發(fā)。
    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. 推薦使用方式
    根據(jù)官網(wǎng)使用示例,我們可以把方式整理成一個類,在加密的時候保存密鑰和密文,在解密的時候讀取密鑰和密文,實現(xiàn)解密。
    • 首先我們定義二進制文件的寫入和讀入
    ####  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數(shù)據(jù)類型寫入文件
    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數(shù)據(jù)類型寫入文件
    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'))
    

郵件的發(fā)送規(guī)范

  1. 郵件的書寫
    我們使用python內置的emailsmtplib包實現(xiàn)郵件的發(fā)送,在郵件文本中我們需要定義以下的屬性
    • 最大發(fā)送次數(shù)
    • 最大間隔時間
    • 郵件發(fā)送者
    • 發(fā)送者郵箱密碼
    • 郵箱服務器地址
    • 接收者
    • 抄送者
    • 郵件主題
    • 郵件正文
    • 郵件附件
  2. 郵件的發(fā)送
    一般過程如下:
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' ))
# 郵件發(fā)送
smtp.sendmail( addressor , receiver.split(';') , msginfo.as_string())

加密技術在郵件發(fā)送的應用方式

??這里我們應用前文的方式二進行示例,首先密文是字符串可以直接讀入,密鑰是bytes,需要使用上文的函數(shù)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
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容