示例#1
0
    def decrypt(self, memo):
        """ Decrypt a memo

            :param str memo: encrypted memo message
            :returns: encrypted memo
            :rtype: str
        """
        if not memo:
            return None

        # We first try to decode assuming we received the memo
        if isinstance(memo, dict) and "to" in memo and "from" in memo and "memo" in memo:
            memo_to = Account(memo["to"], steem_instance=self.steem)
            memo_from = Account(memo["from"], steem_instance=self.steem)
            message = memo["memo"]
        else:
            memo_to = self.to_account
            memo_from = self.from_account
            message = memo
        if isinstance(memo, dict) and "nonce" in memo:
            nonce = memo.get("nonce")
        else:
            nonce = ""

        try:
            memo_wif = self.steem.wallet.getPrivateKeyForPublicKey(
                memo_to["memo_key"]
            )
            pubkey = memo_from["memo_key"]
        except MissingKeyError:
            try:
                # if that failed, we assume that we have sent the memo
                memo_wif = self.steem.wallet.getPrivateKeyForPublicKey(
                    memo_from["memo_key"]
                )
                pubkey = memo_to["memo_key"]
            except MissingKeyError:
                # if all fails, raise exception
                raise MissingKeyError(
                    "Non of the required memo keys are installed!"
                    "Need any of {}".format(
                    [memo_to["name"], memo_from["name"]]))

        if not hasattr(self, 'chain_prefix'):
            self.chain_prefix = self.steem.prefix

        if message[0] == '#':
            return BtsMemo.decode_memo(
                PrivateKey(memo_wif),
                message
            )
        else:
            return BtsMemo.decode_memo_bts(
                PrivateKey(memo_wif),
                PublicKey(pubkey, prefix=self.chain_prefix),
                nonce,
                message
            )
示例#2
0
 def test_encrypt_decrypt(self):
     base58 = u'#HU6pdQ4Hh8cFrDVooekRPVZu4BdrhAe9RxrWrei2CwfAApAPdM4PT5mSV9cV3tTuWKotYQF6suyM4JHFBZz4pcwyezPzuZ2na7uwhRcLqFotsqxWRBpaXkNks2QCnYLS8'
     text = u'#爱'
     nonce = u'1462976530069648'
     wif = str(PasswordKey("", "", role="", prefix="STM").get_private_key())
     private_key = PrivateKey(wif=wif, prefix="STM")
     public_key = private_key.pubkey
     cypertext = encode_memo(private_key,
                             public_key,
                             nonce,
                             text,
                             prefix="STM")
     self.assertEqual(cypertext, base58)
     plaintext = decode_memo(private_key, cypertext)
     self.assertEqual(plaintext, text)
示例#3
0
    def decrypt_binary(self, infile, outfile, buffer_size=2048):
        """ Decrypt a binary file

            :param str infile: encrypted binary file
            :param str outfile: output file name
            :param int buffer_size: read buffer size
            :returns: encrypted memo information
            :rtype: dict
        """
        if not os.path.exists(infile):
            raise ValueError("%s does not exists!" % infile)
        if buffer_size % 16 != 0:
            raise ValueError("buffer_size must be dividable by 16")
        with open(infile, 'rb') as fin:
            memo_size = struct.unpack('<Q', fin.read(struct.calcsize('<Q')))[0]
            memo = fin.read(memo_size)
            orig_file_size = struct.unpack('<Q', fin.read(struct.calcsize('<Q')))[0]
        memo = '#' + base58encode(hexlify(memo).decode("ascii"))
        memo_to = self.to_account
        memo_from = self.from_account
        from_key, to_key, nonce, check, cipher = BtsMemo.extract_memo_data(memo)
        if memo_to is None and memo_from is None:
            try:
                memo_wif = self.blockchain.wallet.getPrivateKeyForPublicKey(
                    str(to_key)
                )
                pubkey = from_key
            except MissingKeyError:
                try:
                    # if that failed, we assume that we have sent the memo
                    memo_wif = self.blockchain.wallet.getPrivateKeyForPublicKey(
                        str(from_key)
                    )
                    pubkey = to_key
                except MissingKeyError:
                    # if all fails, raise exception
                    raise MissingKeyError(
                        "Non of the required memo keys are installed!"
                        "Need any of {}".format(
                        [str(to_key), str(from_key)]))
        elif memo_to is not None and memo_from is not None and isinstance(memo_from, PrivateKey):
            memo_wif = memo_from
            if isinstance(memo_to, Account):
                pubkey = memo_to["memo_key"]
            else:
                pubkey = memo_to
        elif memo_to is not None and memo_from is not None and isinstance(memo_to, PrivateKey):
            memo_wif = memo_to
            if isinstance(memo_from, Account):
                pubkey = memo_from["memo_key"]
            else:
                pubkey = memo_from           
        else:
            
            try:
                memo_wif = self.blockchain.wallet.getPrivateKeyForPublicKey(
                    memo_to["memo_key"]
                )
                pubkey = memo_from["memo_key"]
            except MissingKeyError:
                try:
                    # if that failed, we assume that we have sent the memo
                    memo_wif = self.blockchain.wallet.getPrivateKeyForPublicKey(
                        memo_from["memo_key"]
                    )
                    pubkey = memo_to["memo_key"]
                except MissingKeyError:
                    # if all fails, raise exception
                    raise MissingKeyError(
                        "Non of the required memo keys are installed!"
                        "Need any of {}".format(
                        [memo_to["name"], memo_from["name"]]))        

        if not hasattr(self, 'chain_prefix'):
            self.chain_prefix = self.blockchain.prefix
        priv = PrivateKey(memo_wif)
        pubkey = PublicKey(pubkey, prefix=self.chain_prefix)
        beem_version = BtsMemo.decode_memo(
                priv,
                memo
            )
        shared_secret = BtsMemo.get_shared_secret(priv, pubkey)
        # Init encryption
        aes, checksum = BtsMemo.init_aes(shared_secret, nonce)
        with open(infile, 'rb') as fin:
            memo_size = struct.unpack('<Q', fin.read(struct.calcsize('<Q')))[0]
            memo = fin.read(memo_size)
            file_size = struct.unpack('<Q', fin.read(struct.calcsize('<Q')))[0]
            with open(outfile, 'wb') as fout:
                while True:
                    data = fin.read(buffer_size)
                    n = len(data)
                    if n == 0:
                        break
                    decd = aes.decrypt(data)
                    n = len(decd)
                    if file_size > n:
                        fout.write(decd)
                    else:
                        fout.write(decd[:file_size]) # <- remove padding on last block
                    file_size -= n        
        return {
            "file_size": orig_file_size,
            "from_key": str(from_key),
            "to_key": str(to_key),
            "nonce": nonce,
            "beem_version": beem_version
        }
