Example #1
0
 def try_skipped_keys(self, hcrypt, hnonce, mcrypt, mnonce):
     for mk, hkr in self.skipped_HK_MK.items():
         try: nacl.crypto_secretbox_open(hcrypt, hnonce, hkr)
         except: continue
         try: msg = nacl.crypto_secretbox_open(mcrypt, mnonce, mk)
         except: continue
         del self.skipped_HK_MK[mk]
         return msg
Example #2
0
File: chaining.py Project: stef/pbp
 def decrypt(self, cipher, nonce):
     if self.in_k == (b'\0' * nacl.crypto_scalarmult_curve25519_BYTES):
         # use pk crypto to decrypt the packet
         return nacl.crypto_box_open(cipher, nonce, self.peer_id.cp, self.me_id.cs)
     else:
         # decrypt using chained keys
         try:
             return nacl.crypto_secretbox_open(cipher, nonce, self.in_k)
         except ValueError:
             # with previous key in case a prev send failed to be delivered
             return nacl.crypto_secretbox_open(cipher, nonce, self.in_prev)
Example #3
0
 def try_skipped_keys(self, hcrypt, hnonce, mcrypt, mnonce):
     for mk, hkr in self.skipped_HK_MK.items():
         try:
             nacl.crypto_secretbox_open(hcrypt, hnonce, hkr)
         except:
             continue
         try:
             msg = nacl.crypto_secretbox_open(mcrypt, mnonce, mk)
         except:
             continue
         del self.skipped_HK_MK[mk]
         return msg
Example #4
0
 def decrypt(self, cipher, nonce):
     if self.in_k == (b'\0' * nacl.crypto_scalarmult_curve25519_BYTES):
         # use pk crypto to decrypt the packet
         return nacl.crypto_box_open(cipher, nonce, self.peer_id.cp,
                                     self.me_id.cs)
     else:
         # decrypt using chained keys
         try:
             return nacl.crypto_secretbox_open(cipher, nonce, self.in_k)
         except ValueError:
             # with previous key in case a prev send failed to be delivered
             return nacl.crypto_secretbox_open(cipher, nonce, self.in_prev)
  def data_received(self, data):
    if verbose: print('Data received: ', data)

    try:
      data = pysodium.crypto_sign_open(data, self.handler.getserverkey())
    except ValueError:
      raise ValueError('invalid signature.\nabort')

    if data!=b'ok' and (data[:-42] == b'fail' or len(data)!=sphinxlib.DECAF_255_SER_BYTES+42):
        raise ValueError('fail')

    if not self.b:
      self.cb()
      return

    rwd=sphinxlib.finish(self.pwd, self.b, data[:sphinxlib.DECAF_255_SER_BYTES])

    if self.handler.namesite is not None:
      if self.handler.namesite['name'].encode() not in self.handler.list(self.handler.namesite['site']):
        self.handler.cacheuser(self.handler.namesite)

    rule = data[sphinxlib.DECAF_255_SER_BYTES:]
    if len(rule)!=42:
      raise ValueError('fail')
    rk = pysodium.crypto_generichash(self.handler.getkey(),self.handler.getsalt())
    rule = pysodium.crypto_secretbox_open(rule[24:], rule[:24],rk)
    rule = struct.unpack(">H",rule)[0]
    size = (rule & 0x7f)
    rule = {c for i,c in enumerate(('u','l','s','d')) if (rule >> 7) & (1 << i)}
    self.cb(bin2pass.derive(rwd,rule,size).decode())
Example #6
0
def decrypt(pkt, pwd=None, k=None, retries=3):
    # decrypts a message symmetrically using crypto_secretbox
    # pkt is a (nonce, ciphertext) tuple
    # k specifies an encryption key, which if not supplied, is derived from
    # pwd which is queried from the user, if also not specified.
    clearpwd = (pwd is None)
    cleark = (k is None)
    cnt = 0
    res = None
    while cnt < retries:
        if not k:
            if not pwd:
                pwd = getpass.getpass('\nPassphrase for decrypting: ')
            k = scrypt.hash(pwd, scrypt_salt)[:nacl.crypto_secretbox_KEYBYTES]
            if clearpwd:
                clearmem(pwd)
                pwd = None
        try:
            res = nacl.crypto_secretbox_open(pkt[1], pkt[0], k)
        except ValueError:
            cnt += 1
            if cleark:
                clearmem(k)
                k = None
            continue
        break
    if cleark and k:
        clearmem(k)
        k = None
    if res:
        return res
Example #7
0
File: pbp.py Project: fpletz/pbp
def decrypt(pkt, pwd=None, k=None, retries=3):
    # decrypts a message symmetrically using crypto_secretbox
    # pkt is a (nonce, ciphertext) tuple
    # k specifies an encryption key, which if not supplied, is derived from
    # pwd which is queried from the user, if also not specified.
    cleark = (pwd is None)
    clearpwd = (k is None)
    cnt=0
    res = None
    while cnt<retries:
        if not k:
            if not pwd:
                pwd = getpass.getpass('\nPassphrase for decrypting: ')
            k =  scrypt.hash(pwd, scrypt_salt)[:nacl.crypto_secretbox_KEYBYTES]
            if clearpwd: clearmem(pwd)
            pwd = None
        try:
            res = nacl.crypto_secretbox_open(pkt[1], pkt[0], k)
        except ValueError:
            cnt += 1
            if cleark: clearmem(k)
            k = None
            continue
        break
    if cleark: clearmem(k)
    if res:
        return res
