1.base64加密
base64是什么
Base64編碼,是由64個字符組成編碼集:26個大寫字母AZ,26個小寫字母az,10個數字0~9,符號“+”與符號“/”。Base64編碼的基本思路是將原始數據的三個字節拆分轉化為四個字節,然后根據Base64的對應表,得到對應的編碼數據。
當原始數據湊不夠三個字節時,編碼結果中會使用額外的**符號“=”**來表示這種情況。
base64原理
每一個base64的字符會對應有一個索引值(0-63)
將you進行base64編碼過程如下:
小于3個字符為一組的編碼方式如:
ASCII表:
base64代碼演示
加密過程
# 將you進行加密
import base64# 1.先將字符串編碼成二進制
data = 'you'.encode("utf-8")
print(data) # 打印結果:b'you'# 2.再將二進制編碼成base64的二進制,再由二進制進行解碼成字符串
bs = base64.b64encode(data).decode('utf-8')
print(bs) # 打印結果:eW91# 3.如果不夠4位加密,則換成等號
data1 = 'y'.encode("utf-8")
bs1 = base64.b64encode(data1).decode("utf-8")
print(bs1) # 打印結果:eQ==
解密過程
# 將eW91進行解密
import base64data = 'eW91'
bs1 = base64.b64decode(data).decode()
print(bs1)data1 = 'eW91eQ=='
bs2 = base64.b64decode(data1).decode()
print(bs1)# 必須是4的倍數
s = "eW91eQ"
# 填充為4的倍數
s += ("=" * (4 - len(s) % 4))
print("填充后", s)
ret = base64.b64decode(s).decode()
print(ret)
js常見的加密方式
- 加密在前端開發和爬蟲中是經常遇見的。掌握了加密、解密算法也是你從一個編程小白到大神級別質的一個飛躍。且加密算法的熟練和剖析也是很有助于幫助我們實現高效的js逆向。下述只把我們常用的加密方法進行總結。不去深究加密的具體實現方式。
- 常見的加密算法基本分為這幾類,
- 線性散列算法(簽名算法)MD5
- 對稱性加密算法 AES DES
- 非對稱性加密算法 RSA
2.Md5加密(不可逆)
- MD5是一種被廣泛使用的線性散列算法,可以產生出一個128位(16字節)的散列值(hash value),用于確保信息傳輸完整的一致性。且MD5加密之后產生的是一個固定長度(32位或16位)的數據。
- 結論:一旦看到了一個長度為32位的密文數據,該數據極有可能是通過md5算法進行的加密!
- 解密:
- 常規講MD5是不存在解密的。但是理論上MD5是可以進行反向暴力破解的。暴力破解的大致原理就是用很多不同的數據進行加密后跟已有的加密數據進行對比,由此來尋找規律。理論上只要數據量足夠龐大MD5是可以被破解的。但是要注意,破解MD5是需要考慮破解的成本(時間和機器性能)。假設破解當前的MD5密碼需要目前計算能力最優秀的計算機工作100年才能破解完成。那么當前的MD5密碼就是安全的。
- 增加破解成本的方法(方法很多,這里只說我常用的)。
- 使用一段無意義且隨機的私匙進行MD5加密會生成一個加密串,我們暫且稱之為串1
- 將要加密的的數據跟串1拼接,再進行一次MD5,這時會生成串2
- 將串2再次進行MD5加密,這時生成的串3就是我們加密后的數據。
- 我們在注冊賬號時的密碼一般都是用的MD5加密。
Python中使用MD5加密
from hashlib import md5obj = md5()
obj.update("bobo".encode("utf-8"))bs = obj.hexdigest()
print(bs)
JS中使用MD5加密
- JS版本:下載安裝crypto-js(npm install crypto-js)
- 前提要安裝node.js
var CryptoJS = require('crypto-js'); // 原始數據 var data = '123456'; // 生成MD5摘要 var md5Digest = CryptoJS.MD5(data).toString();console.log(md5Digest);
3.DES/AES加密(可逆)
-
DES全稱為Data Encryption Standard,即數據加密標準,是一種使用密鑰加密的算法。該加密算法是一種對稱加密方式,其加密運算、解密運算需要使用的是同樣的密鑰(一組字符串)即可。
-
注意:
- 現在用AES這個標準來替代原先的DES。
- AES和DES的區別:
- 加密后密文長度的不同:
- DES加密后密文長度是8的整數倍
- AES加密后密文長度是16的整數倍
- 應用場景的不同:
- 企業級開發使用DES足夠安全
- 如果要求高使用AES
- 加密后密文長度的不同:
-
DES算法的入口參數有三個:
- Key、Data、Mode,padding、iv。
- Key為DES算法的工作密鑰;
- Data為要被加密或被解密的數據;
- Mode為DES的工作模式。最常用的模式就是 CBC 模式和 ECB模式
- ECB:是一種基礎的加密方式,密文被分割成分組長度相等的塊(不足補齊),然后單獨一個個加密,一個個輸出組成密文。
- CBC:是一種循環模式,前一個分組的密文和當前分組的明文異或后再加密,這樣做的目的是增強破解難度。
- padding為填充模式,如果加密后密文長度如果達不到指定整數倍(8個字節、16個字節),填充對應字符
- iv:參數中的iv主要用于CBC模式,確保即使加密相同的明文,每次產生的密文也不相同,增強加密的安全性。iv通常是一個16字節的隨機字符串。這個字符串在解密時也需要用到,因此需要妥善保存。
- Key、Data、Mode,padding、iv。
-
Python版本:
-
環境安裝:
pip install pycryptodome
-
python加密代碼:
```
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import base64
import os
key_value = os.getenv('KEY')key = '0123456789abcdef'.encode() # 秘鑰: 必須16字節
iv = b'abcdabcdabcdabcd' # 偏移量:16位/字節(字節類型)
text = 'alex is a monkey!' # 加密內容
# 設置加密內容的長度填充(位數為16的整數倍)
text = pad(text.encode(), 16)
# 創建加密對象
aes = AES.new(key, AES.MODE_CBC, iv) # 創建一個aes對象en_text = aes.encrypt(text) # 加密明文
print("aes加密數據:::", en_text) # 返回二進制類型數據# 二進制密文轉換成字符串格式
en_text = base64.b64encode(en_text).decode() # 將返回的字節型數據轉進行base64編碼
print(en_text)
```
python解密
```
from Crypto.Cipher import AES
import base64
from Crypto.Util.Padding import unpadkey = '0123456789abcdef'.encode()
iv = b'abcdabcdabcdabcd'
aes = AES.new(key, AES.MODE_CBC, iv)
# 需要解密的文本
text = 'X/A0fy9S7+kUI3HYQRKO46WTlid6T1DBhXutwmPdboY='.encode()
# 將密文數據轉換為二進制類型
ecrypted_base64 = base64.b64decode(text)source = aes.decrypt(ecrypted_base64) # 解密
# 未填充數據
print("aes解密數據:::", source.decode())
# 取消填充數據
print("aes解密數據:::", unpad(source, 16).decode())
```
js加密
const CryptoJS = require("crypto-js")// 密鑰(128位,16字節)
var key = CryptoJS.enc.Utf8.parse('0123456789abcdef');// 初始化向量(IV)(128位,16字節)
var iv = CryptoJS.enc.Utf8.parse('1234567890abcdef');// 待加密的數據
var plaintext = 'Hello, bobo!';// 進行AES-128加密,使用CBC模式和PKCS7填充
var encrypted = CryptoJS.AES.encrypt(plaintext, key, {iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7
});// 獲取加密后的密文
var ciphertext = encrypted.toString();console.log(ciphertext);
js解密
const CryptoJS = require("crypto-js")// 密鑰(128位,16字節)
var key = CryptoJS.enc.Utf8.parse('0123456789abcdef');// 初始化向量(IV)(128位,16字節)
var iv = CryptoJS.enc.Utf8.parse('1234567890abcdef');// 密文數據
var encrypText = 'GYc9oxlZB/PeyfFG3ppK6Q==';// 進行加密,使用CBC模式和PKCS7填充
var decrypted = CryptoJS.AES.decrypt(encrypText, key, {iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7
});// 解密
var plaintext = decrypted.toString(CryptoJS.enc.Utf8);console.log(plaintext);
4.RSA加密(可逆)
- RSA加密:
- RSA加密算法是一種非對稱加密算法。在公開密鑰加密和電子商業中RSA被廣泛使用。
- 非對稱加密算法:
- 非對稱加密算法需要兩個密鑰:
- 公開密鑰(publickey:簡稱公鑰)== 數據加密
- 私有密鑰(privatekey:簡稱私鑰)==數據解密
- 公鑰與私鑰是一對,如果用公鑰對數據進行加密,只有用對應的私鑰才能解密。因為加密和解密使用的是兩個不同的密鑰,所以這種算法叫作非對稱加密算法。
- 非對稱加密算法需要兩個密鑰:
- 注意:
- 使用時都是使用公匙加密使用私匙解密。公匙可以公開,私匙自己保留。
- 算法強度復雜、安全性依賴于算法與密鑰但是由于其算法復雜,而使得加密解密速度沒有對稱加密解密的速度快。
- 使用流程和場景介紹
- 通過公匙加密,使用私匙解密。私匙是通過公匙計算生成的。假設ABC三方之間相互要進行加密通信。大家相互之間使用公匙進行信息加密,信息讀取時使用各自對應的私匙進行信息解密
- 用戶輸入的支付密碼會通過RSA加密
- 公鑰私鑰生成方式:
- 公私匙可以在線生成
- http://web.chacuo.net/netrsakeypair
- 公私匙可以在線生成
- 環境安裝:npm install jsencrypt
js加密、解密
window = globalThis;const JSEncrypt = require('jsencrypt');var PUBLIC_KEY = '-----BEGIN PUBLIC KEY-----MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALyBJ6kZ/VFJYTV3vOC07jqWIqgyvHulv6us/8wzlSBqQ2+eOTX7s5zKfXY40yZWDoCaIGk+tP/sc0D6dQzjaxECAwEAAQ==-----END PUBLIC KEY-----';//私鑰
var PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvIEnqRn9UUlhNXe84LTuOpYiqDK8e6W/q6z/zDOVIGpDb545NfuznMp9djjTJlYOgJogaT60/+xzQPp1DONrEQIDAQABAkEAu7DFsqQEDDnKJpiwYfUE9ySiIWNTNLJWZDN/Bu2dYIV4DO2A5aHZfMe48rga5BkoWq2LALlY3tqsOFTe3M6yoQIhAOSfSAU3H6jIOnlEiZabUrVGqiFLCb5Ut3Jz9NN+5p59AiEA0xQDMrxWBBJ9BYq6RRY4pXwa/MthX/8Hy+3GnvNw/yUCIG/3Ee578KVYakq5pih8KSVeVjO37C2qj60d3Ok3XPqBAiEAqGPvxTsAuBDz0kcBIPqASGzArumljkrLsoHHkakOfU0CIDuhxKQwHlXFDO79ppYAPcVO3bph672qGD84YUaHF+pQ-----END PRIVATE KEY-----';
//使用公鑰加密
var encrypt = new JSEncrypt();//實例化加密對象
encrypt.setPublicKey(PUBLIC_KEY);//設置公鑰
var encrypted = encrypt.encrypt('hello bobo!');//對指定數據進行加密
console.log(encrypted);//使用私鑰解密// 使用私鑰解密
var decrypt = new JSEncrypt();
decrypt.setPrivateKey(PRIVATE_KEY);//設置私鑰
var uncrypted = decrypt.decrypt(encrypted);//解密
console.log(uncrypted);
python中RSA創建公鑰、私鑰
from Crypto.PublicKey import RSA# 通過相關算法生成唯一秘鑰,生成密鑰對
rsakey = RSA.generate(1024)
# 將秘鑰保存到文件中
with open("rsa.public.pem", mode="wb") as f:# 公鑰:rsa.public.pemf.write(rsakey.publickey().exportKey())with open("rsa.private.pem", mode="wb") as f:# 私鑰:rsa.private.pemf.write(rsakey.exportKey())
python中RSA加密
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64# 加密
data = "我喜歡你"
with open("rsa.public.pem", mode="r") as f:pk = f.read()rsa_pk = RSA.importKey(pk)# 基于公鑰創建加密對象rsa = PKCS1_v1_5.new(rsa_pk)result = rsa.encrypt(data.encode("utf-8"))# 處理成b64方便傳輸b64_result = base64.b64encode(result).decode("utf-8")print(b64_result)
python中RSA解密
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64data = 'IIw+I9D3YhccQDBpH6mwmPT5MExW7NUlrrcrXaEEBF54NYPVfaV5Mb+ps3CCictOiCZMv4jSETZp6H1b3tW3FwHFCojxtFnMSn/RpH0HTfFrJQm7yVwF+qoQQqz8Fj5/qdQk2ejruXkvK21CYwl1REiFY1+1Req4WMChRB1bWuw='
# 解密
with open("rsa.private.pem", mode="r") as f:prikey = f.read()rsa_pk = RSA.importKey(prikey)# 創建解密對象rsa = PKCS1_v1_5.new(rsa_pk)result = rsa.decrypt(base64.b64decode(data), None)print("rsa解密數據:::", result.decode("utf-8"))