Coder Social home page Coder Social logo

libnacl's People

Contributors

aboe76 avatar andreasbaumann avatar brainwater avatar ch3ll avatar cjwatson avatar cro avatar darix avatar dbrgn avatar doc-hex avatar fletom avatar ineiti avatar jedisct1 avatar jensbjorgensen avatar johnttan avatar julianhille avatar kmosiejczuk avatar kpcyrd avatar lgrahl avatar lvzon avatar mgorny avatar michaelmendoza avatar mindw avatar mk-fg avatar mumbleskates avatar s0undt3ch avatar smithsamuelm avatar terminalmage avatar thatch45 avatar tirkarthi avatar whs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libnacl's Issues

crypto_generichash does not produce a verifyable BLAKE2b digest

According to RFC 7693 Appendix-A, the BLAKE2b hexadecimal digest of "abc" should be:

BLAKE2b-512("abc") = BA 80 A5 3F 98 1C 4D 0D 6A 27 97 B6 9F 12 F6 E9
                     4C 21 2F 14 68 5A C4 B7 4B 12 BB 6F DB FF A2 D1
                     7D 87 C5 39 2A AB 79 2D C2 52 D5 DE 45 33 CC 95
                     18 D3 8A A8 DB F1 92 5A B9 23 86 ED D4 00 99 23

This is confirmed by compiling and executing the reference code at https://github.com/blake2/blake2:

% printf 'abc' | b2sum -a blake2b | tr 'a-f' 'A-F' | sed -r 's/(..)/\1 /g' | fold -w 48
BA 80 A5 3F 98 1C 4D 0D 6A 27 97 B6 9F 12 F6 E9 
4C 21 2F 14 68 5A C4 B7 4B 12 BB 6F DB FF A2 D1 
7D 87 C5 39 2A AB 79 2D C2 52 D5 DE 45 33 CC 95 
18 D3 8A A8 DB F1 92 5A B9 23 86 ED D4 00 99 23 

crypto_generichash seems to be printing the length of a BLAKE2s digest (32-bytes instead of 64-bytes), and even then, the hexadecimal output is still wrong:

% python -c 'import libnacl;h=libnacl.crypto_generichash("abc");print h.encode("hex")' 
bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319

According to the RFC, the BLAKE2s hexadecimal digest should be:

BLAKE2s-256("abc") = 50 8C 5E 8C 32 7C 14 E2 E1 A7 2B A3 4E EB 45 2F
                     37 45 8B 20 9E D6 3A 29 4D 99 9B 4C 86 67 59 82

Verified with the reference executable:

% printf 'abc' | b2sum -a blake2s | tr 'a-f' 'A-F' | sed -r 's/(..)/\1 /g' | fold -w 48 
50 8C 5E 8C 32 7C 14 E2 E1 A7 2B A3 4E EB 45 2F 
37 45 8B 20 9E D6 3A 29 4D 99 9B 4C 86 67 59 82 

Whatever crypto_generichash is printing, it doesn't conform to the BLAKE2 specification.

SecretBox is using an old libsodium crypto_secretbox API?

As the documentation doesn't clearly specify whether libnacl's Secret Key Encryption is actually authenticated encryption or not, I started reading the source code and eventually noticed this:

libnacl.secret.SecretBox calls libnacl.crypto_secretbox which calls the libsodium crypto_secretbox method...

The libsodium documentation contains the following statement:

The original NaCl crypto_secretbox API is also supported, albeit not recommended.

crypto_secretbox() takes a pointer to 32 bytes before the message, and stores the ciphertext 16 bytes after the destination pointer, the first 16 bytes being overwritten with zeros.

crypto_secretbox_open() takes a pointer to 16 bytes before the ciphertext and stores the message 32 bytes after the destination pointer, overwriting the first 32 bytes with zeros.

The _easy and _detached APIs are faster and improve usability by not requiring padding, copying or tricky pointer arithmetic.

So, it appears libnacl can be made simpler/faster/more secure(?) by using the newer, simpler API. Unless compatibility with some other (older) implementations is required?

Documentation on signing is incorrect/misleading

The documentation for "Signing and Verifying Messages" states:

Please be advised that public key encrypted messages do not need to be signed, the nacl box construct verifies the validity of the sender.

However, the NaCl docs explicitly state:

The crypto_box function is not meant to provide non-repudiation. On the contrary: the crypto_box function guarantees repudiability. A receiver can freely modify a boxed message, and therefore cannot convince third parties that this particular message came from the sender. The sender and receiver are nevertheless protected against forgeries by other parties. In the terminology of https://groups.google.com/group/sci.crypt/msg/ec5c18b23b11d82c, crypto_box uses "public-key authenticators" rather than "public-key signatures."

