Example #1
0
    def _encrypt_message(self, msg, nonce, timestamp=None):
        """将公众号回复用户的消息加密打包

        :param msg: 待回复用户的消息,xml格式的字符串
        :param nonce: 随机串,可以自己生成,也可以用URL参数的nonce
        :param timestamp: 时间戳,可以自己生成,也可以用URL参数的timestamp,如为None则自动用当前时间
        :return: 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串
        """
        xml = """<xml>
<Encrypt><![CDATA[{encrypt}]]></Encrypt>
<MsgSignature><![CDATA[{signature}]]></MsgSignature>
<TimeStamp>{timestamp}</TimeStamp>
<Nonce><![CDATA[{nonce}]]></Nonce>
</xml>"""
        nonce = to_binary(nonce)
        timestamp = to_binary(timestamp) or to_binary(int(time.time()))
        encrypt = self.__pc.encrypt(to_text(msg), self.__id)
        # 生成安全签名
        signature = get_sha1_signature(self.__token, timestamp, nonce, encrypt)
        return to_text(xml.format(
            encrypt=to_text(encrypt),
            signature=to_text(signature),
            timestamp=to_text(timestamp),
            nonce=to_text(nonce)
        ))
Example #2
0
def format_url(params, api_key=None):
    data = [
        to_binary('{0}={1}'.format(k, params[k])) for k in sorted(params)
        if params[k]
    ]
    if api_key:
        data.append(to_binary('key={0}'.format(api_key)))
    return b"&".join(data)
Example #3
0
    def __init__(self, token, encoding_aes_key, _id):
        """构造函数

        :param token: 公众平台上,开发者设置的Token
        :param encoding_aes_key: 公众平台上,开发者设置的EncodingAESKey
        :param _id: 公众号的 appid 或企业号的 corpid
        """
        self.__key = base64.b64decode(to_binary(encoding_aes_key) + to_binary('='))
        if len(self.__key) != 32:
            raise ValidateAESKeyError(encoding_aes_key)
        self.__token = to_binary(token)
        self.__id = to_binary(_id)
        self.__pc = BaseCrypto(self.__key)
Example #4
0
    def __init__(self, token, encoding_aes_key, _id):
        """构造函数

        :param token: 公众平台上,开发者设置的Token
        :param encoding_aes_key: 公众平台上,开发者设置的EncodingAESKey
        :param _id: 公众号的 appid 或企业号的 corpid
        """
        self.__key = base64.b64decode(to_binary(encoding_aes_key) + '=')
        if len(self.__key) != 32:
            raise ValidateAESKeyError(encoding_aes_key)
        self.__token = to_binary(token)
        self.__id = to_binary(_id)
        self.__pc = BaseCrypto(self.__key)
Example #5
0
    def get_random_str(self):
        """ 随机生成16位字符串

        @return: 16位字符串
        """
        rule = string.ascii_letters + string.digits
        return to_binary("".join(random.sample(rule, 16)))
Example #6
0
 def __str__(self):
     _repr = 'Error code: {code}, message: {msg}'.format(code=self.errcode,
                                                         msg=self.errmsg)
     if six.PY2:
         return to_binary(_repr)
     else:
         return to_text(_repr)
Example #7
0
 def __str__(self):
     if six.PY2:
         return to_binary('{code}: {msg}'.format(code=self.errcode,
                                                 msg=self.errmsg))
     else:
         return to_text('{code}: {msg}'.format(code=self.errcode,
                                               msg=self.errmsg))
Example #8
0
    def get_random_str(self):
        """ 随机生成16位字符串

        @return: 16位字符串
        """
        rule = string.ascii_letters + string.digits
        return to_binary("".join(random.sample(rule, 16)))
Example #9
0
 def __repr__(self):
     _repr = '{klass}({code}, {msg})'.format(klass=self.__class__.__name__,
                                             code=self.errcode,
                                             msg=self.errmsg)
     if six.PY2:
         return to_binary(_repr)
     else:
         return to_text(_repr)
Example #10
0
def get_sha1_signature(token, timestamp, nonce, encrypt):
    """
    用 SHA1 算法生成安全签名
    @param token: 票据
    @param timestamp: 时间戳
    @param encrypt: 密文
    @param nonce: 随机字符串
    @return: 安全签名
    """

    try:
        sortlist = [token, timestamp, nonce, to_binary(encrypt)]
        sortlist.sort()
        sha = hashlib.sha1()
        sha.update(to_binary("").join(sortlist))
        return sha.hexdigest()
    except Exception as e:
        raise CryptoComputeSignatureError(e)
Example #11
0
    def _decrypt_message(self, msg, msg_signature, timestamp, nonce):
        """检验消息的真实性,并且获取解密后的明文

        :param msg: 密文,对应POST请求的数据
        :param msg_signature: 签名串,对应URL参数的msg_signature
        :param timestamp: 时间戳,对应URL参数的timestamp
        :param nonce: 随机串,对应URL参数的nonce
        :return: 解密后的原文
        """
        timestamp = to_binary(timestamp)
        nonce = to_binary(nonce)
        try:
            msg = xmltodict.parse(to_text(msg))['xml']
        except Exception as e:
            raise ParseError(e)

        encrypt = msg['Encrypt']
        signature = get_sha1_signature(self.__token, timestamp, nonce, encrypt)
        if signature != msg_signature:
            raise ValidateSignatureError()
        return self.__pc.decrypt(encrypt, self.__id)
