2

I have been working on a project myself and using this website's codes as a guide. Is there any way, I can put the generation of keys into 1 file and encryption/decryption into another. How do I define bob_box without having to generate another pair of keys?

GEN.PY:

import libnacl.public

def genkeys():

    bob = libnacl.public.SecretKey()
    alice = libnacl.public.SecretKey()

    bob_box = libnacl.public.Box(bob.sk, alice.pk)
    alice_box = libnacl.public.Box(alice.sk, bob.pk)

genkeys()

ENDEcrypt:

import libnacl.public
from GEN import genkeys

msg = '1234'

# Bob's box encrypts messages for Alice
bob_ctxt = bob_box.encrypt(msg)

# Alice's box decrypts messages from Bob
bclear = alice_box.decrypt(bob_ctxt)

# Alice can send encrypted messages which only Bob can decrypt
alice_ctxt = alice_box.encrypt(msg)
aclear = bob_box.decrypt(alice_ctxt)

output when I run ENDEcrypt:

Traceback (most recent call last):
File "/home/pi/Desktop/BOBALICE/endecrypt.py", line 7, in <module>
bob_ctxt = bob_box.encrypt(msg)
NameError: name 'bob_box' is not defined
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
meh
  • 53
  • 1
  • 7
  • @ArtjomB. oops! my bad, i made an error when i added the keys into the box. Ive updated my codes – meh Jul 05 '17 at 06:57
  • Passing both Bob's private and public key to `libnacl.public.Box` doesn't make sense. The public key has to be from the person Bob wants to communicate with. Here, Bob wants to communicate with himself. – Artjom B. Jul 05 '17 at 18:06
  • @ArtjomB. but lets say i only need 1 pair of keys (public and private), if i followed the codes from the website, wouldn't that give me 2 pairs of keys? – meh Jul 06 '17 at 02:12
  • @ArtjomB. I have simplified my codes already. do check it out! – meh Jul 06 '17 at 02:36

1 Answers1

3

The API of libnacl is designed in such a way that two parties that want to communicate securely must somehow exchange their public keys. Let's say Alice wants to send a message to Bob.

# Alice's computer:                             Bob's computer:
alice_sign = libnacl.public.SecretKey()         bob_enc = libnacl.public.SecretKey()
alice_spk_h = alice_sign.hex_pk()               bob_epk_h = bob_enc.hex_pk()

# magic happens where alice_spk_h goes to Bob and bob_epk_h goes to alice (i.e. by phone)

bob_epk = libnacl.public.PublicKey(bob_epk_h)   alice_spk = libnacl.public.PublicKey(
                                                        alice_spk_h)
alice_box = libnacl.public.Box(                 bob_box = libnacl.public.Box(
        alice_sign.sk, bob_epk)                         bob_enc.sk, alice_spk)

# preparation is done, let's start encrypting...

ct = alice_box.encrypt(msg)

# send ct to Bob (the message is protected)

                                                msg = bob_box.decrypt(ct)

As you can see, you need to treat the public and secret keys separately to send them between machine of the communicating parties. You cannot combine them into one method, because that would contradict the usage scenario of libnacl's public-key encryption.

Keep in mind that with a single key pair per party, it is only permissible to send the encrypted messages in one direction. If you need to send messages back, then each party needs to have two keys (one for signing and one for encryption; note that I named Alice's and Bob's keys in a certain way to make that clear).


Is there a way to do the generation of keys in one file and the storing of keys into a box + encryption/decryption into another file?

Yes, but here you have to think about what these files are doing. A Python file is code. If you run the code that generates the SecretKey from a command line, you need to store it in some way, because running the code again would change the key.

gen.py

import libnacl.public

def genkey():
    return libnacl.public.SecretKey()

def gen_keys_and_save():
    # Generate two key pairs and store them for later use
    enc = genkey()
    enc.save('myencsecret.key')
    with open('myencpublic.key', 'w') as pkf:
        pkf.write(enc.hex_pk())

    sign = genkey()
    sign.save('mysignsecret.key')
    with open('mysignpublic.key', 'w') as pkf:
        pkf.write(sign.hex_pk())

if __name__ == "__main__":
    # this code only runs when executed directly (i.e. from command line)
    gen_keys_and_save()

enc.py

import libnacl.public
import libnacl.utils

def encrypt(mysignsecret, theirencpublic, data):
    box = libnacl.public.Box(mysignsecret, theirencpublic)
    return box.encrypt(data)

def parse_and_encrypt(mysignsecretfile, theirencpublicfile, data):
    sk = libnacl.utils.load_key(mysignsecretfile)
    with open(theirencpublicfile, 'r') as pkf:
        pk = libnacl.public.PublicKey(pkf.read())
    return encrypt(sk, pk, data)

if __name__ == "__main__":
    parse_and_encrypt('mysignsecret.key', 'theirencpublic.key', 'some kind of msg')

dec.py

import libnacl.public

def decrypt(myencsecret, theirsignpublic, ciphertext):
    box = libnacl.public.Box(myencsecret, theirsignpublic)
    return box.decrypt(ciphertext)

# similar to enc.py ...

Now you can run it like this:

$ python gen.py 

Now you need to receive theirencpublic.key and send mysignpublic.key. When you've done that, you can do that:

$ python enc.py 
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • Anything that is not split by a code comment can be combined to a function in the above code example. – Artjom B. Jul 06 '17 at 18:37
  • Thank you for the detailed explanation!! I do have a question. Is there a way to do the generation of keys in one file and the storing of keys into a box + encryption/decryption into another file? Because that was my main question. But I will change the codes in my project according to yr answer. However, the issue I have right now is that I need to separate them into 2 files . Any ideas? @Artjom B. – meh Jul 08 '17 at 18:07
  • I've extended my answer – Artjom B. Jul 09 '17 at 12:14