Users who want public verifiability (or receiver-assisted public verifiability) should instead use signatures (or signcryption).

So the documentation is at least misleading; encrypted messages need to be signed if they are intended to provide non-repudiation.

libnacl-1.4.4 does'nt work with libsodium-0.4.5-3.el6.x86_64 (latest version from CentOS EPEL)

When using libnacl-1.4.4 on centos-6.7 box, with libsodium-0.4.5-3.el6.x86_64 installed, which is the latest available version of package in EPEL repo for centos 6, I get this error:

Traceback (most recent call last): File "./decrypt_file.py", line 5, in <module> import libnacl.public File "/usr/lib/python2.6/site-packages/libnacl/__init__.py", line 127, in <module> crypto_verify_64_BYTES = nacl.crypto_verify_64_bytes() File "/usr/lib64/python2.6/ctypes/__init__.py", line 366, in __getattr__ func = self.__getitem__(name) File "/usr/lib64/python2.6/ctypes/__init__.py", line 371, in __getitem__ func = self._FuncPtr((name_or_ordinal, self)) AttributeError: /usr/lib64/libsodium.so.4: undefined symbol: crypto_verify_64_bytes

I found that crypto_verify_64_bytes support has been implemented in libsodium starting version libsodium-0.5.0.

I'd recommend to modify rpm spec file you provide, to reflect dependency on specific version of libsodium:

-Requires: libsodium
+Requires: libsodium >= 0.5.0

Note: libnacl-1.4.3 does not have this dependency and works fine with libsodium-0.4.5-3.el6.x86_64 on centos 6.7.

libnacl should support libsodium 23

ibnacl cannot use libsodium.so.23, /libnacl/init.py should be modified to for libsodium.so.23.
Adding 23 to the __SONAMES array on line 12 should be the simplest fix.

Support Cython backend

We want to have a compiled/not compiled option for deployment of libnacl, since compiled is slightly faster but ctypes is a little more flexible. We want to deliver the best of both worlds!

Incorrect documentation/functionality RE: public key initializers

The documentation says that you can initialize a public key like so:

tom = libnacl.public.PublicKey(tom_public_key_hex)

However, that is actually incorrect as the initializer does not unhexlify the argument:

class PublicKey(libnacl.base.BaseKey):
    '''
    This class is used to manage public keys
    '''
    def __init__(self, pk):
        self.pk = pk

The same is true for the SecretKey:

class SecretKey(libnacl.base.BaseKey):
    '''
    This class is used to manage keypairs
    '''
    def __init__(self, sk=None):
        '''
        If a secret key is not passed in then it will be generated
        '''
        if sk is None:
            self.pk, self.sk = libnacl.crypto_box_keypair()
        elif len(sk) == libnacl.crypto_box_SECRETKEYBYTES:
            self.sk = sk

This is what happens obviously:

