Example #1
0
 def test_crypto_box_open(self):
     m = b"howdy"
     pk, sk = pysodium.crypto_box_keypair()
     n = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES)
     c = pysodium.crypto_box(m, n, pk, sk)
     plaintext = pysodium.crypto_box_open(c, n, pk, sk)
     self.assertEqual(m, plaintext)
Example #2
0
def encrypt_message(nonce, public_key, secret_key, message):
	lenmessage = struct.pack("<I", len(message))+message
	encrypted = pysodium.crypto_box(lenmessage, nonce, public_key, secret_key)
	encrypted = nonce + "\x00"*16 + encrypted
	length = struct.pack("<I", len(encrypted))
	
	return length+encrypted
Example #3
0
    def test_AsymCrypto_With_Seeded_Keypair(self):
        msg     = b"correct horse battery staple"
        nonce   = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES)
        pk, sk = pysodium.crypto_box_seed_keypair("howdy")

        c = pysodium.crypto_box(msg, nonce, pk, sk)
        m = pysodium.crypto_box_open(c, nonce, pk, sk)

        self.assertEqual(msg, m)
Example #4
0
    def test_AsymCrypto_With_Seeded_Keypair(self):
        msg = b"correct horse battery staple"
        nonce = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES)
        pk, sk = pysodium.crypto_box_seed_keypair("howdy")

        c = pysodium.crypto_box(msg, nonce, pk, sk)
        m = pysodium.crypto_box_open(c, nonce, pk, sk)

        self.assertEqual(msg, m)
Example #5
0
 def handle(self):
     data, socket = self.request
     unsealed = pysodium.crypto_box_seal_open(data, pk, sk)
     ap = unsealed[:pysodium.crypto_box_PUBLICKEYBYTES]
     challenge = unsealed[pysodium.crypto_box_PUBLICKEYBYTES:]
     packets.append(ap)
     nonce = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES)
     response = pysodium.crypto_box(challenge, nonce, ap, sk)
     dst = (src2dst(self.client_address[0]), REG_PORT)
     socket.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
     socket.sendto(nonce + response, dst)
Example #6
0
File: chaining.py Project: stef/pbp
    def encrypt(self,plain):
        if self.out_k == (b'\0' * nacl.crypto_scalarmult_curve25519_BYTES):
            # encrypt using public key
            nonce = nacl.randombytes(nacl.crypto_box_NONCEBYTES)
            cipher= nacl.crypto_box(plain, nonce, self.peer_id.cp, self.me_id.cs)
        else:
            # encrypt using chaining mode
            nonce = nacl.randombytes(nacl.crypto_secretbox_NONCEBYTES)
            cipher = nacl.crypto_secretbox(plain, nonce, self.out_k)

        return cipher, nonce
Example #7
0
    def encrypt(self, plain):
        if self.out_k == (b'\0' * nacl.crypto_scalarmult_curve25519_BYTES):
            # encrypt using public key
            nonce = nacl.randombytes(nacl.crypto_box_NONCEBYTES)
            cipher = nacl.crypto_box(plain, nonce, self.peer_id.cp,
                                     self.me_id.cs)
        else:
            # encrypt using chaining mode
            nonce = nacl.randombytes(nacl.crypto_secretbox_NONCEBYTES)
            cipher = nacl.crypto_secretbox(plain, nonce, self.out_k)

        return cipher, nonce
Example #8
0
 def save(self):
     keyfdir = "%s/sk/.%s" % (self.basedir, self.me)
     if not os.path.exists(keyfdir):
         os.mkdir(keyfdir)
     fname = '%s/%s' % (keyfdir, self.peer)
     nonce = nacl.randombytes(nacl.crypto_box_NONCEBYTES)
     ctx = b''.join((self.e_in, self.e_out, self.peer_pub, self.out_k,
                     self.in_k, self.in_prev))
     if not self.me_id:
         self.me_id = publickey.Identity(self.me, basedir=self.basedir)
     with open(fname, 'wb') as fd:
         fd.write(nonce)
         fd.write(nacl.crypto_box(ctx, nonce, self.me_id.cp, self.me_id.cs))