Example #8
0
 def decrypt_with_user_pw(self, filename, pw_for):
     with open(filename, 'rb') as fd:
         nonce = fd.read(nacl.crypto_secretbox_NONCEBYTES)
         prompt = 'Passphrase for decrypting {0} for {1}: '.format(
             pw_for, self.name)
         k = scrypt.hash(getpass.getpass(prompt),
                         pbp.scrypt_salt)[:nacl.crypto_secretbox_KEYBYTES]
         return nacl.crypto_secretbox_open(fd.read(), nonce, k)
Example #9
0
def decrypt_blob(blob):
    # todo implement padding
    sk = get_sealkey()
    nonce = blob[:pysodium.crypto_secretbox_NONCEBYTES]
    blob = blob[pysodium.crypto_secretbox_NONCEBYTES:]
    res = pysodium.crypto_secretbox_open(blob, nonce, sk)
    clearmem(sk)
    return res
Example #10
0
 def __decrypt(self, encrypted):
     keyFile = open('logo', 'r')
     key = base64.b64decode(keyFile.read())
     keyFile.close()
     decoded = base64.b64decode(encrypted)
     nonce = decoded[:pysodium.crypto_secretbox_NONCEBYTES]
     ciph = decoded[pysodium.crypto_secretbox_NONCEBYTES:]
     return pysodium.crypto_secretbox_open(ciph, nonce, key).decode()
Example #11
0
    def open(self, nut):
        '''decrypt and verify the integrity of a nut returned by a client

        returns the original nut passed to seal
        '''
        box = urlsafe_b64decode(nut)
        nonce = box[:na.crypto_secretbox_NONCEBYTES]
        ct = box[na.crypto_secretbox_NONCEBYTES:]
        pt = na.crypto_secretbox_open(ct, nonce, self.__key)
        return Nut(*self.NUTBOX.unpack(pt))
Example #12
0
def scrypt_decrypt(data, password):
    buf = io.BytesIO(data)
    memlimit = int.from_bytes(buf.read(4), "little")
    opslimit = int.from_bytes(buf.read(4), "little")
    salt = buf.read(pysodium.crypto_pwhash_scryptsalsa208sha256_SALTBYTES)
    if isinstance(password, str): password = password.encode("utf-8")
    key = pysodium.crypto_pwhash_scryptsalsa208sha256(pysodium.crypto_secretbox_KEYBYTES, password, salt, memlimit, opslimit)
    nonce = buf.read(pysodium.crypto_secretbox_NONCEBYTES)
    cyphertext = buf.read()
    return pysodium.crypto_secretbox_open(cyphertext, nonce, key)
Example #13
0
def decrypt_message(bytes_, key, pubkeyhash):
    version, nonce, encrypted = outer_pack.unpack(bytes_)
    decrypted = pysodium.crypto_secretbox_open(encrypted, nonce, key)
    decrypted_record = parse_innerbox(decrypted)
    if not validate_pubkey(decrypted_record.pubkey, pubkeyhash):
        raise PubkeyError()
    if version != decrypted_record.inner_ver:
        # The version on the outside doesn't match the version that the other
        # end signed!
        raise SignatureError()
    return decrypted_record
Example #14
0
    def decode(self, jdata):
        """ Decode message using libsodium

        :param str jdata: jdata to load
        :return: the Encoded message
        """
        ckmsg = self.loads(jdata)
        return Message.loads(
            pysodium.crypto_secretbox_open(
                base64.b64decode(ckmsg["data"]),
                base64.b64decode(ckmsg["nonce"]),
                base64.b64decode(self.secretbox_key)).decode('utf-8'))
Example #15
0
def session_input (_inbound_key, _inbound_nonce, _encrypted) :
	
	pysodium.sodium_increment (_inbound_nonce)
	log ("[8408f904]", "[crypto][input]", "using nonce `%s`;", _inbound_nonce.encode ("b64"))
	
	log ("[62fc5bf5]", "[crypto][input]", "decoding packet (encrypted) `%s`...", _encrypted.encode ("b64"))
	
	_packet = pysodium.crypto_secretbox_open (_encrypted, _inbound_nonce, _inbound_key)
	
	log ("[7eeb53a0]", "[crypto][input]", "decoded packet (plain) `%s`;", _packet.encode ("b64"))
	
	return _packet
Example #16
0
File: pbp.py Project: dnet/pbp
def decrypt(pkt, pwd=None, basedir=None, k=None):
    # symmetric
    cleark = (pwd is None)
    clearpwd = (k is None)
    if not k:
        if not pwd:
            pwd = getpass.getpass('Passphrase for decrypting: ')
        k = scrypt.hash(pwd, scrypt_salt)[:nacl.crypto_secretbox_KEYBYTES]
        if clearpwd: clearmem(pwd)
    res = nacl.crypto_secretbox_open(pkt[1], pkt[0], k)
    if cleark: clearmem(k)
    return res
