信封加密(Envelope Encryption)是一种应对海量数据的高性能加解密方案,国内的各种公有云都有密钥管理系统,简称 KMS(Key Management Service),该系统中就包含信封加密方案。
一图胜万言(图来自腾讯云文档):

名词解释:
加密核心流程:
1from Crypto.Cipher import AES
2key = b'Sixteen byte key' # 这里就是明文key(here is the plainkey)
3cipher = AES.new(key, AES.MODE_EAX)
4nonce = cipher.nonce
5ciphertext, tag = cipher.encrypt_and_digest(data) # 加密 data,返回 ciphertext(先忽略nonce和tag等)
解密核心流程:
加密数据 + 密文 key,你用密文 key 向 KMS 系统请求获得明文 key,然后你想起上面雪封很久的加密程序,心理想太好了。当初是我亲手加密的,现在亲手解密,一切就像回到从前,存封许久的密密文件由你来解码,感觉自己像军统特务,神秘且居功至伟,这是熟悉的感觉!1 from Crypto.Cipher import AES
2 key = b'Sixteen byte key' # 还是那个熟悉的明文key(the same plainkey)
3 cipher = AES.new(key, AES.MODE_EAX, nonce=nonce)
4 plaintext = cipher.decrypt(ciphertext) # 解密得到plantext
5 try:
6 cipher.verify(tag)
7 print("The message is authentic:", plaintext)
8 except ValueError:
9 print("Key incorrect or message corrupted")
好了,虚拟故事讲完了,现实中,你不是戴笠,也没有委员长给你撑腰。
苦哈哈写代码才是日常.....
所谓帮人帮到底,下面我给一个比较完整的伪代码示例:
1
2import requests
3import base64
4from Crypto.Cipher import AES #pip install pycryptodome
5
6
7url = "your_kms_url"
8
9
10def gen_signature(method, params, secret_key):
11
12 '''
13 signature
14 '''
15 pass
16
17
18def generate_data_key():
19 '''
20 get planinkey and cipherkey
21 '''
22 params = {
23 'xxx1': 'yyy1',
24 'xxx2': 'yyy2',
25 }
26 params['signature'] = gen_signature()
27 r = requests.get(url, params=params)
28 rdata = r.json()["data"]
29 plainkey, cipherkey = rdata["plaintext"], rdata["ciphertext"]
30 return plainkey,cipherkey
31
32
33def get_plainkey(cipherkey):
34 '''
35 use cipherkey get plainkey"
36 '''
37 params = {
38 'zzz1': 'mmm1'
39 'foo': 'bar'
40 }
41 params["ciphertext"] = cipherkey
42 params['signature'] = gen_signature()
43
44 r = requests.get(url, params=params)
45 rdata = r.json()["data"]
46 plainkey = rdata["plaintext"]
47 return plainkeypt
48
49
50def envelope_encrypt(plainkey):
51 '''encrypt'''
52 key = base64.b64decode(plainkey)
53 with open(to_be_encrypt_file, "rb") as f:
54 data = f.read()
55 cipher = AES.new(key, AES.MODE_SIV) # chose your aes mode
56 ciphertext, tag = cipher.encrypt_and_digest(data)
57
58 with open(encrypted_file,"wb") as file_out:
59 [ file_out.write(x) for x in (tag, ciphertext) ]
60
61def envelope_decrypt():
62 '''decrypt'''
63 with open(cipherkey_file,'r') as f:
64 cipherkey = f.read()
65 key = getDatakeyPlaintext(cipherkey)
66 key = base64.b64decode(key)
67 if key:
68 with open(encrypted_file,"rb") as file_in:
69 tag, ciphertext = [ file_in.read(x) for x in (16, -1) ]
70 cipher = AES.new(key, AES.MODE_SIV)
71 data = cipher.decrypt_and_verify(ciphertext,tag)
72 with open(decrypt_file,"wb") as file_origin:
73 file_origin.write(data)
74
75def upload_to_cloud(upload_file):
76 '''
77 upload cipherkey and secret file to cloud like aws s3
78 '''
79 pass
80
81
82if __name__ == "__main__":
83
84 to_be_encrypt_file = 'text.txt' # 待加密文件
85 encrypted_file = "secret.bin" # 加密后的文件
86 decrypt_file = "origin" # 解密后的文件
87 cipherkey_file = "cipherkey"
88
89 plainkey, cipherkey = generate_data_key()
90
91 # encryt
92 envelope_encrypt(plainkey)
93
94 #upload
95 upload_to_cloud(upload_file)
96
97 # decrpyt at someday
98 #envelope_decrypt()
上面的伪代码只是反应了核心流程,还需要读者根据自己的业务状况修改。
信封加密(Envelope Encryption)是一种应对海量数据的高性能加解密方案,国内的各种公有云都有密钥管理系统,简称 KMS(Key Management Service),该系统中就包含信封加密方案。
一图胜万言(图来自腾讯云文档):