>>> keys = libnacl.utils.load_key("TestingKeys.keys")
>>> keys
<libnacl.public.SecretKey object at 0x0000000002225A20>
>>> keys.hex_pk()
b'7c8e073e1bbb8342235d9f21478d29b7969d436cf1fa613d363d00701cc57d40'
>>> pubkey = libnacl.public.PublicKey(b'7c8e073e1bbb8342235d9f21478d29b7969d436c
f1fa613d363d00701cc57d40')
>>> pubkey
<libnacl.public.PublicKey object at 0x0000000002232FD0>
>>> pubkey.hex_pk()
b'376338653037336531626262383334323233356439663231343738643239623739363964343336
63663166613631336433363364303037303163633537643430'
>>> keys.pk
b'|\x8e\x07>\x1b\xbb\x83B#]\x9f!G\x8d)\xb7\x96\x9dCl\xf1\xfaa=6=\x00p\x1c\xc5}@'

>>> pubkey.pk
b'7c8e073e1bbb8342235d9f21478d29b7969d436cf1fa613d363d00701cc57d40'
>>> import binascii
>>> binascii.unhexlify(pubkey.pk)
b'|\x8e\x07>\x1b\xbb\x83B#]\x9f!G\x8d)\xb7\x96\x9dCl\xf1\xfaa=6=\x00p\x1c\xc5}@'

>>>

I'm not sure which behavior would be better, maybe hex form is better because if you're manually feeding them in, that's probably what you'll be using. At least I was.

Either way, the documentation is incorrect.

sealed_boxes

https://download.libsodium.org/doc/

sealed_boxes.html

I would like to add support in the salt nacl module for public key one way encryption.
This way people adding encrypted data to pillars wont need access to the private key that can decrypt.

salt-call nacl.pub_enc data="PASSWOTD" key="PUBKEY"

only the holder of the private key can render the pillar.

password: {{ salt['nacl.dec']('l8kuMoSUG5bStHO7Er08Wz/T10w8HDWfzgAIzbQ==') }}

Undefined symbol: crypto_box_sealbytes

After upgrading from 1.5.0 to 1.5.1, I'm getting the following error:

  File "/usr/local/lib/python3.5/site-packages/libnacl/__init__.py", line 105, in <module>
    crypto_box_SEALBYTES = nacl.crypto_box_sealbytes()
  File "/usr/local/lib/python3.5/ctypes/__init__.py", line 360, in __getattr__
    func = self.__getitem__(name)
  File "/usr/local/lib/python3.5/ctypes/__init__.py", line 365, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /usr/lib/x86_64-linux-gnu/libsodium.so: undefined symbol: crypto_box_sealbytes

I'm using libsodium-dev=1.0.0-1 from apt-get

libsodium 1.0.19 is released: OSError: Could not locate nacl lib, searched for libsodium.so, libsodium.so.23, libsodium.so.18...

FYI, libsodium 1.0.19 is released at Sep 13 2023, with soname changed to libsodium.so.26. This change makes module to fail with:

======================================================================
ERROR: unit.test_aead (unittest.loader._FailedTest.unit.test_aead)
----------------------------------------------------------------------
ImportError: Failed to import test module: unit.test_aead
Traceback (most recent call last):
  File "/usr/lib64/python3.11/unittest/loader.py", line 407, in _find_test_path
    module = self._get_module_from_name(name)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/unittest/loader.py", line 350, in _get_module_from_name
    __import__(name)
  File "/usr/src/RPM/BUILD/python3-module-libnacl-1.7.1/tests/unit/test_aead.py", line 2, in <module>
    import libnacl.aead
  File "/usr/src/RPM/BUILD/python3-module-libnacl-1.7.1/libnacl/__init__.py", line 85, in <module>
    nacl = _get_nacl()
           ^^^^^^^^^^^
  File "/usr/src/RPM/BUILD/python3-module-libnacl-1.7.1/libnacl/__init__.py", line 81, in _get_nacl
    raise OSError(msg)
OSError: Could not locate nacl lib, searched for libsodium.so, libsodium.so.23, libsodium.so.18, libsodium.so.17, libsodium.so.13, libsodium.so.10, libsodium.so.5, libsodium.so.4,

Perhaps, __SONAMES list should be updated.

unittest: ERROR: test_save_load (unit.test_save.TestSave.test_save_load) - TypeError: JSONDecoder.__init__() got an unexpected keyword argument 'encoding'

JSON unit tests fail on python 3.11.4;

======================================================================
ERROR: test_save_load (unit.test_save.TestSave.test_save_load)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/src/RPM/BUILD/python3-module-libnacl-1.7.1/tests/unit/test_save.py", line 32, in test_save_load
    bob_load = libnacl.utils.load_key(bob_path)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/RPM/BUILD/python3-module-libnacl-1.7.1/libnacl/utils.py", line 34, in load_key
    key_data = json.loads(stream.read(), encoding='UTF-8')
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/json/__init__.py", line 359, in loads
    return cls(**kw).decode(s)
           ^^^^^^^^^
TypeError: JSONDecoder.__init__() got an unexpected keyword argument 'encoding'

======================================================================
ERROR: test_save_load_secret (unit.test_save.TestSave.test_save_load_secret)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/src/RPM/BUILD/python3-module-libnacl-1.7.1/tests/unit/test_save.py", line 63, in test_save_load_secret
    lbox = libnacl.utils.load_key(box_path)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/RPM/BUILD/python3-module-libnacl-1.7.1/libnacl/utils.py", line 34, in load_key
    key_data = json.loads(stream.read(), encoding='UTF-8')
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/json/__init__.py", line 359, in loads
    return cls(**kw).decode(s)
           ^^^^^^^^^
TypeError: JSONDecoder.__init__() got an unexpected keyword argument 'encoding'

======================================================================
ERROR: test_save_load_sign (unit.test_save.TestSave.test_save_load_sign)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/src/RPM/BUILD/python3-module-libnacl-1.7.1/tests/unit/test_save.py", line 74, in test_save_load_sign
    signer_load = libnacl.utils.load_key(sign_path)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/RPM/BUILD/python3-module-libnacl-1.7.1/libnacl/utils.py", line 34, in load_key
    key_data = json.loads(stream.read(), encoding='UTF-8')
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/json/__init__.py", line 359, in loads
    return cls(**kw).decode(s)
           ^^^^^^^^^
TypeError: JSONDecoder.__init__() got an unexpected keyword argument 'encoding'

----------------------------------------------------------------------
Ran 65 tests in 0.040s

FAILED (errors=3)
error: Bad exit status from /usr/src/tmp/rpm-tmp.12559 (%check)

It seems that encoding is removed since 3.9: https://docs.python.org/3/library/json.html#json.loads

Changed in version 3.9: The keyword argument encoding has been removed.

Consider pure python tweetnacl

This is still just an idea, but it would allow for a pure python deployment of encrypted code to systems that do not have libsodium installed.

Could not locate nacl lib on Windows

screenshot_1

So basically this happens when I try to import the library... I tried installing it over pip3, and over setup.py

Is it just me or is there something wrong with it?

Include a proper license header in source files

It would make it easier to redistribute python-libnacl in Fedora[1] if each source file contains a license header. None of the source code files contains a license header. Can you update the source files with license header and confirm that all the files are licensed ASL 2.0?

Check https://bugzilla.redhat.com/show_bug.cgi?id=1399833#c3 and for details.

[1] https://fedoraproject.org/wiki/Packaging:LicensingGuidelines?rd=Packaging/LicensingGuidelines#License_Clarification

Crash with parameter passing in crypto_aead_aes256gcm_decrypt and crypto_aead_chacha20poly1305_ietf_decrypt

Tests fail on 32-bit Intel:

==> Starting check()...
test_gcm_aead (unit.test_aead.TestAEAD) ... /startdir/PKGBUILD: line 30:   424 Aborted                 (core dumped) python -m unittest discover --start-directory tests -v
==> ERROR: A failure occurred in check().
    Aborting...

In sodium/crypto_aead_aes256gcm.h I see that mlen_p is a pointer to a 64-bit long long:

int crypto_aead_aes256gcm_decrypt(unsigned char *m,
                                  unsigned long long *mlen_p,
                                  unsigned char *nsec,
                                  const unsigned char *c,
                                  unsigned long long clen,
                                  const unsigned char *ad,
                                  unsigned long long adlen,
                                  const unsigned char *npub,
                                  const unsigned char *k)

In __init.py__ in the 'ctypes' wrapper I see:

mlen = ctypes.c_ulonglong()
..
   ret = nacl.crypto_aead_aes256gcm_decrypt(
        m, mlen,
        None,
        ctxt, ctypes.c_ulonglong(len(ctxt)),
        aad, ctypes.c_ulonglong(len(aad)),
        nonce, key)
...
    ret = nacl.crypto_aead_chacha20poly1305_ietf_decrypt(
        m, mlen,
        None,
        ctxt, ctypes.c_ulonglong(len(ctxt)),
        aad, ctypes.c_ulonglong(len(aad)),
        nonce, key)
...

This works fine on 64-bit, but not on 32-bit. The tests crash with segfault.

When I change the calls to use a ctypes.byref the tests work fine:

    ret = nacl.crypto_aead_aes256gcm_decrypt(
        m, ctypes.byref(mlen),
        None,
        ctxt, ctypes.c_ulonglong(len(ctxt)),
        aad, ctypes.c_ulonglong(len(aad)),
        nonce, key)
...
   ret = nacl.crypto_aead_chacha20poly1305_ietf_decrypt(
        m, ctypes.byref(mlen),
        None,
        ctxt, ctypes.c_ulonglong(len(ctxt)),
        aad, ctypes.c_ulonglong(len(aad)),
        nonce, key)

See also debugging session on https://bbs.archlinux32.org/viewtopic.php?pid=219#p219.

allow generating secret key in public key encryption from seed

Creating a SecretKey in public.py should be allowed by seed.

However i'd like to create a PR and implement that i'm unsure how to achieve that.

  1. add a classmethod to the SecretKey model called something like generate_from_seed
  2. add a function to public.py generate_secret_key_from_seed
  3. change signature of __init__ method of the SecretKey and add seed as argument.
  4. always give a seed and create internally the right sk and pk

im mostly for 2.

  1. im not a big fan of class methods in this case
  2. has the issue that its not in all case backward compatible and is odd to give sk or seed or both or none of them. Not a good api and not easy to understand.
  3. would be backwards incompatible, but would be harmonize Signer and SecretKey creation.

What do you think?

crypto_kdf_derive_from_key segfaults on ARM

test_crypto_kdf_derive_from_key segfaults on the ARM architecture due to incorrect use of ctypes.

The information about argument/return types of C function is present in .h files that aren't available at run time. So, when using ctypes, you need to declare argument types (technically only if different from defaults – but it's better to do it always). See ctypes documentation.