def unlock_private_key(private_key):
    private_key = base64.b64decode(private_key)

    if private_key[0] == b'y':
        sbytes = pysodium.crypto_pwhash_SALTBYTES
        nbytes = pysodium.crypto_box_NONCEBYTES
        salt  = private_key[1:sbytes+1]
        nonce = private_key[sbytes+1: sbytes+nbytes+1]
        cyphertext = private_key[sbytes+nbytes+1:]
        key = hash_password(getpass.getpass(), salt)
        private_key = pysodium.crypto_secretbox_open(cyphertext, nonce, key)
        return private_key
    return private_key[1:]
Example #18
0
def unlock_private_key(private_key_b64: str) -> bytes:
    private_key: bytes = base64.b64decode(private_key_b64)

    if private_key[0] == b'y':
        sbytes: int = pysodium.crypto_pwhash_SALTBYTES
        nbytes: int = pysodium.crypto_box_NONCEBYTES
        salt: bytes = private_key[1:sbytes + 1]
        nonce: bytes = private_key[sbytes + 1:sbytes + nbytes + 1]
        cyphertext: bytes = private_key[sbytes + nbytes + 1:]
        key: bytes = hash_password(getpass.getpass(), salt)
        private_key = pysodium.crypto_secretbox_open(cyphertext, nonce, key)
        return private_key
    else:
        return private_key[1:]
Example #19
0
 def decrypt_keys(self, topic, msgval=None):
   if (isinstance(topic,(bytes,bytearray))):
     self._logger.debug("passed a topic in bytes (should be string)")
     topic = topic.decode('utf-8')
   #
   # msgval should be a msgpacked chain.
   # The public key in the array is a set of public key(s) to combine with our
   # encryption key to get the secret to decrypt the key. If we do not
   # have an encryption key for the topic, we cannot do it until we have one.
   # The next item is then the pair of random values for generating the shared
   # secret, followed by the actual key message.
   #
   try:
     with self.__allowdenylist_lock:
       pk,pkprint = process_chain(msgval,topic,'key-encrypt',allowlist=self.__allowlist,denylist=self.__denylist)
     if (len(pk) < 5):
       if not (pkprint is None):
         raise ProcessChainError("Unexpected number of chain elements:", pkprint)
       else:
         raise ValueError("Unexpected number of chain elements!")
     random0 = pk[3][0]
     random1 = pk[3][1]
     nonce = pk[4][0:pysodium.crypto_secretbox_NONCEBYTES]
     msg = pk[4][pysodium.crypto_secretbox_NONCEBYTES:]
     eks = self.__cryptokey.use_epk(topic, 'decrypt_keys', pk[2], clear=False)
     for ck in eks:
       # Construct candidate shared secrets as sha256(topic || random0 || random1 || our_private*their_public)
       ss = pysodium.crypto_hash_sha256(topic.encode('utf-8') + random0 + random1 + ck)[0:pysodium.crypto_secretbox_KEYBYTES]
       # decrypt and return key
       try:
         msg = msgpack.unpackb(pysodium.crypto_secretbox_open(msg,nonce,ss),raw=True)
         rvs = {}
         for i in range(0,len(msg),2):
           rvs[msg[i]] = msg[i+1]
         if len(rvs) < 1 or 2*len(rvs) != len(msg):
           raise ValueError
       except:
         pass
       else:
         # clear the esk/epk we just used
         self.__cryptokey.use_epk(topic, 'decrypt_keys', [])
         return rvs
     raise ValueError
   except Exception as e:
     self._logger.warning("".join(format_exception_shim(e)))
     pass
   return None
Example #20
0
    def from_encoded_key(cls, key, passphrase=''):
        """ Creates a key object from a base58 encoded key.

        :param key: a public or secret key in base58 encoding
        :param passphrase: the passphrase used if the key provided is an encrypted private key
        """
        key = scrub_input(key)

        curve = key[:2]  # "sp", "p2" "ed"
        if curve not in [b'sp', b'p2', b'ed']:
            raise ValueError("Invalid prefix for a key encoding.")
        if not len(key) in [54, 55, 88, 98]:
            raise ValueError("Invalid length for a key encoding.")

        encrypted = (key[2:3] == b'e')
        public_or_secret = key[3:5] if encrypted else key[2:4]
        if public_or_secret not in [b'pk', b'sk']:
            raise Exception("Invalid prefix for a key encoding.")

        key = base58_decode(key)
        is_secret = (public_or_secret == b'sk')
        if not is_secret:
            return cls.from_public_point(key, curve)

        if encrypted:
            if not passphrase:
                raise ValueError(
                    "Encrypted key provided without a passphrase.")
            if isinstance(passphrase, str):
                passphrase = passphrase.encode()
            assert isinstance(
                passphrase, bytes
            ), f'expected bytes or str, got {type(passphrase).__name__}'

            salt, encrypted_sk = key[:8], key[8:]
            encryption_key = hashlib.pbkdf2_hmac(hash_name="sha512",
                                                 password=passphrase,
                                                 salt=salt,
                                                 iterations=32768,
                                                 dklen=32)
            key = pysodium.crypto_secretbox_open(c=encrypted_sk,
                                                 nonce=b'\000' * 24,
                                                 k=encryption_key)
            del passphrase

        return cls.from_secret_exponent(key, curve)
