python aes 128 gcm
最近防沉迷的api用到aes 128 gcm
python 3版本
import json
from Crypto.Cipher import AES
import base64
import requests
import hashlib
import time
import os
import binascii
URL = "https://wlc.nppa.gov.cn/test/authentication/check"
KEY = "d10d8642c66c1c785aa32b194aba2afa"
APPID = "9177929f5010481b858f661a409fd764"
BIZID = "1101999999"
TEST_PARAMS = {"ai":"100000000000000001",
"name":"某一一",
"idNum":"110000190101010001"}
class AES_GCM(object):
def __init__(self, key):
self.key = key #秘钥
self.MODE = AES.MODE_GCM
self.iv = os.urandom(12)
def aes_encrypt(self, params):
aes = AES.new(binascii.unhexlify(self.key), self.MODE, self.iv)
params, tag=aes.encrypt_and_digest(json.dumps(params).encode("utf-8"))
base64_data= self.iv + params + tag
encrypted_text = str(base64.b64encode(base64_data), encoding='utf-8')
return encrypted_text
def aes_decrypt(self, encrypted_text):
encrypted_text = base64.b64decode(encrypted_text)
cipher = AES.new(binascii.unhexlify(self.key), self.MODE, encrypted_text[:12])
cc = cipher.decrypt_and_verify(encrypted_text[12:-16], encrypted_text[-16:])
return json.loads(cc)
def hash256(pre_hash_text):
hs256 = hashlib.sha256()
hs256.update(pre_hash_text.encode())
return hs256.hexdigest()
def sorted_params(params, param_="%s%s", none_keys = []):
return "".join([
param_ % i for i in
sorted(params.items(), key=lambda d:d[0]) if i[0] not in none_keys
])
def main():
aesobject = AES_GCM(KEY)
aes_gcm = aesobject.aes_encrypt(TEST_PARAMS)
body_data='{"data":"%s"}' % aes_gcm ## 国家游戏防沉迷的api试了不能进行json.dumps()
_time = str(int(time.time()*1000))
## 加入请求头报文
headers = {"Content-Type":"application/json; charset=utf-8","appId":APPID,"bizId":BIZID,"timestamps":_time}
## 对请求头报文排序并排除 不必要的字段进行字符串拼接
params_str = sorted_params(headers, none_keys=["Content-Type"])
headers["sign"] = hash256("".join([KEY, params_str, body_data]))
# print(aesobject.aes_decrypt(aes_gcm)) ## 解码
response = requests.post(URL, headers=headers, data= body_data)
print(response.json())
if __name__ == '__main__':
main()
兼容python3和python2 版本
因个别老系统可能还在使用python2进行维护,出个兼容版本
#coding:utf8
"""安装 cryptography 支持2.7+ and 3.4+ 建议在linux在调试 """
import sys
import os
import base64
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import (
Cipher, algorithms, modes
)
import binascii
PY2 = sys.version_info[0] == 2
if PY2:
reload(sys)
sys.setdefaultencoding("utf8") ## 在python2一定要加上,否则会出现编码问题
def encrypt(key, plaintext):
"""加密"""
iv = os.urandom(12)
encryptor = Cipher(
algorithms.AES(binascii.unhexlify(key)),
modes.GCM(iv),
backend=default_backend()
).encryptor()
plaintext = encryptor.update(plaintext)
finalize = encryptor.finalize() ##
tag = encryptor.tag
ciphertext =iv + plaintext+ finalize + tag
return base64.b64encode(ciphertext)
def decrypt(key, ciphertext):
"""解密"""
ciphertext = base64.b64decode(ciphertext)
decryptor = Cipher(
algorithms.AES(binascii.unhexlify(key)),
modes.GCM(ciphertext[:12], ciphertext[-16:]),
).decryptor()
return decryptor.update(ciphertext[12:-16]) + decryptor.finalize()
if __name__ =='__main__':
key = "d10d8642c66c1c785aa32b194aba2afa"
data = '{"ai":"100000000000000001","name":"某一一","idNum":"110000190101010001"}'
ciphertext = encrypt(key, data.encode("utf8")) ##
print(ciphertext)
print(decrypt(key, ciphertext))
查询是否认证示例代码
#coding:utf8
import requests
import hashlib
import time
url = "https://wlc.nppa.gov.cn/test/authentication/query?ai=100000000000000001"
key = "d10d8642c66c1c785aa32b194aba2afa"
def sorted_params(params, param_="%s%s", none_keys = []):
return "".join([
param_ % i for i in
sorted(params.items(), key=lambda d:d[0]) if i[0] not in none_keys
])
def hash256(pre_hash_text):
hs256 = hashlib.sha256()
hs256.update(pre_hash_text.encode())
return hs256.hexdigest()
_time = str(int(time.time()*1000))
headers = {"Content-Type":"application/json; charset=utf-8","ai":"100000000000000001",
"appId":"9177929f5010481b858f661a409fd764","bizId":"1101999999","timestamps":_time}
_str = sorted_params(headers, none_keys=["Content-Type"])
_str =key+_str ## 加密的key要放在最前面
sign = hash256(_str)
headers["sign"] = sign
headers.pop("ai", None) ## 最好去掉,不去掉也目前也是可以的
response = requests.get(url, headers=headers)
print(response.json())
返回结果示例,已认证会有pi值返回
{'errcode': 0, 'errmsg': 'OK', 'data': {'result': {'status': 0, 'pi': '1fffbjzos82bs9cnyj1dna7d6d29zg4esnh99u'}}}