For kdf_derive_from_key specifically, this should probably be:

    nacl.crypto_kdf_derive_from_key.argtypes = [
        ctypes.c_char_p, ctypes.c_size_t, ctypes.c_ulonglong, ctypes.c_char_p, ctypes.c_char_p,
    ]

Without that, subkey_id is treated as C int instead of uint64_t. This is most likely causing #122 (Cannot use 64bit subkey ID) and the segfault on ARM architecture.

Take the above fix with a grain of NaCl though. I'm not really a ctypes expert.
You probably know about tools like Cython or CFFI, which can use info in .h files to avoid problems like this.

Add cuvecp handshake

I want to add classes and methods that encapsulate the curvecp key handshake and messaging. The goal being to make it super easy to use libnacl for network communication very easy

libnacl, mingw and Windows

TL;DR init.py looks for libsodium.dll, but the prebuilt dll is libsodium-10.dll. Easy fix is to rename it but I don't know what that might break. Alternate fix is to make dependency lookup version-independent.

Here is my setup story on both a Mac and Windows machine, for posterity.

I first trialed libnacl on a Mac dev box and when I tried to pip install libnacl, I got an error saying I was missing a nacl lib. In fact, this was my first time even hearing about libsodium (I was using tweetnacl) but thankfully, it was only a brew install libsodium away and I was up and running before long. Great!