Example #21
0
    def from_encoded_key(
        cls,
        key: Union[str, bytes],
        passphrase: PassphraseInput = None,
    ) -> 'Key':
        """Creates a key object from a base58 encoded key.

        :param key: a public or secret key in base58 encoding
        :param passphrase: the passphrase used if the key provided is an encrypted private key,
            if not set value from from PYTEZOS_PASSPHRASE env variable will be used or promted dynamically
        """
        encoded_key = scrub_input(key)

        curve = encoded_key[:2]  # "sp", "p2" "ed"
        if curve not in [b'sp', b'p2', b'ed']:
            raise ValueError("Invalid prefix for a key encoding.")
        if not len(encoded_key) in [54, 55, 88, 98]:
            raise ValueError("Invalid length for a key encoding.")

        encrypted = encoded_key[2:3] == b'e'
        public_or_secret = encoded_key[3:5] if encrypted else encoded_key[2:4]
        if public_or_secret not in [b'pk', b'sk']:
            raise Exception("Invalid prefix for a key encoding.")

        encoded_key = base58_decode(encoded_key)
        is_secret = public_or_secret == b'sk'
        if not is_secret:
            return cls.from_public_point(encoded_key, curve)

        if encrypted:
            passphrase = get_passphrase(passphrase)

            salt, encrypted_sk = encoded_key[:8], encoded_key[8:]
            encryption_key = hashlib.pbkdf2_hmac(hash_name="sha512",
                                                 password=passphrase,
                                                 salt=salt,
                                                 iterations=32768,
                                                 dklen=32)
            encoded_key = pysodium.crypto_secretbox_open(
                c=encrypted_sk,
                nonce=b'\000' * 24,
                k=encryption_key,
            )
            del passphrase

        return cls.from_secret_exponent(encoded_key, curve)
    def test_destructure_decrypt_decode_verbose(self):
        """
        Strictly verify the content and behaviour of the serializer,
        and how the encryption functions are used.
        """
        encrypted = self.obj.dumps(SESSION).encode('utf-8')

        dec = urlsafe_b64decode(encrypted)
        key = crypto_generichash(app.secret_key,
                                 outlen=crypto_secretbox_KEYBYTES)
        n = dec[:crypto_secretbox_NONCEBYTES]
        c = dec[crypto_secretbox_NONCEBYTES:]
        m = crypto_secretbox_open(c, n, key)

        session = self.obj.serializer.loads(m)
        assert session[self.obj.timestamp_key]
        del session[self.obj.timestamp_key]
        assert SESSION == session
Example #23
0
 def decrypt_with_user_pw(self, filename, pw_for):
     with file(filename) as fd:
         nonce = fd.read(nacl.crypto_secretbox_NONCEBYTES)
         prompt = 'Passphrase for decrypting {0} for {1}: '.format(pw_for, self.name)
         k = scrypt.hash(getpass.getpass(prompt), pbp.scrypt_salt)[:nacl.crypto_secretbox_KEYBYTES]
         return nacl.crypto_secretbox_open(fd.read(), nonce, k)
Example #24
0
 def decrypt(self, pkt):
     peer, key = self.keydecrypt(pkt[1])
     if key:
         return peer, nacl.crypto_secretbox_open(pkt[2], pkt[0], key)
Example #25
0
def run_server():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind((server_ip, server_port))

    log('[INFO] Listening on '+server_ip+':'+str(server_port))

    # NONCE(24) + MAC(16) + MAGIC(8) + SIGNPUB(32) + SIG(64) + COUNTER(14) + LEN(2) + REST

    PROTO_MIN_SIZE = 160

    magic_bin = '42f9708e2f1369d9'.decode('hex') # chosen by fair die
    server_ip_bin = socket.inet_aton(server_ip)

    # FIXME: lock state file for duration of the program
    counter = read_counter()

    while True:
        try:
            client_ip, client_port = (None, None)
            cdata, (client_ip, client_port) = sock.recvfrom(1024)

            if len(cdata) < PROTO_MIN_SIZE:
                # normal: a UDP scan would cause this
                log('[INFO] small packet', client_ip, client_port)
                continue

            pkt_nonce = cdata[:pysodium.crypto_secretbox_NONCEBYTES]

            try:
                plain = pysodium.crypto_secretbox_open(cdata[pysodium.crypto_secretbox_NONCEBYTES:],
                                                       pkt_nonce,
                                                       server_private_key)
            except:
                # normal-ish: any big enough packet to the port will cause
                # this, but unless knockd happens to run on a common UDP
                # port there's not much reason to see such a big packet
                log('[INFO] incorrect ciphertext', client_ip, client_port)
                continue

            pkt_magic = plain[:8]
            plain = plain[8:]

            if pkt_magic != magic_bin:
                # unrecognised protocol version
                log('[WARN] unrecognised version magic', client_ip, client_port, pkt_magic.encode('hex'))
                continue

            pkt_sign_pub = plain[:32]
            plain = plain[32:]

            if pkt_sign_pub not in client_sign_keys:
                log('[WARN] unrecognised client sign key', client_ip, client_port, pkt_sign_pub.encode('hex'))
                continue

            pkt_sig = plain[:64]
            plain = plain[64:]

            pkt_counter_bin = plain[:14]
            pkt_counter = int(pkt_counter_bin.encode('hex'), 16)
            plain = plain[14:]

            # check counter early so we don't need to verify replays
            if pkt_counter <= counter:
                log('[POSSIBLE_REPLAY] bad counter', client_ip, client_port)
                continue

            try:
                pysodium.crypto_sign_verify_detached(pkt_sig,
                                                     (pkt_nonce + magic_bin + pkt_sign_pub +
                                                      pkt_counter_bin + plain +
                                                      server_private_key + server_ip_bin),
                                                     pkt_sign_pub)
            except:
                # shenanigans, the data isn't signed by that user
                log('[SEVERE] bad signature', client_ip, client_port)
                continue

            pkt_data_len_bin = plain[:2]
            pkt_data_len = int(pkt_data_len_bin.encode('hex'), 16)
            plain = plain[2:]

            pkt_data = plain[:pkt_data_len]

            # Cool, write that counter ASAP so the packet can't be used again
            counter = pkt_counter
            write_counter(counter)

            log('[INFO] valid knock', client_ip, client_port)

            # NB. do *not* trust that client_ip is the originator (beyond
            # port knocking functionality). A person who can perform
            # packet captures can race the packet from their own IP
            subprocess.Popen([knocked_command, client_ip, pkt_data])


        except KeyboardInterrupt:
            break

        except Exception as e:
            log('[ERROR] packet exception', client_ip, client_port, e)