Example #12
0
    def _decrypt_message(self, msg, msg_signature, timestamp, nonce):
        """检验消息的真实性,并且获取解密后的明文

        :param msg: 密文,对应POST请求的数据
        :param msg_signature: 签名串,对应URL参数的msg_signature
        :param timestamp: 时间戳,对应URL参数的timestamp
        :param nonce: 随机串,对应URL参数的nonce
        :return: 解密后的原文
        """
        timestamp = to_binary(timestamp)
        nonce = to_binary(nonce)
        if isinstance(msg, six.string_types):
            try:
                msg = xmltodict.parse(to_text(msg))['xml']
            except Exception as e:
                raise ParseError(e)

        encrypt = msg['Encrypt']
        signature = get_sha1_signature(self.__token, timestamp, nonce, encrypt)
        if signature != msg_signature:
            raise ValidateSignatureError()
        return self.__pc.decrypt(encrypt, self.__id)
Example #13
0
 def encode(cls, text):
     """
     对需要加密的明文进行填充补位
     @param text: 需要进行填充补位操作的明文
     @return: 补齐明文字符串
     """
     text_length = len(text)
     # 计算需要填充的位数
     amount_to_pad = cls.block_size - (text_length % cls.block_size)
     if amount_to_pad == 0:
         amount_to_pad = cls.block_size
     # 获得补位所用的字符
     pad = to_binary(chr(amount_to_pad))
     return text + pad * amount_to_pad
    def _encrypt_message(self, msg, nonce, timestamp=None):
        """将公众号回复用户的消息加密打包

        :param msg: 待回复用户的消息,xml格式的字符串
        :param nonce: 随机串,可以自己生成,也可以用URL参数的nonce
        :param timestamp: 时间戳,可以自己生成,也可以用URL参数的timestamp,如为None则自动用当前时间
        :return: 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串
        """
        xml = """<xml>
<Encrypt><![CDATA[{encrypt}]]></Encrypt>
<MsgSignature><![CDATA[{signature}]]></MsgSignature>
<TimeStamp>{timestamp}</TimeStamp>
<Nonce><![CDATA[{nonce}]]></Nonce>
</xml>"""
        nonce = to_binary(nonce)
        timestamp = to_binary(timestamp) or to_binary(int(time.time()))
        encrypt = self.__pc.encrypt(to_text(msg), self.__id)
        # 生成安全签名
        signature = get_sha1_signature(self.__token, timestamp, nonce, encrypt)
        return to_text(
            xml.format(encrypt=to_text(encrypt),
                       signature=to_text(signature),
                       timestamp=to_text(timestamp),
                       nonce=to_text(nonce)))
Example #15
0
 def __str__(self):
     if six.PY2:
         return to_binary(
             'Error code: {code}, message: {msg}. Pay Error code: {pay_code}, message: {pay_msg}'
             .format(code=self.return_code,
                     msg=self.return_msg,
                     pay_code=self.errcode,
                     pay_msg=self.errmsg))
     else:
         return to_text(
             'Error code: {code}, message: {msg}. Pay Error code: {pay_code}, message: {pay_msg}'
             .format(code=self.return_code,
                     msg=self.return_msg,
                     pay_code=self.errcode,
                     pay_msg=self.errmsg))
Example #16
0
    def encrypt(self, text, appid):
        """对明文进行加密

        @param text: 需要加密的明文
        @return: 加密得到的字符串
        """
        # 16位随机字符串添加到明文开头
        text = self.get_random_str() + struct.pack("I", socket.htonl(len(text))) + to_binary(text) + appid
        # 使用自定义的填充方式对明文进行补位填充
        pkcs7 = PKCS7Encoder()
        text = pkcs7.encode(text)
        # 加密
        cryptor = AES.new(self.key, self.mode, self.key[:16])
        try:
            ciphertext = cryptor.encrypt(text)
            # 使用BASE64对加密后的字符串进行编码
            return base64.b64encode(ciphertext)
        except Exception as e:
            raise EncryptAESError(e)
Example #17
0
 def __str__(self):
     if six.PY2:
         return to_binary(self.message)
     else:
         return to_text(self.message)
Example #18
0
 def __str__(self):
     if six.PY2:
         return to_binary('{code}: {msg}'.format(code=self.errcode, msg=self.errmsg))
     else:
         return to_text('{code}: {msg}'.format(code=self.errcode, msg=self.errmsg))
Example #19
0
 def get_random_str(self):
     return to_binary('doraemonext')
Example #20
0
 def __str__(self):
     if six.PY2:
         return to_binary(self.message)
     else:
         return to_text(self.message)