However...

For many unsavory reasons, I do most of my development in Windows, so I now had to figure out how to satisfy the nacl dependency without brew. I was using a weird mix of cygwin and msys so I wasn't entirely sure where to place a dll even if I got my hands on one.

I noticed libsodium had prebuilt releases for mingw, so I jettisoned my cygwin setup and started with mingw from scratch. After finding a dll named libsodium-10.dll in the libsodium release tarball, I figured I'd place it in C:\MinGW\bin and that would be that. Well, init.py looks specifically for libsodium.dll so the dll had to be renamed before it was happy.

It would be an easy fix to make the lookup in python a less version-dependent but I don't know how safe that is in both a security and dependency sense.

Cannot use 64bit subkey ID with kdf_derive_from_key

libsodium is allowing a uint64_t subkey_id for crypto_kdf_derive_from_key, but ctypes seems to truncate the 64bit value.

A possible fix is to use ctypes.c_ulonglong(subkey_id) in the snippet below.

nacl.crypto_kdf_derive_from_key(buf, subkey_size, subkey_id, context, master_key)

How to reproduce:

subkey_id = 14303928198542443005
master_key = b"12345678901234567890123456789012"
buf = libnacl.crypto_kdf_derive_from_key(16, subkey_id, b"Context0", master_key)
print(buf.hex())

Result: 1e6d55e5b5abb245a32596f946926644
Result with the fix: 3fb440810c54617ab62096b56409a3e2

Reference C code:

uint8_t master_key[32] = "12345678901234567890123456789012";
uint64_t keyid = 14303928198542443005ULL;
uint8_t subkey[16];

crypto_kdf_derive_from_key(subkey, sizeof subkey, keyid, "Context0", master_key);
for (int i=0; i<sizeof subkey; i++)
   printf("%02x", subkey[i]);

Result: 3fb440810c54617ab62096b56409a3e2

crypto_box_open,crypto_box_open_easy

crypto_box_open_easy() and crypto_box_open() in libsodium seem to be different。
企业微信截图_eb11d952-87b8-4c5d-b8d1-5bd861e1624b

