def extract_ref_l(ref): """ 解析ref:长字符串 :param ref: :return: """ logger.debug('extract ref begin') if not ref or not isinstance(ref, str) or ref == '': return None ref = rc4_decrypt(ref, ref_pwd, a2b_hex) logger.debug(u'ref = %r', ref) if len(ref) <= 3: #至少要求3字节 return None head, acc_len, key_cipher_len = struct.unpack('>BBB', ref[:3]) logger.debug(u'head = %r, acc_len = %r, key_cipher_len = %r', head, acc_len, key_cipher_len) if len(ref) != 3 + acc_len + key_cipher_len + MAX_FILENAME_LEN: return None acc = ref[3:acc_len + 3] key_cipher = ref[acc_len + 3:acc_len + 3 + key_cipher_len] logger.debug(u'acc = %r, key_cipher = %r', acc, key_cipher) logger.debug(u'rc4 decrypt result = %r', rc4_decrypt(key_cipher, ref_pwd, None)) if acc != rc4_decrypt(key_cipher, ref_pwd, None): return None share, by_app = span_bits(head, 7, 6, 0) logger.debug('extract ref end') return share, by_app, acc, unpad(ref[-MAX_FILENAME_LEN:])
def decrypt(s, key, iv, seg_size, seg_ratio=3): """ :param seg_ratio: aes密文的长度必定为ratio的整数倍 """ if not s or not isinstance(s, str): return None # 1->2 binascii, one seg_ratio if 0 != len(s) % (2 * seg_ratio): return None _ = AES.new(key, AES.MODE_CFB, iv, segment_size=seg_size).decrypt(binascii.a2b_hex(s)) # unpadding return unpad(_)
def extract_tk_l(tk, ul): """ :param ul: 上传:长字符串 """ logger.debug('extract tk begin') if not tk or not isinstance(tk, str) or len(tk) <= 2: logger.info('tk too short') return None tk = rc4_decrypt(tk, tk_pwd, a2b_hex) logger.debug(u'tk = %r', tk) rnd, val = tk[-2:] val = rc4_decrypt(val, tk_pwd, None) logger.debug('rnd = %r, val = %r', rnd, val) rnd = struct.unpack('>B', rnd)[0] val = struct.unpack('>B', val)[0] logger.debug('rnd = %r, val = %r', rnd, val) if rnd + 1 != val: logger.warn('rnd={0} & val={1} unmatch'.format(rnd, val)) return None head, acc_len = struct.unpack('>BB', tk[:2]) logger.debug('head = %r, acc_len = %r', head, acc_len) if len(tk) != 2 + acc_len + 4 + MAX_FILENAME_LEN + 2: logger.warn('tk len not ok') return None #10分钟有效 ts_offset = 2 + acc_len t = struct.unpack('>I', tk[ts_offset:ts_offset + 4])[0] now = time.time() logger.debug('now = %r, t = %r', now, t) if now - struct.unpack('>I', tk[ts_offset:ts_offset + 4])[0] >= 600: logger.warn('tk timeout') logger.debug('now = %r, t = %r', now, t) return None share, by_app, is_ul = span_bits(head, 7, 5, 0) logger.debug('share = %r, by_app = %r, is_ul = %r, ul=%r', share, by_app, is_ul, ul) if is_ul != ul: logger.warn('ul param invalid') return None logger.debug('extract tk end') return share, by_app, tk[2:acc_len + 2], unpad(tk[ts_offset + 4:ts_offset + 4 + MAX_FILENAME_LEN])
def ecb_decrypt(text, key): """ decrypt request message @param key: 服务器预先分配的20字节随机串,aes加密和hmac-sha1校验密钥相关 @param text: 待解密的文本,前32字节为aes解密后的密文,后40字节为相关hmac-sha1校验值 """ if not key or not isinstance(key, str): return None if not text or not isinstance(text, str): return None text = binascii.unhexlify(text) aes_after = AES.new(key, AES.MODE_ECB).decrypt(text) return unpad(aes_after)