Example #26
0
 def decrypt(self, m):
     n = m[:crypto_secretbox_NONCEBYTES]
     c = m[crypto_secretbox_NONCEBYTES:]
     return crypto_secretbox_open(c, n, self.key)
Example #27
0
    def recv(self, msg):
        """
        as per https://github.com/trevp/axolotl/wiki/newversion (Nov 19, 2013 · 41 revisions)

        Receiving messages
        -------------------
        Local variables:
          MK  : message key
          Np  : Purported message number
          PNp : Purported previous message number
          CKp : Purported new chain key
          DHp : Purported new DHr
          RKp : Purported new root key
          NHKp, HKp : Purported new header keys

        if (plaintext = try_skipped_header_and_message_keys()):
          return plaintext

        if Dec(HKr, header):
          Np = read()
          CKp, MK = stage_skipped_header_and_message_keys(HKr, Nr, Np, CKr)
          if not Dec(MK, ciphertext):
            raise undecryptable
          if bobs_first_message:
            DHRr = read()
            RK = HASH(RK || ECDH(DHRs, DHRr))
            HKs = NHKs
            NHKs, CKs = KDF(RK)
            erase(DHRs)
            bobs_first_message = False
        else:
          if not Dec(NHKr, header):
            raise undecryptable()
          Np, PNp, DHRp = read()
          stage_skipped_header_and_message_keys(HKr, Nr, PNp, CKr)
          RKp = HASH(RK || ECDH(DHRs, DHRr))
          HKp = NHKr
          NHKp, CKp = KDF(RKp)
          CKp, MK = stage_skipped_header_and_message_keys(HKp, 0, Np, CKp)
          if not Dec(MK, ciphertext):
            raise undecryptable()
          RK = RKp
          HKr = HKp
          NHKr = NHKp
          DHRr = DHRp
          RK = HASH(RK || ECDH(DHRs, DHRr))
          HKs = NHKs
          NHKs, CKs = KDF(RK)
          erase(DHRs)
        commit_skipped_header_and_message_keys()
        Nr = Np + 1
        CKr = CKp
        return read()
        """

        hnonce = msg[:nacl.crypto_secretbox_NONCEBYTES]
        i = nacl.crypto_secretbox_NONCEBYTES
        mnonce = msg[i:i+nacl.crypto_secretbox_NONCEBYTES]
        i += nacl.crypto_secretbox_NONCEBYTES
        hcrypt = msg[i:i + nacl.crypto_secretbox_MACBYTES + 4 + 4 + nacl.crypto_scalarmult_curve25519_BYTES]
        i += nacl.crypto_secretbox_MACBYTES + 4 + 4 + nacl.crypto_scalarmult_curve25519_BYTES
        mcrypt = msg[i:]

        ret = self.try_skipped_keys(hcrypt, hnonce, mcrypt, mnonce)
        if ret:
            return ret

        headers = None
        try: headers = nacl.crypto_secretbox_open(hcrypt, hnonce, self.HKr)
        except: pass
        if headers:
            Np = struct.unpack('>I',headers[:4])[0]
            CKp, MK = self.stage_skipped_keys(self.HKr, self.Nr, Np, self.CKr)
            msg = nacl.crypto_secretbox_open(mcrypt, mnonce, MK)
            if self.bobs1stmsg:
                self.DHRr = headers[8:]
                self.RK = nacl.crypto_generichash(self.RK, nacl.crypto_scalarmult_curve25519(self.DHRs.sk,self.DHRr), KEY_SIZE)
                self.HKs = self.NHKs
                if self.isalice:
                    self.NHKs = nacl.crypto_generichash(self.RK, "NHKs", KEY_SIZE)
                    self.CKs = nacl.crypto_generichash(self.RK, "CKs", KEY_SIZE)
                else:
                    self.NHKs = nacl.crypto_generichash(self.RK, "NHKr", KEY_SIZE)
                    self.CKs = nacl.crypto_generichash(self.RK, "CKr", KEY_SIZE)
                self.DHRs.clear()
                self.DHRs = None
                self.bobs1stmsg = False
        else:
            headers = nacl.crypto_secretbox_open(hcrypt, hnonce, self.NHKr)
            #unpack header fields
            Np = struct.unpack('>I',headers[:4])[0]
            PNp = struct.unpack('>I',headers[4:8])[0]
            DHRp = headers[8:]
            self.stage_skipped_keys(self.HKr, self.Nr, PNp, self.CKr)
            RKp = nacl.crypto_generichash(self.RK, nacl.crypto_scalarmult_curve25519(self.DHRs.sk,self.DHRr), KEY_SIZE)
            HKp = self.NHKr
            if self.isalice:
                NHKp = nacl.crypto_generichash(RKp, "NHKr", KEY_SIZE)
                CKp = nacl.crypto_generichash(RKp, "CKr", KEY_SIZE)
            else:
                NHKp = nacl.crypto_generichash(RKp, "NHKs", KEY_SIZE)
                CKp = nacl.crypto_generichash(RKp, "CKs", KEY_SIZE)
            CKp, MK = self.stage_skipped_keys(HKp, 0, Np, CKp)
            msg = nacl.crypto_secretbox_open(mcrypt, mnonce, MK)
            self.RK = RKp
            self.HKr = HKp
            self.NHKr = NHKp
            self.DHRr = DHRp
            self.RK = nacl.crypto_generichash(self.RK, nacl.crypto_scalarmult_curve25519(self.DHRs.sk,self.DHRr), KEY_SIZE)
            self.HKs = self.NHKs
            if self.isalice:
                self.NHKs = nacl.crypto_generichash(self.RK, "NHKs", KEY_SIZE)
                self.CKs = nacl.crypto_generichash(self.RK, "CKs", KEY_SIZE)
            else:
                self.NHKs = nacl.crypto_generichash(self.RK, "NHKr", KEY_SIZE)
                self.CKs = nacl.crypto_generichash(self.RK, "CKr", KEY_SIZE)
            self.DHRs.clear()
            self.DHRs = None

        # commit_skipped_header_and_message_keys() : Commits any skipped-over message keys from the
        # staging area to persistent storage (along with their associated header keys).
        self.skipped_HK_MK.update(self.staged_HK_MK)
        self.staged_HK_MK = {}

        self.Nr = Np + 1
        self.CKr = CKp
        return msg
