# -*- coding: utf-8 -*-
#pycrypto==2.6.1 # https://www.dlitz.net/software/pycrypto/
import hmac
import hashlib
import base64
import codecs
import random, string
from Crypto.Cipher import AES
from django.conf import settings
class OTCHandler(object):
CIPHER_KEY_LEN = 16
OTC_CONFIGURATION = settings.TREASURE_BOX_TOKEN
ENCRYPTION_METHOD = AES
# caculate signature by given time
def sign(self, unixTime):
message = str(unixTime) + self.OTC_CONFIGURATION['APP_URL']
signature = base64.b64encode(hmac.new(codecs.encode(self.OTC_CONFIGURATION['APP_SECRET']), codecs.encode(message), hashlib.sha256).digest())
# return bytes result in string
return str(signature).split('\'')[1]
# add padding to message
def pad(self, s):
return s + (AES.block_size - len(s) % AES.block_size) * chr(AES.block_size - len(s) % AES.block_size)
def encryptUID(self, uid):
# generate random 16 characters for iv value
CIPHER_IV = ''.join(random.choice(string.ascii_lowercase + string.digits) for i in range(16))
encryptedUID = self.encrypt(self.OTC_CONFIGURATION['APP_SECRET'], CIPHER_IV, uid)
return self.OTC_CONFIGURATION['APP_PASSPHRASE'] + encryptedUID
# encrypt input data with given key and iv
def encrypt(self, key, iv, data):
if len(key) < self.CIPHER_KEY_LEN:
numPad = self.CIPHER_KEY_LEN - len(key)
for i in range(numPad):
key+='0'
elif len(key) > self.CIPHER_KEY_LEN:
key = key[:self.CIPHER_KEY_LEN]
encryptor = self.ENCRYPTION_METHOD.new(key.encode("utf8"), self.ENCRYPTION_METHOD.MODE_CBC, iv.encode("utf8"))
base64_EncryptedData = base64.b64encode(encryptor.encrypt(self.pad(data).encode("utf8")))
base64_IV = base64.b64encode(iv.encode("utf8"))
# convert bytes result to string
base64_EncryptedData = str(base64_EncryptedData).split('\'')[1]
base64_IV = str(base64_IV).split('\'')[1]
return base64_EncryptedData + ':' + base64_IV
def appID(self):
return self.OTC_CONFIGURATION['APP_ID']
def appURL(self):
return self.OTC_CONFIGURATION['APP_URL']
def appKey(self):
return self.OTC_CONFIGURATION['APP_KEY']此文件为父类,封装了signature与UID加密算法。(signature为单向加密,UID为双向加密)