Example #9
0
 def genProposeSalsa(self, cSuite, servPubkey, sessionKey, myEncrypKey,
                     mySignKey, senderCertificate, statusCertificate):
     nonce = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES)
     encrypSession = pysodium.crypto_box(sessionKey, nonce, servPubkey,
                                         myEncrypKey)
     # encrypSession = pysodium.randombytes(32)
     G_temp = struct.pack(
         '>BBI', 0, cSuite, len(nonce + encrypSession)
     ) + nonce + encrypSession + senderCertificate + statusCertificate
     zeroSig = (0).to_bytes(64, byteorder='big')
     G = G_temp + struct.pack('>I', len(zeroSig)) + zeroSig
     G = pysodium.crypto_sign_detached(G, mySignKey)
     return G_temp + struct.pack('>I', len(G)) + G
Example #10
0
def test_box():

    m = b"passwd"

    pk, sk = pysodium.crypto_box_keypair()

    n = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES)

    print(n)

    c = pysodium.crypto_box(m, n, pk, sk)
    plaintext = pysodium.crypto_box_open(c, n, pk, sk)
    print(plaintext)
Example #11
0
def encrypt_handler(infile=None,
                    outfile=None,
                    recipient=None,
                    self=None,
                    basedir=None):
    # provides a high level function to do encryption of files
    # infile specifies the filename of the input file,
    #        if '-' or not specified it uses stdin
    # outfile specifies the filename of the output file, if not specified
    #         it uses the same filename with '.pbp' appended
    # recipient specifies the name of the recipient for using public key crypto
    # self specifies the sender for signing the message using pk crypto
    # basedir provides a root for the keystores needed for pk crypto
    # if both self and recipient is specified pk crypto is used, otherwise symmetric
    # this function also handles buffering.
    fd = inputfd(infile)
    outfd = outputfd(outfile or
                     (infile + '.pbp' if infile not in [None, '-'] else '-'))

    if recipient and self:
        # let's do public key encryption
        key = nacl.randombytes(nacl.crypto_secretbox_KEYBYTES)
        me = publickey.Identity(self, basedir=basedir)
        size = struct.pack('>H', len(recipient))
        # write out encrypted message key (nonce, c(key+recplen)) for each recipient
        for r in recipient:
            r = publickey.Identity(r, basedir=basedir, publicOnly=True)
            nonce = nacl.randombytes(nacl.crypto_box_NONCEBYTES)
            outfd.write(nonce)
            outfd.write(nacl.crypto_box(key + size, nonce, r.cp, me.cs))
        me.clear()
    else:
        # let's do symmetric crypto
        key = getkey(nacl.crypto_secretbox_KEYBYTES)

    buf = fd.read(BLOCK_SIZE)
    if buf:
        nonce, cipher = encrypt(buf, k=key)
        outfd.write(nonce)
        outfd.write(cipher)
        buf = fd.read(BLOCK_SIZE)
        while buf:
            nonce = inc_nonce(nonce)
            nonce, cipher = encrypt(buf, k=key, nonce=nonce)
            outfd.write(cipher)
            buf = fd.read(BLOCK_SIZE)
    clearmem(key)
    key = None

    if fd != sys.stdin: fd.close()
    if outfd != sys.stdout and isinstance(outfd, file): outfd.close()
Example #12
0
 def save(self):
     keyfdir="%s/dh/" % (self.basedir)
     if not os.path.exists(keyfdir):
         os.mkdir(keyfdir)
     keyfdir="%s/%s" % (keyfdir, self.me)
     if not os.path.exists(keyfdir):
         os.mkdir(keyfdir)
     fname='%s/%s' % (keyfdir, self.id)
     nonce = nacl.randombytes(nacl.crypto_box_NONCEBYTES)
     if not self.me_id:
         self.me_id = publickey.Identity(self.me, basedir=self.basedir)
     with open(fname,'w') as fd:
         fd.write(nonce)
         fd.write(nacl.crypto_box(self.key, nonce, self.me_id.cp, self.me_id.cs))