名词解释:
加密核心流程:
1from Crypto.Cipher import AES
2key = b'Sixteen byte key' # 这里就是明文key(here is the plainkey)
3cipher = AES.new(key, AES.MODE_EAX)
4nonce = cipher.nonce
5ciphertext, tag = cipher.encrypt_and_digest(data) # 加密 data,返回 ciphertext(先忽略nonce和tag等)
解密核心流程:
加密数据 + 密文 key,你用密文 key 向 KMS 系统请求获得明文 key,然后你想起上面雪封很久的加密程序,心理想太好了。当初是我亲手加密的,现在亲手解密,一切就像回到从前,存封许久的密密文件由你来解码,感觉自己像军统特务,神秘且居功至伟,这是熟悉的感觉!1 from Crypto.Cipher import AES
2 key = b'Sixteen byte key' # 还是那个熟悉的明文key(the same plainkey)
3 cipher = AES.new(key, AES.MODE_EAX, nonce=nonce)
4 plaintext = cipher.decrypt(ciphertext) # 解密得到plantext
5 try:
6 cipher.verify(tag)
7 print("The message is authentic:", plaintext)
8 except ValueError:
9 print("Key incorrect or message corrupted")
好了,虚拟故事讲完了,现实中,你不是戴笠,也没有委员长给你撑腰。
苦哈哈写代码才是日常.....
所谓帮人帮到底,下面我给一个比较完整的伪代码示例:
1
2import requests
3import base64
4from Crypto.Cipher import AES #pip install pycryptodome
5
6
7url = "your_kms_url"
8
9
10def gen_signature(method, params, secret_key):
11
12 '''
13 signature
14 '''
15 pass
16
17
18def generate_data_key():
19 '''
20 get planinkey and cipherkey
21 '''
22 params = {
23 'xxx1': 'yyy1',
24 'xxx2': 'yyy2',
25 }
26 params['signature'] = gen_signature()
27 r = requests.get(url, params=params)
28 rdata = r.json()["data"]
29 plainkey, cipherkey = rdata["plaintext"], rdata["ciphertext"]
30 return plainkey,cipherkey
31
32
33def get_plainkey(cipherkey):
34 '''
35 use cipherkey get plainkey"
36 '''
37 params = {
38 'zzz1': 'mmm1'
39 'foo': 'bar'
40 }
41 params["ciphertext"] = cipherkey
42 params['signature'] = gen_signature()
43
44 r = requests.get(url, params=params)
45 rdata = r.json()["data"]
46 plainkey = rdata["plaintext"]
47 return plainkeypt
48
49
50def envelope_encrypt(plainkey):
51 '''encrypt'''
52 key = base64.b64decode(plainkey)
53 with open(to_be_encrypt_file, "rb") as f:
54 data = f.read()
55 cipher = AES.new(key, AES.MODE_SIV) # chose your aes mode
56 ciphertext, tag = cipher.encrypt_and_digest(data)
57
58 with open(encrypted_file,"wb") as file_out:
59 [ file_out.write(x) for x in (tag, ciphertext) ]
60
61def envelope_decrypt():
62 '''decrypt'''
63 with open(cipherkey_file,'r') as f:
64 cipherkey = f.read()
65 key = getDatakeyPlaintext(cipherkey)
66 key = base64.b64decode(key)
67 if key:
68 with open(encrypted_file,"rb") as file_in:
69 tag, ciphertext = [ file_in.read(x) for x in (16, -1) ]
70 cipher = AES.new(key, AES.MODE_SIV)
71 data = cipher.decrypt_and_verify(ciphertext,tag)
72 with open(decrypt_file,"wb") as file_origin:
73 file_origin.write(data)
74
75def upload_to_cloud(upload_file):
76 '''
77 upload cipherkey and secret file to cloud like aws s3
78 '''
79 pass
80
81
82if __name__ == "__main__":
83
84 to_be_encrypt_file = 'text.txt' # 待加密文件
85 encrypted_file = "secret.bin" # 加密后的文件
86 decrypt_file = "origin" # 解密后的文件
87 cipherkey_file = "cipherkey"
88
89 plainkey, cipherkey = generate_data_key()
90
91 # encryt
92 envelope_encrypt(plainkey)
93
94 #upload
95 upload_to_cloud(upload_file)
96
97 # decrpyt at someday
98 #envelope_decrypt()
上面的伪代码只是反应了核心流程,还需要读者根据自己的业务状况修改。