def rsa_decrypt(encrypted_data, pem, password=None): """ rsa 解密 :param encrypted_data: 待解密 bytes :param pem: RSA private key 内容/binary :param password: RSA private key pass phrase :return: 解密后的 binary """ from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding encrypted_data = to_binary(encrypted_data) pem = to_binary(pem) private_key = serialization.load_pem_private_key(pem, password, backend=default_backend()) data = private_key.decrypt( encrypted_data, padding=padding.OAEP( mgf=padding.MGF1(hashes.SHA1()), algorithm=hashes.SHA1(), label=None, ), ) return data
def rsa_encrypt(data, pem, b64_encode=True): """ rsa 加密 :param data: 待加密字符串/binary :param pem: RSA public key 内容/binary :param b64_encode: 是否对输出进行 base64 encode :return: 如果 b64_encode=True 的话,返回加密并 base64 处理后的 string;否则返回加密后的 binary """ from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding encoded_data = to_binary(data) pem = to_binary(pem) public_key = serialization.load_pem_public_key(pem, backend=default_backend()) encrypted_data = public_key.encrypt( encoded_data, padding=padding.OAEP( mgf=padding.MGF1(hashes.SHA1()), algorithm=hashes.SHA1(), label=None, ), ) if b64_encode: encrypted_data = base64.b64encode(encrypted_data).decode("utf-8") return encrypted_data
def _encrypt(self, text, _id): text = to_binary(text) tmp_list = [] tmp_list.append(to_binary(self.get_random_string())) length = struct.pack(b"I", socket.htonl(len(text))) tmp_list.append(length) tmp_list.append(text) tmp_list.append(to_binary(_id)) text = b"".join(tmp_list) text = PKCS7Encoder.encode(text) ciphertext = to_binary(self.cipher.encrypt(text)) return base64.b64encode(ciphertext)
def encode(cls, text): length = len(text) padding_count = cls.block_size - length % cls.block_size if padding_count == 0: padding_count = cls.block_size padding = to_binary(chr(padding_count)) return text + padding * padding_count
def _decrypt(self, text, _id, exception=None): text = to_binary(text) plain_text = self.cipher.decrypt(base64.b64decode(text)) padding = plain_text[-1] content = plain_text[16:-padding] xml_length = socket.ntohl(struct.unpack(b"I", content[:4])[0]) xml_content = to_text(content[4:xml_length + 4]) from_id = to_text(content[xml_length + 4:]) if from_id != _id: exception = exception or Exception raise exception() return xml_content
def get_qrcode_url(self, ticket, data=None): """ 通过 ticket 换取二维码地址 详情请参考 https://iot.weixin.qq.com/wiki/new/index.html?page=3-4-4 :param ticket: 二维码 ticket :param data: 额外数据 :return: 二维码地址 """ url = f"https://we.qq.com/d/{ticket}" if data: if isinstance(data, (dict, tuple, list)): data = urllib.urlencode(data) data = to_text(base64.b64encode(to_binary(data))) url = f"{url}#{data}" return url
def update_account(self, account, nickname, password): """ 更新客服账号 详情请参考 http://mp.weixin.qq.com/wiki/1/70a29afed17f56d537c833f89be979c9.html :param account: 完整客服账号,格式为:账号前缀@公众号微信号 :param nickname: 客服昵称,最长6个汉字或12个英文字符 :param password: 客服账号登录密码 :return: 返回的 JSON 数据包 """ password = to_binary(password) password = hashlib.md5(password).hexdigest() return self._post( "https://api.weixin.qq.com/customservice/kfaccount/update", data={ "kf_account": account, "nickname": nickname, "password": password }, )
def send_message(self, device_type, device_id, user_id, content): """ 主动发送消息给设备 详情请参考 https://iot.weixin.qq.com/wiki/new/index.html?page=3-4-3 :param device_type: 设备类型,目前为“公众账号原始ID” :param device_id: 设备ID :param user_id: 微信用户账号的openid :param content: 消息内容,BASE64编码 :return: 返回的 JSON 数据包 """ content = to_text(base64.b64encode(to_binary(content))) return self._post( "transmsg", data={ "device_type": device_type, "device_id": device_id, "open_id": user_id, "content": content, }, )
def __base64_decode(self, text): return to_text(base64.b64decode(to_binary(text)))
def __init__(self, token, encoding_aes_key, _id): encoding_aes_key = to_binary(encoding_aes_key + "=") self.key = base64.b64decode(encoding_aes_key) assert len(self.key) == 32 self.token = token self._id = _id
def __init__(self, key): self.key = to_binary(hashlib.md5(to_binary(key)).hexdigest()) assert len(self.key) == 32
def format_url(params, api_key=None): data = [to_binary(f"{k}={params[k]}") for k in sorted(params) if params[k]] if api_key: data.append(to_binary(f"key={api_key}")) return b"&".join(data)
def _decrypt(self, text, exception=None): text = to_binary(text) plain_text = self.cipher.decrypt(base64.b64decode(text)) padding = plain_text[-1] content = plain_text[:-padding] return content
def _encrypt(self, text): text = to_binary(text) text = PKCS7Encoder.encode(text) ciphertext = to_binary(self.cipher.encrypt(text)) return base64.b64encode(ciphertext)