Example #13
0
File: pbp.py Project: stef/pbp
def encrypt_handler(infile=None, outfile=None, recipient=None, self=None, basedir=None):
    # provides a high level function to do encryption of files
    # infile specifies the filename of the input file,
    #        if '-' or not specified it uses stdin
    # outfile specifies the filename of the output file, if not specified
    #         it uses the same filename with '.pbp' appended
    # recipient specifies the name of the recipient for using public key crypto
    # self specifies the sender for signing the message using pk crypto
    # basedir provides a root for the keystores needed for pk crypto
    # if both self and recipient is specified pk crypto is used, otherwise symmetric
    # this function also handles buffering.
    fd = inputfd(infile)
    outfd = outputfd(outfile or (infile+'.pbp' if infile not in [None,'-'] else '-'))

    if recipient and self:
        # let's do public key encryption
        key = nacl.randombytes(nacl.crypto_secretbox_KEYBYTES)
        me = publickey.Identity(self, basedir=basedir)
        size = struct.pack('>H',len(recipient))
        # write out encrypted message key (nonce, c(key+recplen)) for each recipient
        for r in recipient:
            r = publickey.Identity(r, basedir=basedir, publicOnly=True)
            nonce = nacl.randombytes(nacl.crypto_box_NONCEBYTES)
            outfd.write(nonce)
            outfd.write(nacl.crypto_box(key+size, nonce, r.cp, me.cs))
        me.clear()
    else:
        # let's do symmetric crypto
        key = getkey(nacl.crypto_secretbox_KEYBYTES)

    buf = fd.read(BLOCK_SIZE)
    if buf:
        nonce, cipher = encrypt(buf, k=key)
        outfd.write(nonce)
        outfd.write(cipher)
        buf = fd.read(BLOCK_SIZE)
        while buf:
            nonce = inc_nonce(nonce)
            nonce, cipher = encrypt(buf, k=key, nonce=nonce)
            outfd.write(cipher)
            buf = fd.read(BLOCK_SIZE)
    clearmem(key)
    key=None

    if fd != sys.stdin: fd.close()
    if outfd != sys.stdout: outfd.close()
Example #14
0
File: chaining.py Project: stef/pbp
 def save(self):
     keyfdir="%s/sk/.%s" % (self.basedir, self.me)
     if not os.path.exists(keyfdir):
         os.mkdir(keyfdir)
     fname='%s/%s' % (keyfdir, self.peer)
     nonce = nacl.randombytes(nacl.crypto_box_NONCEBYTES)
     ctx=b''.join((self.e_in,
                   self.e_out,
                   self.peer_pub,
                   self.out_k,
                   self.in_k,
                   self.in_prev))
     if not self.me_id:
         self.me_id = publickey.Identity(self.me, basedir=self.basedir)
     with open(fname,'wb') as fd:
         fd.write(nonce)
         fd.write(nacl.crypto_box(ctx, nonce, self.me_id.cp, self.me_id.cs))
Example #15
0
    def send_message_request(self, msg: dict) -> (dict):
        """Send request with a message and get decoded response json."""

        action = msg["action"]
        msg = json.dumps(msg)

        retries = 1
        timeout = 3
        while retries > 0:
            retries -= 1

            encrypted_message = pysodium.crypto_box(msg.encode(), self.nonce,
                                                    self.server_key,
                                                    self.get_private_key())
            request = {
                "action": action,
                "nonce": encode(self.nonce),
                "message": encode(encrypted_message),
                "clientID": self.clientid,
                "triggerUnlock": "true",
            }
            logging.debug("Sending message: " + str(msg))
            response = self.send_request(request)

            if "errorCode" in response:
                self.nonce = increment_nonce(self.nonce)
                if response["errorCode"] == "1":
                    err = response["error"]
                    logging.error(
                        f"Error in response: {err}. Trying again. Retries left: "
                        + str(retries))
                    time.sleep(timeout)
                    response = self.send_request(request)
                    continue

                # all other error codes crash the program
                logging.fatal(
                    "Uncaught error in response " + str(response) +
                    " to message: " + str(msg), )

            return self.decode_message(response)

        logging.fatal("Timed out")