Example #28
0
    def recv(self, msg):
        """
        as per https://github.com/trevp/axolotl/wiki/newversion (Nov 19, 2013 · 41 revisions)

        Receiving messages
        -------------------
        Local variables:
          MK  : message key
          Np  : Purported message number
          PNp : Purported previous message number
          CKp : Purported new chain key
          DHp : Purported new DHr
          RKp : Purported new root key
          NHKp, HKp : Purported new header keys

        if (plaintext = try_skipped_header_and_message_keys()):
          return plaintext

        if Dec(HKr, header):
          Np = read()
          CKp, MK = stage_skipped_header_and_message_keys(HKr, Nr, Np, CKr)
          if not Dec(MK, ciphertext):
            raise undecryptable
          if bobs_first_message:
            DHRr = read()
            RK = HASH(RK || ECDH(DHRs, DHRr))
            HKs = NHKs
            NHKs, CKs = KDF(RK)
            erase(DHRs)
            bobs_first_message = False
        else:
          if not Dec(NHKr, header):
            raise undecryptable()
          Np, PNp, DHRp = read()
          stage_skipped_header_and_message_keys(HKr, Nr, PNp, CKr)
          RKp = HASH(RK || ECDH(DHRs, DHRr))
          HKp = NHKr
          NHKp, CKp = KDF(RKp)
          CKp, MK = stage_skipped_header_and_message_keys(HKp, 0, Np, CKp)
          if not Dec(MK, ciphertext):
            raise undecryptable()
          RK = RKp
          HKr = HKp
          NHKr = NHKp
          DHRr = DHRp
          RK = HASH(RK || ECDH(DHRs, DHRr))
          HKs = NHKs
          NHKs, CKs = KDF(RK)
          erase(DHRs)
        commit_skipped_header_and_message_keys()
        Nr = Np + 1
        CKr = CKp
        return read()
        """

        hnonce = msg[:nacl.crypto_secretbox_NONCEBYTES]
        i = nacl.crypto_secretbox_NONCEBYTES
        mnonce = msg[i:i + nacl.crypto_secretbox_NONCEBYTES]
        i += nacl.crypto_secretbox_NONCEBYTES
        hcrypt = msg[i:i + nacl.crypto_secretbox_MACBYTES + 4 + 4 +
                     nacl.crypto_scalarmult_curve25519_BYTES]
        i += nacl.crypto_secretbox_MACBYTES + 4 + 4 + nacl.crypto_scalarmult_curve25519_BYTES
        mcrypt = msg[i:]

        ret = self.try_skipped_keys(hcrypt, hnonce, mcrypt, mnonce)
        if ret:
            return ret

        headers = None
        try:
            headers = nacl.crypto_secretbox_open(hcrypt, hnonce, self.HKr)
        except:
            pass
        if headers:
            Np = struct.unpack('>I', headers[:4])[0]
            CKp, MK = self.stage_skipped_keys(self.HKr, self.Nr, Np, self.CKr)
            msg = nacl.crypto_secretbox_open(mcrypt, mnonce, MK)
            if self.bobs1stmsg:
                self.DHRr = headers[8:]
                self.RK = nacl.crypto_generichash(
                    self.RK,
                    nacl.crypto_scalarmult_curve25519(self.DHRs.sk, self.DHRr),
                    KEY_SIZE)
                self.HKs = self.NHKs
                if self.isalice:
                    self.NHKs = nacl.crypto_generichash(
                        self.RK, "NHKs", KEY_SIZE)
                    self.CKs = nacl.crypto_generichash(self.RK, "CKs",
                                                       KEY_SIZE)
                else:
                    self.NHKs = nacl.crypto_generichash(
                        self.RK, "NHKr", KEY_SIZE)
                    self.CKs = nacl.crypto_generichash(self.RK, "CKr",
                                                       KEY_SIZE)
                self.DHRs.clear()
                self.DHRs = None
                self.bobs1stmsg = False
        else:
            headers = nacl.crypto_secretbox_open(hcrypt, hnonce, self.NHKr)
            #unpack header fields
            Np = struct.unpack('>I', headers[:4])[0]
            PNp = struct.unpack('>I', headers[4:8])[0]
            DHRp = headers[8:]
            self.stage_skipped_keys(self.HKr, self.Nr, PNp, self.CKr)
            RKp = nacl.crypto_generichash(
                self.RK,
                nacl.crypto_scalarmult_curve25519(self.DHRs.sk, self.DHRr),
                KEY_SIZE)
            HKp = self.NHKr
            if self.isalice:
                NHKp = nacl.crypto_generichash(RKp, "NHKr", KEY_SIZE)
                CKp = nacl.crypto_generichash(RKp, "CKr", KEY_SIZE)
            else:
                NHKp = nacl.crypto_generichash(RKp, "NHKs", KEY_SIZE)
                CKp = nacl.crypto_generichash(RKp, "CKs", KEY_SIZE)
            CKp, MK = self.stage_skipped_keys(HKp, 0, Np, CKp)
            msg = nacl.crypto_secretbox_open(mcrypt, mnonce, MK)
            self.RK = RKp
            self.HKr = HKp
            self.NHKr = NHKp
            self.DHRr = DHRp
            self.RK = nacl.crypto_generichash(
                self.RK,
                nacl.crypto_scalarmult_curve25519(self.DHRs.sk, self.DHRr),
                KEY_SIZE)
            self.HKs = self.NHKs
            if self.isalice:
                self.NHKs = nacl.crypto_generichash(self.RK, "NHKs", KEY_SIZE)
                self.CKs = nacl.crypto_generichash(self.RK, "CKs", KEY_SIZE)
            else:
                self.NHKs = nacl.crypto_generichash(self.RK, "NHKr", KEY_SIZE)
                self.CKs = nacl.crypto_generichash(self.RK, "CKr", KEY_SIZE)
            self.DHRs.clear()
            self.DHRs = None

        # commit_skipped_header_and_message_keys() : Commits any skipped-over message keys from the
        # staging area to persistent storage (along with their associated header keys).
        self.skipped_HK_MK.update(self.staged_HK_MK)
        self.staged_HK_MK = {}

        self.Nr = Np + 1
        self.CKr = CKp
        return msg
