Python實現常見的幾種加密演算法(MD5,SHA-1,HMAC,DESAES,RSA和ECC)
MD5加密
全稱:MD5訊息摘要演算法(英語:MD5 Message-Digest Algorithm),一種被廣泛使用的密碼雜湊函式,可以產生出一個128位(16位元組)的雜湊值(hash value),用於確保資訊傳輸完整一致。md5加密演算法是不可逆的,所以解密一般都是通過暴力窮舉方法,通過網站的介面實現解密。Python程式碼:
import hashlib
m = hashlib.md5()
m.update(str.encode("utf8"))
print(m.hexdigest())
SHA1加密
全稱:安全雜湊演算法(Secure Hash Algorithm)主要適用於數字簽名標準(Digital Signature Standard DSS)裡面定義的數字簽名演算法(Digital Signature Algorithm DSA),SHA1比MD5的安全性更強。對於長度小於2^ 64位的訊息,SHA1會產生一個160位的訊息摘要。Python程式碼:
import hashlib
sha1 = hashlib.sha1()
data = '2333333'
sha1.update(data.encode('utf-8'))
sha1_data = sha1.hexdigest()
print(sha1_data)
HMAC加密
全稱:雜湊訊息鑑別碼(Hash Message Authentication Code), HMAC加密演算法是一種安全的基於加密hash函式和共享金鑰的訊息認證協議。實現原理是用公開函式和金鑰產生一個固定長度的值作為認證標識,用這個標識鑑別訊息的完整性。使用一個金鑰生成一個固定大小的小資料塊,即 MAC,並將其加入到訊息中,然後傳輸。接收方利用與傳送方共享的金鑰進行鑑別認證等。Python程式碼:
import hmac
import hashlib
# 第一個引數是金鑰key,第二個引數是待加密的字串,第三個引數是hash函式
mac = hmac.new('key','hello',hashlib.md5)
mac.digest() # 字串的ascii格式
mac.hexdigest() # 加密後字串的十六進位制格式
DES加密
全稱:資料加密標準(Data Encryption Standard),屬於對稱加密演算法。DES是一個分組加密演算法,典型的DES以64位為分組對資料加密,加密和解密用的是同一個演算法。它的金鑰長度是56位(因為每個第8 位都用作奇偶校驗),金鑰可以是任意的56位的數,而且可以任意時候改變。Python程式碼:
import binascii
from pyDes import des, CBC, PAD_PKCS5
# 需要安裝 pip install pyDes
def des_encrypt(secret_key, s):
iv = secret_key
k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
en = k.encrypt(s, padmode=PAD_PKCS5)
return binascii.b2a_hex(en)
def des_decrypt(secret_key, s):
iv = secret_key
k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
de = k.decrypt(binascii.a2b_hex(s), padmode=PAD_PKCS5)
return de
secret_str = des_encrypt('12345678', 'I love YOU~')
print(secret_str)
clear_str = des_decrypt('12345678', secret_str)
print(clear_str)
AES加密
全稱:高階加密標準(英語:Advanced Encryption Standard),在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣為全世界所使用。Python程式碼:
import base64
from Crypto.Cipher import AES
'''
AES對稱加密演算法
'''
# 需要補位,str不是16的倍數那就補足為16的倍數
def add_to_16(value):
while len(value) % 16 != 0:
value += '\0'
return str.encode(value) # 返回bytes
# 加密方法
def encrypt(key, text):
aes = AES.new(add_to_16(key), AES.MODE_ECB) # 初始化加密器
encrypt_aes = aes.encrypt(add_to_16(text)) # 先進行aes加密
encrypted_text = str(base64.encodebytes(encrypt_aes), encoding='utf-8') # 執行加密並轉碼返回bytes
return encrypted_text
# 解密方法
def decrypt(key, text):
aes = AES.new(add_to_16(key), AES.MODE_ECB) # 初始化加密器
base64_decrypted = base64.decodebytes(text.encode(encoding='utf-8')) # 優先逆向解密base64成bytes
decrypted_text = str(aes.decrypt(base64_decrypted), encoding='utf-8').replace('\0', '') # 執行解密密並轉碼返回str
return decrypted_text
RSA加密
全稱:Rivest-Shamir- Adleman,RSA加密演算法是一種非對稱加密演算法。在公開金鑰加密和電子商業中RSA被廣泛使用。它被普遍認為是目前比較優秀的公鑰方案之一。RSA是第一個能同時用於加密和數字簽名的演算法,它能夠抵抗到目前為止已知的所有密碼攻擊。Python程式碼:
# -*- coding: UTF-8 -*-
# reference codes: https://www.jianshu.com/p/7a4645691c68
import base64
import rsa
from rsa import common
# 使用 rsa庫進行RSA簽名和加解密
class RsaUtil(object):
PUBLIC_KEY_PATH = 'xxxxpublic_key.pem' # 公鑰
PRIVATE_KEY_PATH = 'xxxxxprivate_key.pem' # 私鑰
# 初始化key
def __init__(self,
company_pub_file=PUBLIC_KEY_PATH,
company_pri_file=PRIVATE_KEY_PATH):
if company_pub_file:
self.company_public_key = rsa.PublicKey.load_pkcs1_openssl_pem(open(company_pub_file).read())
if company_pri_file:
self.company_private_key = rsa.PrivateKey.load_pkcs1(open(company_pri_file).read())
def get_max_length(self, rsa_key, encrypt=True):
"""加密內容過長時 需要分段加密 換算每一段的長度.
:param rsa_key: 鑰匙.
:param encrypt: 是否是加密.
"""
blocksize = common.byte_size(rsa_key.n)
reserve_size = 11 # 預留位為11
if not encrypt: # 解密時不需要考慮預留位
reserve_size = 0
maxlength = blocksize - reserve_size
return maxlength
# 加密 支付方公鑰
def encrypt_by_public_key(self, message):
"""使用公鑰加密.
:param message: 需要加密的內容.
加密之後需要對接過進行base64轉碼
"""
encrypt_result = b''
max_length = self.get_max_length(self.company_public_key)
while message:
input = message[:max_length]
message = message[max_length:]
out = rsa.encrypt(input, self.company_public_key)
encrypt_result += out
encrypt_result = base64.b64encode(encrypt_result)
return encrypt_result
def decrypt_by_private_key(self, message):
"""使用私鑰解密.
:param message: 需要加密的內容.
解密之後的內容直接是字串,不需要在進行轉義
"""
decrypt_result = b""
max_length = self.get_max_length(self.company_private_key, False)
decrypt_message = base64.b64decode(message)
while decrypt_message:
input = decrypt_message[:max_length]
decrypt_message = decrypt_message[max_length:]
out = rsa.decrypt(input, self.company_private_key)
decrypt_result += out
return decrypt_result
# 簽名 商戶私鑰 base64轉碼
def sign_by_private_key(self, data):
"""私鑰簽名.
:param data: 需要簽名的內容.
使用SHA-1 方法進行簽名(也可以使用MD5)
簽名之後,需要轉義後輸出
"""
signature = rsa.sign(