def prepare_pack_recipient_keys(to_verkeys: Sequence[bytes],
                                from_verkey: bytes = None,
                                from_sigkey: bytes = None) -> (str, bytes):
    """
    Assemble the recipients block of a packed message.

    Args:
        to_verkeys: Verkeys of recipients
        from_verkey: Sender Verkey needed to authcrypt package
        from_sigkey: Sender Sigkey needed to authcrypt package

    Returns:
        A tuple of (json result, key)

    """
    if from_verkey is not None and from_sigkey is None or \
            from_sigkey is not None and from_verkey is None:
        raise CryptoError(
            'Both verkey and sigkey needed to authenticated encrypt message')

    cek = pysodium.crypto_secretstream_xchacha20poly1305_keygen()
    recips = []

    for target_vk in to_verkeys:
        target_pk = pysodium.crypto_sign_pk_to_box_pk(target_vk)
        if from_verkey:
            sender_vk = bytes_to_b58(from_verkey).encode("ascii")
            enc_sender = pysodium.crypto_box_seal(sender_vk, target_pk)
            sk = pysodium.crypto_sign_sk_to_box_sk(from_sigkey)

            nonce = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES)
            enc_cek = pysodium.crypto_box(cek, nonce, target_pk, sk)
        else:
            enc_sender = None
            nonce = None
            enc_cek = pysodium.crypto_box_seal(cek, target_pk)

        recips.append(
            OrderedDict([
                ("encrypted_key", bytes_to_b64(enc_cek, urlsafe=True)),
                (
                    "header",
                    OrderedDict([
                        ("kid", bytes_to_b58(target_vk)),
                        (
                            "sender",
                            bytes_to_b64(enc_sender, urlsafe=True)
                            if enc_sender else None,
                        ),
                        (
                            "iv",
                            bytes_to_b64(nonce, urlsafe=True)
                            if nonce else None,
                        ),
                    ]),
                ),
            ]))

    data = OrderedDict([
        ("enc", "xchacha20poly1305_ietf"),
        ("typ", "JWM/1.0"),
        ("alg", "Authcrypt" if from_verkey else "Anoncrypt"),
        ("recipients", recips),
    ])
    return json.dumps(data), cek
Example #17
0
 def test_crypto_box_open(self):
     pk, sk = pysodium.crypto_box_keypair()
     n = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES)
     c = pysodium.crypto_box(b"howdy", n, pk, sk)
     pysodium.crypto_box_open(c, n, pk, sk)
Example #18
0
def encrypt(message, nonce, serverKey, secretKey):
    return pysodium.crypto_box(message, nonce, serverKey, secretKey)