`def inttobytes(param_int_list):
param_hex = ""
for param_int in param_int_list:
if param_int<0:
param_int = param_int + 256
if len(hex(param_int)[2:])==1:
param_hex = param_hex + "0" + hex(param_int)[2:]
else:
param_hex = param_hex + hex(param_int)[2:]
return bytes.fromhex(param_hex)

def bytesToString(bs):
return bytes.decode(bs,encoding='utf8')

privateKey_int_list = [-42,23,-8,-49,68,59,-86,57,124,-34,-56,90,44,-103,-48,115,-94,57,-32,-53,40,-82,7,-66,-15,-83,72,25,-14,105,95,-61]
privateKey = base64.b64decode("1hf4z0Q7qjl83shaLJnQc6I54Msorge+8a1IGfJpX8M=")
publickey_int_list = [95,73,-2,-73,63,-78,-1,41,-103,73,125,-8,-78,122,-5,-124,36,-23,9,-125,38,-81,-63,3,-63,26,-12,-33,120,60,-23,36]
publickey = inttobytes(publickey_int_list)
bArr2_int_hex= [-41,-81,-73,-39,-40,106,-127,82,5,118,83,-128,-121,-81,-17,63,-121,6,108,-81,-99,75,93,105,-74,22,21,67,72,-101,110,108,55,-60,-64,-115,-4,-49,15,80,-95,51,98,31,-1,7,86,78,-27,-128,-78,-74,-86,-78,123,28,-126,-41,-76,97,51,-11,122,65,-80,-80,-114,-90,13,-55,-101,89,-112,-7,-31,64,92,61,-111,49,-35,-120,110,-6,-26,107,61,5,88,57,75,-102,18,-104,120,15,-124,58,19,-9,-12,-45,-22,14,42,-51,-90,39,-109,-70,89,53,-80,-19,-55,-93,-42,29,-46,-116,-96,-8,33,1,-9,-68,-119,-116,34,-78,-54,-29,-6,-100,-74,33,-89,-87,6,-8,43,-74,75,8,-57,-9,12,25,60,67,52,32,53,54,59,107,38,85,-83,-45,-1,32,93,-11,-17,-19,-41,116,-56,74,70,10,-70,20,-119,-113,55,80,-98,31,-99,-36,88,114,72,-40,75,116,44,-65,92,-61,106,88,121,-79,-18,-33,-73,-86,-13,-33,19,125,71,2,104,-16,-23,72,-91,-75,-54,-3,-63,111,69,87,24,10,19,-108,-111,-21,118,-51,20,98,-54,44,-59,-110,69,77,14,-70,40,80,-31,-50,43,-82,-11,-2,-96,-89,101,34,-8,54,-5,-86,-31,19,25,123,-106,-23,105,73,-26,-61,118,-111,37,108,114,77,-43,-50,83,76,-71,-55,65,9,90,-115,121,-81,-51,88,89,-29,-97,5,-46,-21,-59,33,-51,34,-27,18,95,65,-98,-68,86,-65,-96,91,-86,52,-33,-26,-121,-63,68,-41,-114,125,62,62,39,-51,85,95,-90,-8,77]
bArr2 = inttobytes(bArr2_int_hex)
bArr3_int_hex = [106,112,-58,-70,28,-71,45,-121,65,24,13,48,96,39,79,-15,37,-73,125,-6,120,-78,-54,-111]
bArr3 = inttobytes(bArr3_int_hex)
i = 321
bArr_int_hex = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
bArr = inttobytes(bArr_int_hex)
print(libnacl.crypto_box_open_easy(bArr2,bArr3,publickey,privateKey))`

When I change crypto_box_open in the picture to crypto_box_open_easy, no Crypterror will be reported

Custom exceptions

We are using ValueError everywhere, this should be changed to a custom exception type

crypto_scalarmult_base can segfault