示例#4
0
    def decrypt(self, memo):
        """ Decrypt a memo

            :param str memo: encrypted memo message
            :returns: encrypted memo
            :rtype: str
        """
        if not memo:
            return None
        memo_wif = None
        # We first try to decode assuming we received the memo
        if isinstance(memo, dict) and "to" in memo and "from" in memo and "memo" in memo:
            memo_to = Account(memo["to"], blockchain_instance=self.blockchain)
            memo_from = Account(memo["from"], blockchain_instance=self.blockchain)
            message = memo["memo"]
        else:
            memo_to = self.to_account
            memo_from = self.from_account
            message = memo
        if isinstance(memo, dict) and "nonce" in memo:
            nonce = memo.get("nonce")
        else:
            nonce = ""
        
        if memo_to is None or memo_from is None:
            from_key, to_key, nonce, check, cipher = BtsMemo.extract_memo_data(message)
            try:
                memo_wif = self.blockchain.wallet.getPrivateKeyForPublicKey(
                    str(to_key)
                )
                pubkey = from_key
            except MissingKeyError:
                try:
                    # if that failed, we assume that we have sent the memo
                    memo_wif = self.blockchain.wallet.getPrivateKeyForPublicKey(
                        str(from_key)
                    )
                    pubkey = to_key
                except MissingKeyError:
                    # if all fails, raise exception
                    raise MissingKeyError(
                        "Non of the required memo keys are installed!"
                        "Need any of {}".format(
                        [str(to_key), str(from_key)]))
        elif memo_to is not None and memo_from is not None and isinstance(memo_from, PrivateKey):
            memo_wif = memo_from
            pubkey = memo_to
        elif memo_to is not None and memo_from is not None and isinstance(memo_to, PrivateKey):
            memo_wif = memo_to
            pubkey = memo_from           
        else:
            try:
                memo_wif = self.blockchain.wallet.getPrivateKeyForPublicKey(
                    memo_to["memo_key"]
                )
                pubkey = memo_from["memo_key"]
            except MissingKeyError:
                try:
                    # if that failed, we assume that we have sent the memo
                    memo_wif = self.blockchain.wallet.getPrivateKeyForPublicKey(
                        memo_from["memo_key"]
                    )
                    pubkey = memo_to["memo_key"]
                except MissingKeyError:
                    # if all fails, raise exception
                    raise MissingKeyError(
                        "Non of the required memo keys are installed!"
                        "Need any of {}".format(
                        [memo_to["name"], memo_from["name"]]))

        if not hasattr(self, 'chain_prefix'):
            self.chain_prefix = self.blockchain.prefix

        if message[0] == '#' or memo_to is None or memo_from is None:
            return BtsMemo.decode_memo(
                PrivateKey(memo_wif),
                message
            )
        else:
            return BtsMemo.decode_memo_bts(
                PrivateKey(memo_wif),
                PublicKey(pubkey, prefix=self.chain_prefix),
                nonce,
                message
            )
示例#5
0
 def test_decrypt(self):
     for memo in test_cases:
         dec = decode_memo(PrivateKey(memo["wif"]), memo["message"])
         self.assertEqual(memo["plain"], dec)
示例#6
0
 def test_decrypt_bugged_padding(self):
     for memo in not_enough_padding:
         dec = decode_memo(PrivateKey(memo["wif"]), memo["message"])
         self.assertEqual(memo["plain"], dec[1:])