Example #19
0
def test_pysodium():
    """
    Test all the functions needed from pysodium libarary (libsodium)

    """
    # crypto_sign signatures with Ed25519 keys

    # create keypair without seed
    verkey, sigkey = pysodium.crypto_sign_keypair()
    assert len(verkey) == 32 == pysodium.crypto_sign_PUBLICKEYBYTES
    assert len(sigkey) == 64 == pysodium.crypto_sign_SECRETKEYBYTES

    assert 32 == pysodium.crypto_sign_SEEDBYTES
    sigseed = pysodium.randombytes(pysodium.crypto_sign_SEEDBYTES)
    assert len(sigseed) == 32
    # seed = (b'J\xeb\x06\xf2BA\xd6/T\xe1\xe2\xe2\x838\x8a\x99L\xd9\xb5(\\I\xccRb\xc8\xd5\xc7Y\x1b\xb6\xf0')

    # Ann's seed
    sigseed = (
        b'PTi\x15\xd5\xd3`\xf1u\x15}^r\x9bfH\x02l\xc6\x1b\x1d\x1c\x0b9\xd7{\xc0_\xf2K\x93`'
    )
    assert len(sigseed) == 32

    #  try key stretching from 16 bytes using  pysodium.crypto_pwhash()
    assert 16 == pysodium.crypto_pwhash_SALTBYTES
    salt = pysodium.randombytes(pysodium.crypto_pwhash_SALTBYTES)
    assert len(salt) == 16
    #  salt = b'\x19?\xfa\xc7\x8f\x8b\x7f\x8b\xdbS"$\xd7[\x85\x87'

    # algorithm default is argon2id
    sigseed = pysodium.crypto_pwhash(
        outlen=32,
        passwd="",
        salt=salt,
        opslimit=pysodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,
        memlimit=pysodium.crypto_pwhash_MEMLIMIT_INTERACTIVE,
        alg=pysodium.crypto_pwhash_ALG_DEFAULT)

    assert len(sigseed) == 32
    #  seed = (b'\xa9p\x89\x7f+\x0e\xc4\x9c\xf2\x01r\xafTI\xc0\xfa\xac\xd5\x99\xf8O\x8f=\x843\xa2\xb6e\x9fO\xff\xd0')

    # creates signing/verification key pair from seed
    verkey, sigkey = pysodium.crypto_sign_seed_keypair(sigseed)
    assert len(verkey) == 32
    assert len(sigkey) == 64
    #  sigkey is seed and verkey concatenated. Libsodium does this as an optimization
    #  because the signing scheme needs both the private key (seed) and the public key so
    #  instead of recomputing the public key each time from the secret key it requires
    #  the public key as an input of and instead of two separate inputs, one for the
    #  secret key and one for the public key, it uses a concatenated form.
    #  Essentially crypto_sign_seed_keypair and crypto_sign_keypair return redundant
    #  information in the duple (verkey, sigkey) because sigkey includes verkey
    #  so one could just store sigkey and extract verkey or sigseed when needed
    #  or one could just store verkey and sigseed and reconstruct sigkey when needed.
    #  crypto_sign_detached requires sigkey (sigseed + verkey)
    #  crypto_sign_verify_detached reqires verkey only
    #  https://crypto.stackexchange.com/questions/54353/why-are-nacl-secret-keys-64-bytes-for-signing-but-32-bytes-for-box
    assert sigseed == sigkey[:32]
    assert verkey == sigkey[32:]
    assert sigkey == sigseed + verkey
    # vk = (b'B\xdd\xbb}8V\xa0\xd6lk\xcf\x15\xad9\x1e\xa7\xa1\xfe\xe0p<\xb6\xbex\xb0s\x8d\xd6\xf5\xa5\xe8Q')

    #  utility function to extract seed from secret sigkey (really just extracting from front half)
    assert sigseed == pysodium.crypto_sign_sk_to_seed(sigkey)

    assert 64 == pysodium.crypto_sign_BYTES

    msg = "The lazy dog jumped over the river"
    msgb = msg.encode(
        "utf-8")  # must convert unicode string to bytes in order to sign it
    assert msgb == b'The lazy dog jumped over the river'
    sig = pysodium.crypto_sign_detached(msgb, sigseed +
                                        verkey)  #  sigkey = seed + verkey
    assert len(sig) == 64
    """
    sig = (b"\x99\xd2<9$$0\x9fk\xfb\x18\xa0\x8c@r\x122.k\xb2\xc7\x1fp\x0e'm\x8f@"
           b'\xaa\xa5\x8c\xc8n\x85\xc8!\xf6q\x91p\xa9\xec\xcf\x92\xaf)\xde\xca'
           b'\xfc\x7f~\xd7o|\x17\x82\x1d\xd4<o"\x81&\t')

    """
    #siga = pysodium.crypto_sign(msg.encode("utf-8"), sk)[:pysodium.crypto_sign_BYTES]
    #assert len(siga) == 64
    #assert sig == siga

    try:  #  verify returns None if valid else raises ValueError
        result = pysodium.crypto_sign_verify_detached(sig, msgb, verkey)
    except Exception as ex:
        assert False
    assert not result
    assert result is None

    sigbad = sig[:-1]
    sigbad += b'A'

    try:  #  verify returns None if valid else raises ValueError
        result = pysodium.crypto_sign_verify_detached(sigbad, msgb, verkey)
    except Exception as ex:
        assert True
        assert isinstance(ex, ValueError)

    # crypto_box authentication encryption with X25519 keys

    apubkey, aprikey = pysodium.crypto_box_keypair()
    assert len(apubkey) == 32 == pysodium.crypto_box_SECRETKEYBYTES
    assert len(aprikey) == 32 == pysodium.crypto_box_PUBLICKEYBYTES

    repubkey = pysodium.crypto_scalarmult_curve25519_base(aprikey)
    assert repubkey == apubkey

    assert 32 == pysodium.crypto_box_SEEDBYTES

    boxseed = pysodium.randombytes(pysodium.crypto_box_SEEDBYTES)
    assert len(boxseed) == 32

    bpubkey, bprikey = pysodium.crypto_box_seed_keypair(boxseed)
    assert len(bpubkey) == 32
    assert len(bprikey) == 32

    repubkey = pysodium.crypto_scalarmult_curve25519_base(bprikey)
    assert repubkey == bpubkey

    assert 24 == pysodium.crypto_box_NONCEBYTES
    nonce = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES)
    assert len(nonce) == 24
    # nonce = b'\x11\xfbi<\xf2\xb6k\xa05\x0c\xf9\x86t\x07\x8e\xab\x8a\x97nG\xe8\x87,\x94'

    atob_tx = "Hi Bob I'm Alice"
    atob_txb = atob_tx.encode("utf-8")

    # Detached recomputes shared key every time.
    # A encrypt to B
    acrypt, amac = pysodium.crypto_box_detached(atob_txb, nonce, bpubkey,
                                                aprikey)
    amacl = pysodium.crypto_box_MACBYTES
    assert amacl == 16
    #  amac =  b'\xa1]\xc6ML\xe2\xa9:\xc0\xdc\xab\xa5\xc4\xc7\xf4\xdb'
    #  acrypt = (b'D\n\x17\xb6z\xd8+t)\xcc`y\x1d\x10\x0cTC\x02\xb5@\xe2\xf2\xc9-(\xec*O\xb8~\xe2\x1a\xebO')
    # when transmitting prepend amac to crypt

    acipher = pysodium.crypto_box(atob_txb, nonce, bpubkey, aprikey)
    assert acipher == amac + acrypt

    atob_rxb = pysodium.crypto_box_open_detached(acrypt, amac, nonce, apubkey,
                                                 bprikey)
    atob_rx = atob_rxb.decode("utf-8")
    assert atob_rx == atob_tx
    assert atob_rxb == atob_txb

    atob_rxb = pysodium.crypto_box_open(acipher, nonce, apubkey, bprikey)
    atob_rx = atob_rxb.decode("utf-8")
    assert atob_rx == atob_tx
    assert atob_rxb == atob_txb

    btoa_tx = "Hello Alice I am Bob"
    btoa_txb = btoa_tx.encode("utf-8")

    # B encrypt to A
    bcrypt, bmac = pysodium.crypto_box_detached(btoa_txb, nonce, apubkey,
                                                bprikey)
    # bmac = b'\x90\xe07=\xd22\x8fh2\xff\xdd\x84tC\x053'
    # bcrypt = (b'8\xb5\xba\xe7\xcc\xae B\xefx\xe6{U\xf7\xefA\x00\xc7|\xdbu\xcfc\x01$\xa9\xa2P\xa7\x84\xa5\xae\x180')
    # when transmitting prepend amac to crypt

    bcipher = pysodium.crypto_box(btoa_txb, nonce, apubkey, bprikey)
    assert bcipher == bmac + bcrypt

    btoa_rxb = pysodium.crypto_box_open_detached(bcrypt, bmac, nonce, bpubkey,
                                                 aprikey)
    btoa_rx = btoa_rxb.decode("utf-8")
    assert btoa_rx == btoa_tx
    assert btoa_rxb == btoa_txb

    btoa_rxb = pysodium.crypto_box_open(bcipher, nonce, bpubkey, aprikey)
    btoa_rx = btoa_rxb.decode("utf-8")
    assert btoa_rx == btoa_tx
    assert btoa_rxb == btoa_txb

    # compute shared key
    asymkey = pysodium.crypto_box_beforenm(bpubkey, aprikey)
    bsymkey = pysodium.crypto_box_beforenm(apubkey, bprikey)
    assert asymkey == bsymkey

    acipher = pysodium.crypto_box_afternm(atob_txb, nonce, asymkey)
    atob_rxb = pysodium.crypto_box_open_afternm(acipher, nonce, bsymkey)
    assert atob_rxb == atob_txb

    bcipher = pysodium.crypto_box_afternm(btoa_txb, nonce, bsymkey)
    btoa_rxb = pysodium.crypto_box_open_afternm(bcipher, nonce, asymkey)
    assert btoa_rxb == btoa_txb

    # crypto_box_seal public key encryption with X25519 keys
    #  uses same X25519 type of keys as crypto_box authenticated encryption
    #  so when converting sign key Ed25519 to X25519 can use for both types of encryption

    pubkey, prikey = pysodium.crypto_box_keypair()
    assert len(pubkey) == 32 == pysodium.crypto_box_PUBLICKEYBYTES
    assert len(prikey) == 32 == pysodium.crypto_box_SECRETKEYBYTES

    assert 48 == pysodium.crypto_box_SEALBYTES

    msg_txb = "Catch me if you can.".encode("utf-8")
    assert msg_txb == b'Catch me if you can.'
    cipher = pysodium.crypto_box_seal(msg_txb, pubkey)
    assert len(cipher) == 48 + len(msg_txb)

    msg_rxb = pysodium.crypto_box_seal_open(cipher, pubkey, prikey)
    assert msg_rxb == msg_txb

    #  convert Ed25519 key pair to X25519 key pair
    #  https://blog.filippo.io/using-ed25519-keys-for-encryption/
    #  https://libsodium.gitbook.io/doc/advanced/ed25519-curve25519
    #  crypto_sign_ed25519_pk_to_curve25519
    #  crypto_sign_ed25519_sk_to_curve25519

    pubkey = pysodium.crypto_sign_pk_to_box_pk(verkey)
    assert len(pubkey) == pysodium.crypto_box_PUBLICKEYBYTES

    prikey = pysodium.crypto_sign_sk_to_box_sk(sigkey)
    assert len(prikey) == pysodium.crypto_box_SECRETKEYBYTES

    repubkey = pysodium.crypto_scalarmult_curve25519_base(prikey)
    assert repubkey == pubkey

    msg_txb = "Encoded using X25519 key converted from Ed25519 key".encode(
        "utf-8")
    cipher = pysodium.crypto_box_seal(msg_txb, pubkey)
    assert len(cipher) == 48 + len(msg_txb)

    msg_rxb = pysodium.crypto_box_seal_open(cipher, pubkey, prikey)
    assert msg_rxb == msg_txb
    """
Example #20
0
 def keyencrypt(self, key, recipients=None):
     c=[]
     for r in recipients:
         nonce = nacl.randombytes(nacl.crypto_box_NONCEBYTES)
         c.append((nonce, nacl.crypto_box(key, nonce, r.cp, self.cs)))
     return c
Example #21
0
 def add_encryption(self, data):
     nonce_bytes = self.get_nonce_8_bytes_and_increment()
     nonce_bytes_zpadded = (b"\x00\x00\x00\x00\x00\x00\x00\x00" +
                            b"\x00\x00\x00\x00\x00\x00\x00\x00" + nonce_bytes)
     return (nonce_bytes, pysodium.crypto_box(data, nonce_bytes_zpadded, self.their_public, self.our_secret))
Example #22
0
def EncryptPacket(packet, pk, sk):
    nounce = LAST_NOUNCE
    data = pysodium.crypto_box(packet, nounce, pk, sk)
    return struct.pack("<I", len(data) + 24 + 4) + nounce + data
Example #23
0
 def test_crypto_box_open(self):
     pk, sk = pysodium.crypto_box_keypair()
     n = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES)
     c = pysodium.crypto_box(b"howdy", n, pk, sk)
     pysodium.crypto_box_open(c, n, pk, sk)
Example #24
0
 def keyencrypt(self, key, recipients=None):
     c = []
     for r in recipients:
         nonce = nacl.randombytes(nacl.crypto_box_NONCEBYTES)
         c.append((nonce, nacl.crypto_box(key, nonce, r.cp, self.cs)))
     return c
Example #25
0
def __encrypt(msg, nonce, serverKey, secretKey):
    enc = pysodium.crypto_box(msg, base64.b64decode(nonce),
                              base64.b64decode(serverKey),
                              base64.b64decode(secretKey))
    return base64.b64encode(enc)
Example #26
0
def oneshotEncrypt(sk, pk, data):
    n = rand(pysodium.crypto_box_NONCEBYTES)
    return n + pysodium.crypto_box(data, n, pk, sk)
Example #27
0
def prepare_pack_recipient_keys(
    to_verkeys: Sequence[bytes], from_secret: bytes = None
) -> (str, bytes):
    """
    Assemble the recipients block of a packed message.

    Args:
        to_verkeys: Verkeys of recipients
        from_secret: Secret to use for signing keys

    Returns:
        A tuple of (json result, key)

    """
    cek = pysodium.crypto_secretstream_xchacha20poly1305_keygen()
    recips = []

    for target_vk in to_verkeys:
        target_pk = pysodium.crypto_sign_pk_to_box_pk(target_vk)
        if from_secret:
            sender_pk, sender_sk = create_keypair(from_secret)
            sender_vk = bytes_to_b58(sender_pk).encode("ascii")
            enc_sender = pysodium.crypto_box_seal(sender_vk, target_pk)
            sk = pysodium.crypto_sign_sk_to_box_sk(sender_sk)

            nonce = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES)
            enc_cek = pysodium.crypto_box(cek, nonce, target_pk, sk)
        else:
            enc_sender = None
            nonce = None
            enc_cek = pysodium.crypto_box_seal(cek, target_pk)

        recips.append(
            OrderedDict(
                [
                    ("encrypted_key", bytes_to_b64(enc_cek, urlsafe=True)),
                    (
                        "header",
                        OrderedDict(
                            [
                                ("kid", bytes_to_b58(target_vk)),
                                (
                                    "sender",
                                    bytes_to_b64(enc_sender, urlsafe=True)
                                    if enc_sender
                                    else None,
                                ),
                                (
                                    "iv",
                                    bytes_to_b64(nonce, urlsafe=True)
                                    if nonce
                                    else None,
                                ),
                            ]
                        ),
                    ),
                ]
            )
        )

    data = OrderedDict(
        [
            ("enc", "xchacha20poly1305_ietf"),
            ("typ", "JWM/1.0"),
            ("alg", "Authcrypt" if from_secret else "Anoncrypt"),
            ("recipients", recips),
        ]
    )
    return json.dumps(data), cek