$ python
Python 3.5.1 (default, Dec  7 2015, 12:58:09) 
[GCC 5.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import libnacl
>>> libnacl.crypto_scalarmult_base(None)
Segmentation fault (core dumped)

This came up in keybase/saltpack-python#1.

undefined symbol errors on libnacl 1.7

On debian 8, when upgrading to 1.7 I see this error:

ImportError: Failed to import test module: unit.modules.test_nacl
Traceback (most recent call last):
  File "/usr/lib/python2.7/unittest/loader.py", line 254, in _find_tests
    module = self._get_module_from_name(name)
  File "/usr/lib/python2.7/unittest/loader.py", line 232, in _get_module_from_name
    __import__(name)
  File "/tmp/kitchen/testing/tests/unit/modules/test_nacl.py", line 10, in <module>
    import salt.modules.nacl as nacl
  File "/tmp/kitchen/testing/salt/modules/nacl.py", line 157, in <module>
    import salt.utils.nacl
  File "/tmp/kitchen/testing/salt/utils/nacl.py", line 26, in <module>
    import libnacl.secret
  File "/tmp/kitchen/testing/.nox/runtests-parametrized-2-7-coverage-true-crypto-none-transport-zeromq/local/lib/python2.7/site-packages/libnacl/__init__.py", line 166, in <module>
    randombytes_SEEDBYTES = nacl.randombytes_seedbytes()
  File "/usr/lib/python2.7/ctypes/__init__.py", line 378, in __getattr__
    func = self.__getitem__(name)
  File "/usr/lib/python2.7/ctypes/__init__.py", line 383, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /usr/lib/x86_64-linux-gnu/libsodium.so: undefined symbol: randombytes_seedbytes

This is because randombytes_seedbytes was added here jedisct1/libsodium@cafb0a6 which was added to libsodium version 1.0.12 and by default it runs libsodium18:amd64 1.0.8-5

I'm also seeing this error on amazon linux 1 for similar reasons:

ImportError: Failed to import test module: integration.runners.test_nacl
Traceback (most recent call last):
  File "/usr/lib64/python2.7/unittest/loader.py", line 254, in _find_tests
    module = self._get_module_from_name(name)
  File "/usr/lib64/python2.7/unittest/loader.py", line 232, in _get_module_from_name
    __import__(name)
  File "/tmp/kitchen/testing/tests/integration/runners/test_nacl.py", line 15, in <module>
    import libnacl.secret  # pylint: disable=unused-import
  File "/tmp/kitchen/testing/.nox/runtests-parametrized-2-7-coverage-true-crypto-none-transport-zeromq/local/lib/python2.7/site-packages/libnacl/__init__.py", line 126, in <module>
    crypto_box_SEEDBYTES = nacl.crypto_box_seedbytes()
  File "/usr/lib64/python2.7/ctypes/__init__.py", line 374, in __getattr__
    func = self.__getitem__(name)
  File "/usr/lib64/python2.7/ctypes/__init__.py", line 379, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /usr/lib64/libsodium.so.4: undefined symbol: crypto_box_seedbytes

ping @thatch45 should we just add this to a try/except or update docs for libsodium version requirements? im willing to put a PR together, just not sure the correct approach here.

Undocumented change of interface.

the d1b25c0 change which was included in the 1.5.1 release changed the interface when failing to decrypt a message from ValueError to CryptError.

While I'm all for consistent interfaces, please do document these kinds of API changes in the Changelog, as they did unexpectedly affect our code base and will likely bite anybody who just updates to the latest patch-version of the code 1.5 branch.

utils.load_key exception on loading saved Signer key

In [5]: signer = libnacl.sign.Signer()

In [6]: signer.save('dev_nacl.key')

In [7]: libnacl.utils.load_key('dev_nacl.key')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
... in <module>()
----> 1 libnacl.utils.load_key('dev_nacl.key')

C:\Python33\lib\site-packages\libnacl\utils.py in load_key(path, serial)
     28         return libnacl.dual.DualSecret(
     29                 libnacl.encode.hex_decode(key_data['priv']),
---> 30                 libnacl.encode.hex_decode(key_data['sign']))
     31     elif 'priv' in key_data:
     32         return libnacl.public.SecretKey(

C:\Python33\lib\site-packages\libnacl\dual.py in __init__(self, crypt, sign)
     15     '''
     16     def __init__(self, crypt=None, sign=None):
---> 17         self.crypt = libnacl.public.SecretKey(crypt)
     18         self.signer = libnacl.sign.Signer(sign)
     19         self.sk = self.crypt.sk

C:\Python33\lib\site-packages\libnacl\public.py in __init__(self, sk)
     33             self.pk = libnacl.crypto_scalarmult_base(sk)
     34         else:
---> 35             raise ValueError('Passed in invalid secret key')
     36
     37

ValueError: Passed in invalid secret key

The file "dev_nacl.key" has the fields sign - 32 bytes, verify - 32 bytes, and priv - 64 bytes. It looks like priv is passed in as the crypt param to a DualSecret object, which is in turn passed as sk to SecretKey, which in turn is unhappy about the priv's length being 64 and not 32. It seems that box and sign differ in the lengths of their secret keys.

The problem may be that the key is being read back in as a DualSecret rather than a signer, or that the JSON struct doesn't adequately capture the different key types.

As a newcomer to nacl I'm also kind of confused about all the different key types and their relations in addition to libnacl's renaming of them. Some clarification in the docs would be very helpful.

Thanks!!

(Not Issue) Question Regarding Dual Keys

Hello.

Thank you for the very well documented and finely crafted software. We are currently evaluating and considering for developing a security infrastructure.

I have a query regarding dual keys. Ed25519 keys can be converted to Curve25519 keys (http://doc.libsodium.org/advanced/ed25519-curve25519.html). Is this the same relationship between the signing -> encryption keys in dual keys?

Also, more out of curiosity, can we generate sub-keys from either Ed25519/Curve25519 keys?

Thanks very much.

Sam

File saving to file-like objects

Use case: retrieve a key from server, then decrypt it. It could look like:

import requests
from Crypto.Cipher import AES
from filelike.wrappers import Decrypt
from libnacl.utils import load_key

enc = requests.get("http://example.com/keybackup.aes").raw # http://urllib3.readthedocs.org/
cipher = AES.new('abcdefgh')
dec = Decrypt(enc, cipher) # http://www.rfk.id.au/software/filelike/
key = load_key(dec)

And the same thing with saving.

Then, loading key from file would look like just load_key(open("abc.key", 'r')). For a smooth transition we could check if the first parameter is a string and open a file accordingly:

def load_key(fp, serial='json'):
    if not is_filelike(fp, 'r'):
        fp = open(fp, 'rb')
    # ...

Please include install direction in the readme.

Please include install direction in the readme.

salt module nacl references this git project for install directions.

[yum|apt-get] install libsodium
pip install?
or perhaps:
git cone https://github.com/saltstack/libnacl.git /tmp/libnacl
mv /tmp/libnacl/libnacl /usr/lib/python2.7/site-packages/libnacl

Naming and invocation consitency

I think it'd be better if for each Object.x where Object.hex_x() exists, there would be Object.x_hex instead.

Since this might introduce incompatibilities with previous versions, I create this ticket for the discussion on how to move forward (for example, this idea has not value at all :))

python3 setup.py test failed with new libsodium 1.0.15

Hi, I'm one packager maintainer of libnacl on Linux Fedora, I got a report today that fails to build from the source with new libsodium 1.0.15 in rawhide [1]
It is an easy fix ?

[1]
https://koji.fedoraproject.org/koji/buildinfo?buildID=977895
https://kojipkgs.fedoraproject.org//work/tasks/4814/22204814/build.log

libnacl (unittest.loader._FailedTest) ... ERROR
======================================================================
ERROR: libnacl (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: libnacl
Traceback (most recent call last):
  File "/usr/lib/python3.6/unittest/loader.py", line 462, in _find_test_path
    package = self._get_module_from_name(name)
  File "/usr/lib/python3.6/unittest/loader.py", line 369, in _get_module_from_name
    __import__(name)
  File "/builddir/build/BUILD/libnacl-1.5.2/libnacl/__init__.py", line 83, in <module>
    nacl = _get_nacl()
  File "/builddir/build/BUILD/libnacl-1.5.2/libnacl/__init__.py", line 81, in _get_nacl
    raise OSError(msg)
OSError: Could not locate nacl lib, searched for libsodium.so, libsodium.so.18, libsodium.so.17, libsodium.so.13, libsodium.so.10, libsodium.so.5, libsodium.so.4, 

TestRandomBytes.test_crypto_kdf_derive_from_key fails on 32-bit x86

________________________________________________ TestRandomBytes.test_crypto_kdf_derive_from_key _________________________________________________

self = <unit.test_raw_random.TestRandomBytes testMethod=test_crypto_kdf_derive_from_key>

    def test_crypto_kdf_derive_from_key(self):
    
      master_key = libnacl.crypto_kdf_keygen()
      subkey = libnacl.crypto_kdf_derive_from_key(16, 1, "Examples", master_key)
      subkey2 = libnacl.crypto_kdf_derive_from_key(16, 1, "Examples", master_key)
      subkey3 = libnacl.crypto_kdf_derive_from_key(16, 2, "Examples", master_key)
    
      self.assertEqual(16, len(subkey))
      self.assertEqual(16, len(subkey2))
      self.assertEqual(16, len(subkey3))
>     self.assertEqual(subkey, subkey2)
E     AssertionError: b'r\xefe\xafr~\x9f\xf5\xe7\x17uK\xa7Ty-' != b'\xf5N\x9c\xe9\xc6\x1ag\xe6\xffJ\xd7\xf8\xd1>\xb8\x12'

tests/unit/test_raw_random.py:64: AssertionError
$ python --version
Python 3.8.8
$ pkg-config --modversion libsodium
1.0.18

Reproduced with git 33b22d2.

Judging by #123, this function has serious portability problems.

Tests failure on Win32 - wrong umask?

test_save.py due to missing os.close() for the mkstemp returned file handle and due to -
base.py:57:

cumask = os.umask(191)

on win32 this sets the file as read only for the user and os.remove() will fail on it.
It may be helpful to use stat.* symbolic flags instead hardcoded numbers?

Support for Key type conversion

In some applications it might be nice to not have to generate and manage both a signing key pair and an encryption key pair. Since Ed25519 and Curve25519 keys are birationally equivalent , one can be converted into the other. Libsodium has a function, to perform this conversion. The request to to expose this function in libnacl.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.