Example #29
0
 def decrypt(self, pkt):
     peer, key = self.keydecrypt(pkt[1])
     if key:
         message = nacl.crypto_secretbox_open(pkt[2], pkt[0], key)
         return peer, message.decode('utf-8')
Example #30
0
import json
import binascii
from PIL import Image
from pyzbar.pyzbar import decode
import pysodium

backup_password = '******'
data = decode(Image.open('backup_qr.png'))

res = json.loads(data[0].data)

salt = binascii.unhexlify(res['salt'])
nonce_and_ciphertext = binascii.unhexlify(res['seed'])

nonce = nonce_and_ciphertext[0:pysodium.crypto_secretbox_NONCEBYTES]
ciphertext = nonce_and_ciphertext[pysodium.crypto_secretbox_NONCEBYTES:]

pwhash = pysodium.crypto_pwhash(
    pysodium.crypto_auth_KEYBYTES, str.encode(backup_password), salt,
    pysodium.crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE,
    pysodium.crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE)

print(pysodium.crypto_secretbox_open(ciphertext, nonce, pwhash))
Example #31
0
 def __decrypt(self, encrypted):
     key = base64.b64decode(os.environ["ENCRYPTION_KEY"])
     decoded = base64.b64decode(encrypted)
     nonce = decoded[:pysodium.crypto_secretbox_NONCEBYTES]
     ciph = decoded[pysodium.crypto_secretbox_NONCEBYTES:]
     return pysodium.crypto_secretbox_open(ciph, nonce, key).decode()
Example #32
0
 def decrypt(self, pkt):
     source = None
     peer, key = self.keydecrypt(pkt[1])
     if key:
         return peer, nacl.crypto_secretbox_open(pkt[2], pkt[0], key)
Example #33
0
 def test_crypto_secretbox_open(self):
     k = pysodium.randombytes(pysodium.crypto_secretbox_KEYBYTES)
     n = pysodium.randombytes(pysodium.crypto_secretbox_NONCEBYTES)
     c = pysodium.crypto_secretbox(b"howdy", n, k)
     pysodium.crypto_secretbox_open(c, n, k)
Example #34
0
 def deserialize(self, topic, bytes_):
   if (isinstance(topic,(bytes,bytearray))):
     self._parent._logger.debug("passed a topic in bytes (should be string)")
     topic = topic.decode('utf-8')
   if bytes_ is None:
     return None
   root = self._parent.get_root(topic)
   if len(bytes_) < 1 or bytes_[0] != 1:
     return KafkaCryptoMessage.fromBytes(bytes_,deser=self,topic=topic)
   try:
     msg = msgpack.unpackb(bytes_[1:],raw=True)
     if (len(msg) != 3):
       raise KafkaCryptoSerializeError("Malformed Message!")
   except Exception as e:
     self._parent._logger.debug("".join(traceback.format_exception(etype=type(e), value=e, tb=e.__traceback__)))
     return KafkaCryptoMessage.fromBytes(bytes_,deser=self,topic=topic)
   ki = msg[0]
   salt = msg[1]
   msg = msg[2]
   self._parent._lock.acquire()
   i = 1
   initial_waiter = False
   try:
     while ((not (root in self._parent._cgens.keys()) or not (ki in self._parent._cgens[root].keys())) and i>0):
       if (not (root in self._parent._cwaits.keys()) or not (ki in self._parent._cwaits[root].keys())):
         self._parent._logger.debug("Setting initial wait for root=%s, key index=%s.", root, ki)
         initial_waiter = True
         # first time we see a topic/key index pair, we wait the initial interval for key exchange
         i = self._parent.DESER_INITIAL_WAIT_INTERVALS
         if not (root in self._parent._cwaits.keys()):
           self._parent._cwaits[root] = {}
         self._parent._cwaits[root][ki] = i
       elif initial_waiter:
         self._parent._cwaits[root][ki] -= 1
       elif (root in self._parent._cwaits.keys()) and (ki in self._parent._cwaits[root].keys()):
         i = self._parent._cwaits[root][ki]
       else:
         i = self.MAX_WAIT_INTERVALS
    	  ntp =	(root+self._parent.TOPIC_SUFFIX_KEYS)
    	  if not (ntp in self._parent._tps):
    	    self._parent._tps[ntp] = TopicPartition(ntp,0)
         self._parent._tps_offsets[ntp] = 0
         self._parent._tps_updated = True
       else:
         if not (root in self._parent._subs_needed):
           self._parent._subs_needed.append(root)
       i=i-1
       if (i > 0):
         self._parent._lock.release()
         sleep(self.WAIT_INTERVAL)
         self._parent._lock.acquire()
     if not (root in self._parent._cgens.keys()) or not (ki in self._parent._cgens[root].keys()):
       self._parent._logger.debug("No decryption key found for root=%s, key index=%s. Returning encrypted message.", root, ki)
       raise ValueError
     gen = self._parent._cgens[root][ki][self._kv]
     key,nonce = gen.generate(salt=salt)
     msg = KafkaCryptoMessage(pysodium.crypto_secretbox_open(msg,nonce,key),ipt=True)
   except:
     return KafkaCryptoMessage.fromBytes(bytes_,deser=self,topic=topic)
   finally:
     self._parent._lock.release()
   return msg
Example #35
0
 def test_crypto_secretbox_open(self):
     k = pysodium.randombytes(pysodium.crypto_secretbox_KEYBYTES)
     n = pysodium.randombytes(pysodium.crypto_secretbox_NONCEBYTES)
     c = pysodium.crypto_secretbox(b"howdy", n, k)
     pysodium.crypto_secretbox_open(c, n, k)
Example #36
0
 def decrypt(self, pkt):
     peer, key = self.keydecrypt(pkt[1])
     if key:
         message = nacl.crypto_secretbox_open(pkt[2], pkt[0], key)
         return peer, message.decode('utf-8')
 def decrypt(self, m):
     n = m[:crypto_secretbox_NONCEBYTES]
     c = m[crypto_secretbox_NONCEBYTES:]
     return crypto_secretbox_open(c, n, self.key)
Example #38
0
 def unwrap_opaque(self, crypto_opaque):
   try:
     return pysodium.crypto_secretbox_open(crypto_opaque[pysodium.crypto_secretbox_NONCEBYTES:],crypto_opaque[0:pysodium.crypto_secretbox_NONCEBYTES], self.__ek)
   except:
     return None