rubycrypto / rbnacl Goto Github PK
View Code? Open in Web Editor NEWRuby FFI binding to the Networking and Cryptography (NaCl) library (a.k.a. libsodium)
License: MIT License
Ruby FFI binding to the Networking and Cryptography (NaCl) library (a.k.a. libsodium)
License: MIT License
libsodium 0.6.0 added a ChaCha20+Poly1305 AEAD construction. This should be exposed via RbNaCl:
I'd like for the second arg of the key constructors to specify an encoding, e.g.:
Crypto::PrivateKey.new(str, :base58)
...but I see Crypto::PrivateKey
takes a public key as its second argument. I don't think this should be necessary as you should be able to calculate the private key with Curve25519 multiplication, so there shouldn't ever be a need for the user to pass it in themselves.
But I'm tempted to rename it SymmetricBox
, since it is that. And also to avoid confusion with you not using a SecretKey
for a SecretBox
.
Also, could I have the commit bit on this repo, please? New features should stay in PRs, but for docco fixes and other similar things, it would be easier. Also that way we can divide up the API by issues and assigned to's.
RbNaCl::Hash::Blake2b::KEYBYTES_MIN
is presently 16
and any keys that are less than 16 bytes are rejected. However, this is not correct according to the Blake2b paper:
http://eprint.iacr.org/2013/322.pdf
Key byte length (1 byte): an integer in [0,64] for BLAKE2b, in [0,32]
for BLAKE2s (set to 0 if no key is used)
Emitting ⊥ could also be returning false
or nil
, since that is not a valid string. In situations where you're checking anyway, this could be cheaper than raising. This should be implemented in a manner consistent with the bang methods for authentication tag and signature checking.
The PGP key given here: https://raw.github.com/cryptosphere/rbnacl/master/rbnacl.gpg has expired.
libsodium-0.4.3 installed from source, make check passes
Ubuntu 13.04 (GNU/Linux 3.8.0-29-generic x86_64)
(Vagrant VM, also fails on remote server (ubuntu 12.10))
ruby 2.0.0-p247 installed via rbenv
require 'rbnacl' fails in IRB, Pry, and from file with:
FFI::NotFoundError: Function 'crypto_onetimeauth_poly1305_ref' not found in [libsodium.so]
from /home/vagrant/.rbenv/versions/2.0.0-p247/gemsets/vod-gemset/gems/ffi-1.9.0/lib/ffi/library.rb:251:in `attach_function'
This gem uses the Crypto
module namespace, despite the gem being named differently.
I have been in the process of releasing a similar library based on NaCl, for which I'd already reserved the gem name cryptography
. I'd be more than happy to yield ownership of that gem name (and thus the Cryptography
namespace) to this project, since it largely implements my intended goals.
libsodium 0.7.0 adds sodium_malloc()
, sodium_allocarray()
, and sodium_free()
which manage buffers with guard pages, along with sodium_mprotect_noaccess()
, sodium_mprotect_readonly()
, and sodium_mprotect_readwrite()
for changing memory permissions.
Given these primitives, it should be possible to construct an RbNaCl::SecretBuffer
for managing things like keying material (and potentially plaintexts) which keeps buffers off-heap and preferentially marks them as PROT_NONE
when they're not in use.
Seriously broken! It doesn't even encrypt(!) due to a difference in how rubinius handles the memory for strings, apparently. I think for rubinius, we will will need to use MemoryPointer
s, not strings. Though it works for ruby and jruby, apparently.
In addition, the rbx version of ffi is missing some nice functions on FFI::MemoryPointer
like put_bytes
and get_bytes
so you end up with constructions like:
m.put_array_of_uchar(0, msg.bytes.to_a)
# or ...
ct.get_array_of_uchar(0, ct.total).pack('c*')
Which is fixed in rbx-head, by the looks of things, but is broken even on rc-1.
This is a tracking ticket for the remaining tasks prior to the first release (which I'd like to call 1.0.0)
AFAIK, these tasks are just finishing the README:
I can tackle the scalar documentation right away ;) (Edit: done!)
Presently we bind to the _ref
implementations of algorithms everywhere, e.g.:
https://github.com/cryptosphere/rbnacl/blob/master/lib/rbnacl/nacl.rb#L51
We should not be doing this. libsodium has a compat.c to support this legacy API which we are presently thunking through:
https://github.com/jedisct1/libsodium/blob/master/src/libsodium/sodium/compat.c
We should call the implementation-agnostic API directly instead. It's available in libsodium 0.4+
This is a tracking ticket for documentation changes that need to happen before we ship RbNaCl 2.0.0:
Crypto
namespace, changing it to RbNaCl
It would be nice to find some standard test vectors for Ed25519 (e.g. from the Ed25519 paper)
libsodium is now updated to 0.4.5 in Homebrew. Should we lock RbNaCl to libsodium 0.4.5+ to ensure compatibility?
We can note that users who want to use an earlier libsodium can continue to use the 1.x version, and possibly do some 1.x releases to backport certain features.
Would love a new gem release, the last release 1.1.0 was back in April and there's been some features and fixes since then we rely on :)
Are there any plans to create a higher-level library on top of RbNaCl?
One of my plans for my cryptography
gem was to both build NaCl bindings as well as provide extremely high-level APIs to access the exposed functionality.
There are still many pitfalls a developer can find themselves in when working with a library at the level currently exposed. Best crypto practice is to never reuse a key across cryptographic primitives — my library, when generating keys, would encode them in a way that limited their use to only the primitive that they were generated for (e.g., Cryptography::SecretBox.key
could only be used for secret boxes.
Similarly, the results of operations (generating keys, creating secret boxes, etc.) would be actual Ruby objects and not merely strings. Those objects can be serialized to and deserialized from things like hashes, JSON, binary strings, Base64 strings, etc. A secret box, for instance, would serialize to include the cryptographic algorithm used, the nonce, and the ciphertext itself.
This has several advantages. If a primitive is ever compromised, NaCl allows for swapping out the implementation with another one. If the ciphertexts and other cryptographic outputs are always stored with the algorithms used to generate them, upgrades can be seamless: new data will be encrypted with better algorithms, but old data can still be decrypted (with a loud warning generated) with no code changes on the user's part. Not simply storing outputs as strings also allows for "natural" operations like comparing auth tokens using ==
. Since it's an object, the method can be implemented with constant timing.
I know this is getting long, so I'll cut it short here. Do you have any plans to write even higher-level adapters as part of this library?
We can include a crypto.rb file if people want the original. I've also contacted the current owner of the "crypto" gem about letting us have the name.
They're currently sharing a lot of functionality and can be simplified, as either a super class, or as a module which implements the common functions
Right now, the values of a bunch of constants from libsodium (e.g., crypto_auth_hmacsha256_BYTES
) are hardcoded in the RbNaCl source due to FFI not giving access to C headers.
Is there any interest in determining these dynamically instead? I have code already written for a C extension that copies them over into relevant modules.
void Init_constants(void) {
VALUE mSodium = rb_const_get(rb_cObject, rb_intern("Sodium"));
VALUE mSodiumAuth = rb_const_get(mSodium, rb_intern("Auth"));
VALUE mSodiumBox = rb_const_get(mSodium, rb_intern("Box"));
VALUE mSodiumAuthHmacsha256 = rb_const_get(mSodiumAuth, rb_intern("HMACSHA256"));
rb_define_const(mSodiumAuthHmacsha256, "PRIMITIVE", rb_str_new2("hmacsha256"));
rb_define_const(mSodiumAuthHmacsha256, "VERSION", rb_str_new2(crypto_auth_hmacsha256_VERSION));
rb_define_const(mSodiumAuthHmacsha256, "BYTES", INT2NUM(crypto_auth_hmacsha256_BYTES));
...
These are handy aliases and should be provided for consistency
Right now the secret box API looks like:
crypto_secret_box.box(nonce, message)
But perhaps it could be
def box(message, options = {})
options[:nonce] ||= Crypto::Random.random_bytes(24)
...
end
This would generate a random nonce by default. Convention over configuration!
I know we discussed this on IRC before, but I'm thinking it might make a lot of sense to prepend the nonce to the message (especially in the case of the above API where it's practically necessary), and automatically remove it when decrypting the message. This feels like another one of those "on Rails" things I think would really help expedite people using the library. With a 24-byte nonce there's really little risk of a random nonce causing problems (unless people have shitty RNGs) and if they really want to use a monotonic counter or something they can input their own nonces.
Regarding the open method, I'd recommend it works like this:
def open(message, options = {})
..
end
Perhaps the user could pass options[:nonce]
if they got the nonce through some other channel than prepending it to the message, but by default, it'd just interpret the beginning of the message as the nonce.
The goal of all of this is to make the library easy to use by avoiding users even having to think about nonces by default, which given XSalsa20's unusually large 192-bit nonces is a fairly safe bet. This would make Crypto::SecretBox
as easy to use as the "ezcrypto" gem (which doesn't provide authenticated encryption o_O)
What do you think?
It's agreed, the encoding system must go!
The CurveCP handshake needs to compare domain names for equality, and they can be a variable length up to 256.
A variable length verify method would be useful for this. One possibility would be to pad A and B then compare each 32-byte chunk.
This would also be useful for the hello packet which needs to verify a string of 64 null bytes.
More compact than base32, more readable than base64. All the current base58 implementations only take integers, but there's nothing inherent in the encoding that doesn't allow raw bytes.
I know I was the one who advocated for the "verify with " ordering, but I now feel like this ordering is backward and we should've just used the same order as NaCl :(
This is how the APIs are designed consistently everywhere else, e.g. (key, message) or (nonce, message). It should also be (signature, message)
Mea culpa :(
I would suggest this change for RbNaCl 2.0
When loading RbNaCl (1.1.0) against newer versions of libsodium (0.4.3, 0.4.5) the library fails to load with the error
/home/vagrant/.rvm/gems/ruby-1.9.3-p484/gems/ffi-1.9.0/lib/ffi/library.rb:251:in `attach_function': Function 'crypto_onetimeauth_poly1305_ref' not found in [libsodium.so] (FFI::NotFoundError)
My guess is that the crypto_onetimeauth_poly1305_ref
function was removed in modern libsodium—it's just the reference implementation of poly1305 anyway. I believe that RbNaCl should be updated to depend on crypto_onetimeauth_poly1305
instead.
https://github.com/cryptosphere/rbnacl/blob/master/lib/rbnacl/hash/blake2b.rb#L36 overwrites #hash
and does so with a different signature. This feels a little weird.
Write some code which tries a few cryptographic operations the first time the library is required, to verify all is working fine with the library.
For VerifyKeys' verify method I used the following ordering:
verify(message, signature)
The idea being that you could remember this ordering as "verify message with signature". I also think this is the "natural" ordering for this sort of thing (sign at the end)
This differs from the ordering used in both NaCl and the one you used for the authenticators, which is:
verify(signature, message)
Either ordering works I guess, but they should be consistent. I'd just like to pick one that's easy to remember, and I think "verify message with signature" provides a nice mnemonic. I also remember Red25519 using the other ordering, me looking at that, and going "it really should be the other way around" which is why I did them this way in RbNaCl.
@namelessjon project moved, and Travis builds can now see libsodium, however there's a segv occuring.
I'm gonna try to dig into this, however perhaps you'll figure it out first?
I'm receiving the following attempting to require rbnacl
on a new system with libsodium 0.4.5 (via brew) and ffi 1.9.3 (just updated after 1.9.2 was pulled). Any help would be greatly appreciated. :-)
/opt/boxen/rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/ffi-1.9.3/lib/ffi/library.rb:261:in `attach_function': Function 'crypto_onetimeauth_poly1305_ref_verify' not found in [libsodium.dylib] (FFI::NotFoundError)
from /opt/boxen/rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rbnacl-1.1.0/lib/rbnacl/nacl.rb:30:in `wrap_nacl_function'
from /opt/boxen/rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rbnacl-1.1.0/lib/rbnacl/nacl.rb:29:in `module_eval'
from /opt/boxen/rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rbnacl-1.1.0/lib/rbnacl/nacl.rb:29:in `wrap_nacl_function'
from /opt/boxen/rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rbnacl-1.1.0/lib/rbnacl/nacl.rb:107:in `<module:NaCl>'
from /opt/boxen/rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rbnacl-1.1.0/lib/rbnacl/nacl.rb:14:in `<module:Crypto>'
from /opt/boxen/rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rbnacl-1.1.0/lib/rbnacl/nacl.rb:3:in `<top (required)>'
from /opt/boxen/rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:228:in `require'
from /opt/boxen/rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:228:in `block in require'
from /opt/boxen/rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:213:in `load_dependency'
from /opt/boxen/rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:228:in `require'
from /opt/boxen/rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/rbnacl-1.1.0/lib/rbnacl.rb:26:in `<top (required)>'
Sodium provides aes128ctr:
https://github.com/jedisct1/libsodium/tree/master/src/libsodium/crypto_stream/aes128ctr
While it should be considered a power user feature, CTR mode is not yet universally available via OpenSSL in Ruby, so it might be interesting to expose this to users.
aes128ctr can be trivially combined with HMAC for authentication + SHA-512 for key derivation to produce a robust authenticated encryption system that's "NIST approved". While I would love for everyone to use XSalsa20+Poly1305 for this application, some people may have requirements to the contrary, and may be scared of Poly1305 because it has not received as much scrutiny as HMAC.
If RbNaCl exposed aes128ctr, portable implementations of AES-CTR and HMAC-512256 would be available, and the latter with guaranteed constant time comparisons. This should make it incredibly easy to put together an AES-CTR + HMAC library for people who are afraid to use the djb crypto and prefer the crappier NIST-approved alternatives ;) And best of all, no OpenSSL would be required!
I've also suggested Sodium integrate aes256 as well. @jedisct1 suggested pulling in the aes256estream implementation from SUPERCOP:
Here's a strawman of how aes(128|256)ctr could be combined into an authenticated encryption primitive:
We have a lot of documentation in the README, which makes it a bit hard to find stuff.
Would it be helpful to factor this documentation into the Wiki instead of the README?
I would personally like to build a Ruby binding to CurveCP. The question is: does this belong in RbNaCl, or a separate gem?
CurveCP is an experimental "alpha quality" library. I've opened an issue about it on Sodium I'd suggest reviewing:
jedisct1/libsodium#22 (comment)
If we were to add CurveCP support to RbNaCl, I'd suggest making it an optional feature, like:
require 'rbnacl/curvecp'
or perhaps
require 'rbnacl/extremely_dangerous_warning_warning_warning/curvecp'
The documentation would need to make it extremely clear that this is a power-user feature. Perhaps something like this?
To really answer the question of whether this belongs in RbNaCl or not: CurveCP is the "Networking" portion of the Networking and Cryptography library. Without it, I don't feel the library is complete ;)
>> key = Crypto::PrivateKey.generate
=> #<Crypto::PrivateKey:1117939400065c544cbe19796d7de76a3acc47e81ea776099d3ea12f7a28782c>
>> key2 = Crypto::PrivateKey.new(key.to_bytes)
=> #<Crypto::PrivateKey:1117939400065c544cbe19796d7de76a3acc47e81ea776099d3ea12f7a28782c>
>> key == key2
=> false
>> key.public_key == key2.public_key
=> false
>> key.to_bytes == key2.to_bytes
=> true
>> key.public_key.to_bytes == key2.public_key.to_bytes
=> true
I've got this easily reproducible here: https://github.com/knewter/rbnacl/tree/feature/rbx-20-test
Anyway, this fails with the following when I try to run the tests:
--(jadams@aye-seven)-(87/pts/6)-(1722/14-Oct-13)--
--($:~/ruby/rbnacl)(feature/rbx-20-test)rbx-2.0.0@rbnacl--
$ be rake
/home/jadams/.rvm/rubies/rbx-2.0.0/bin/rbx -S rspec ./spec/rbnacl/authenticators/poly1305_spec.rb ./spec/rbnacl/boxes/curve25519xsalsa20poly1305/private_key_spec.rb ./spec/rbnacl/boxes/curve25519xsalsa20poly1305/public_key_spec.rb ./spec/rbnacl/boxes/curve25519xsalsa20poly1305_spec.rb ./spec/rbnacl/group_element_spec.rb ./spec/rbnacl/hash/blake2b_spec.rb ./spec/rbnacl/hash_spec.rb ./spec/rbnacl/hmac/sha256_spec.rb ./spec/rbnacl/hmac/sha512256_spec.rb ./spec/rbnacl/random_nonce_box_spec.rb ./spec/rbnacl/random_spec.rb ./spec/rbnacl/secret_box_spec.rb ./spec/rbnacl/signatures/ed25519/signing_key_spec.rb ./spec/rbnacl/signatures/ed25519/verify_key_spec.rb ./spec/rbnacl/util_spec.rb
An exception occurred running at_exit handlers
failed to generate correct ciphertext (RbNaCl::SelfTestFailure)
Backtrace:
RbNaCl::SelfTest.box_common_test at lib/rbnacl/self_test.rb:33
RbNaCl::SelfTest.box_test at lib/rbnacl/self_test.rb:18
Object#__script__ at lib/rbnacl/self_test.rb:127
Rubinius::CodeLoader.require at kernel/common/code_loader.rb:243
Kernel(Object)#require at kernel/common/kernel.rb:685
Object#__script__ at lib/rbnacl.rb:82
Rubinius::CodeLoader.require at kernel/common/code_loader.rb:243
Kernel(Object)#require at kernel/common/kernel.rb:685
Object#__script__ at spec/spec_helper.rb:6
Rubinius::CodeLoader.require at kernel/common/code_loader.rb:243
Kernel(Object)#require at kernel/common/kernel.rb:685
Object#__script__ at spec/rbnacl/authenticators/poly1305_spec.rb:2
Kernel(RSpec::Core::Configuration)#load at kernel/common/kernel.rb:427
{ } in RSpec::Core::Configuration#load_spec_files at /media/jadams/ssd/home/jadams/.rvm/gems/rbx-2.0.0@rbnacl/gems/rspec-core-2.14.5/lib/rspec/core/configuration.rb:896
Array#each at kernel/bootstrap/array.rb:66
RSpec::Core::Configuration#load_spec_files at /media/jadams/ssd/home/jadams/.rvm/gems/rbx-2.0.0@rbnacl/gems/rspec-core-2.14.5/lib/rspec/core/configuration.rb:896
RSpec::Core::CommandLine#run at /media/jadams/ssd/home/jadams/.rvm/gems/rbx-2.0.0@rbnacl/gems/rspec-core-2.14.5/lib/rspec/core/command_line.rb:22
RSpec::Core::Runner.run at /media/jadams/ssd/home/jadams/.rvm/gems/rbx-2.0.0@rbnacl/gems/rspec-core-2.14.5/lib/rspec/core/runner.rb:80
{ } in RSpec::Core::Runner.autorun at /media/jadams/ssd/home/jadams/.rvm/gems/rbx-2.0.0@rbnacl/gems/rspec-core-2.14.5/lib/rspec/core/runner.rb:17
Proc#call at kernel/bootstrap/proc.rb:20
Rubinius::Loader#run_at_exits at kernel/loader.rb:702
Rubinius::Loader#epilogue at kernel/loader.rb:722
Rubinius::Loader#main at kernel/loader.rb:857
/home/jadams/.rvm/rubies/rbx-2.0.0/bin/rbx -S rspec ./spec/rbnacl/authenticators/poly1305_spec.rb ./spec/rbnacl/boxes/curve25519xsalsa20poly1305/private_key_spec.rb ./spec/rbnacl/boxes/curve25519xsalsa20poly1305/public_key_spec.rb ./spec/rbnacl/boxes/curve25519xsalsa20poly1305_spec.rb ./spec/rbnacl/group_element_spec.rb ./spec/rbnacl/hash/blake2b_spec.rb ./spec/rbnacl/hash_spec.rb ./spec/rbnacl/hmac/sha256_spec.rb ./spec/rbnacl/hmac/sha512256_spec.rb ./spec/rbnacl/random_nonce_box_spec.rb ./spec/rbnacl/random_spec.rb ./spec/rbnacl/secret_box_spec.rb ./spec/rbnacl/signatures/ed25519/signing_key_spec.rb ./spec/rbnacl/signatures/ed25519/verify_key_spec.rb ./spec/rbnacl/util_spec.rb failed
I think docs on how to use/not use things in the library are very important. Employing things incorrectly is probably worse than not using them at all.
I'm not 100% certain I got the Diffie-Hellman example correct. Could someone please double check it for me? ;)
(Note: Elliptic curves are o_O)
Hey guys, Im using rbnacl from git currently and just ran bundle update
. When trying to boot my app I get this error:
../ffi-1.9.0/lib/ffi/library.rb:251:in `attach_function': Function 'crypto_sign_ed25519_seedbytes' not found in [libsodium.dylib] (FFI::NotFoundError)
from ../rbnacl-f461d4771336/lib/rbnacl/sodium.rb:29:in `sodium_constant'
from ../rbnacl-f461d4771336/lib/rbnacl/signatures/ed25519.rb:8:in `<module:Ed25519>'
from ../rbnacl-f461d4771336/lib/rbnacl/signatures/ed25519.rb:3:in `<module:Signatures>'
from ../rbnacl-f461d4771336/lib/rbnacl/signatures/ed25519.rb:2:in `<module:RbNaCl>'
from ../rbnacl-f461d4771336/lib/rbnacl/signatures/ed25519.rb:1:in `<top (required)>'
from ../rbnacl-f461d4771336/lib/rbnacl.rb:45:in `require'
from ../rbnacl-f461d4771336/lib/rbnacl.rb:45:in `<module:RbNaCl>'
from ../rbnacl-f461d4771336/lib/rbnacl.rb:13:in `<top (required)>'
Repro:
1.9.3p327 :002 > Crypto::Hash.sha512("\0")
ArgumentError: string contains null byte
cc @namelessjon
We should release 2.0.0! At the very least, we should release 2.0.0.pre. I think we're ready to do that today. There are still a few remaining documentation items to address:
* Non-raising versions of verifiers
Putting the algorithm names in each of the classes allows the core algorithms to change while retaining backwards compatibility for those who need it.
I propose the following:
RbNaCl::Box
=> RbNaCl::Curve25519XSalsa20Poly1305::Box
RbNaCl::PrivateKey
=> RbNaCl::Curve25519XSalsa20Poly1305::PrivateKey
RbNaCl::PublicKey
=> RbNaCl::Curve25519XSalsa20Poly1305::PublicKey
RbNaCl::SecretBox
=> RbNaCl::XSalsa20Poly1305::SecretBox
RbNaCl::SigningKey
=> RbNaCl::Ed25519::SigningKey
RbNaCl::VerifyKey
=> RbNaCl::Ed25519::VerifyKey
RbNaCl::Point
=> RbNaCl::Curve25519::Point
RbNaCl::Auth::OneTime
=> RbNaCl::Poly1305::OneTimeAuth
RbNaCl::Hash::Blake2b
=> RbNaCl::Blake2b::Hash
RbNaCl::HMAC::SHA256
=> RbNaCl::SHA256::HMAC
RbNaCl::HMAC::SHA512256
=> RbNaCl::SHA512256::HMAC
The original names will be preserved as shorthand aliases to the real algorithms with primitive names. The shorthand aliases will serve as the public-facing API, and those are what we should document.
The tests will work against the public-facing API, since that's what we don't want to break.
...unless I'm missing something? I'd consider this a 1.1 blocker
I originally had the string inspect APIs work like this:
#<Crypto::Point:0900000000000000000000000000000000000000000000000000000000000000>
But as @namelessjon noted, this could potentially disclose private keys. Having a bunch of copies of a key in hex format labeled Crypto::PrivateKey
floating around in the VM all super obviously is probably bad.
Perhaps we can avoid this by abbreviating how much of the key is shown:
#<Crypto::Point:090000000>
You know, kind of like git?
Right now, all the APIs in this library (that I can tell) simply defer to the default implementation in libsodium. This is dangerous, and RbNaCl needs to expose some way to both identify primitives used in an operation and specify that an alternative be used.
For instance, with the crypto_secretbox API, every function is actually a #define to crypto_secretbox_xsalsa20poly1305. What I'm asking for is:
(note: Crypto::SecretBox is being used as an example; this also applies to Crypto::Box, Crypto::Auth, et al)
It's important that these features are available immediately. Imagine that tomorrow, XSalsa20Poly1305 is broken. A patch is released to nacl/libsodium to implement crypto_secretbox_aes_256_gcm and to define crypto_secretbox using this primitive. How does a current user of RbNaCl migrate their existing data to a non-broken version?
Even without a complete break, imagine any situation where libsodium changes the default primitive. What happens if a user upgrades libsodium now that the default has changed? RbNacl will start using the new primitive transparently, and users will have a mix of data encrypted with the old and new algorithms, with no way of detecting which ciphertexts were encrypted with which algorithm (other than through trial decryption).
Scenarios like this are exactly why libsodium and nacl make this type of information available to callers. And why RbNaCl must support it as well. RbNaCl doesn't have to make the process transparent, but it must make it possible.
Tony,
Arguments are out of order in the wiki verify signature example.
Thanks,
Andy
# Check the validity of a message's signature
# Will raise RbNaCl::BadSignatureError if the signature check fails
verify_key.verify(message, signature)
It should be:
# Check the validity of a message's signature
# Will raise RbNaCl::BadSignatureError if the signature check fails
verify_key.verify(signature, message)
Method def:
https://github.com/cryptosphere/rbnacl/blob/master/lib/rbnacl/signatures/ed25519/verify_key.rb#L45
At least some of the present documentation contains hardcoded numbers instead of using the nonce length APIs:
These should be fixed to reflect the new API
I've brought it up incidentally in other bug reports, but it's worth bringing up separately: I don't believe that RbNaCl should concern itself with encodings.
It's a nice thought, but it has a lot of downsides IMHO. Every class that takes input or produces output now needs to have boilerplate code handling encoding or decoding. It makes the API less "clean". And it's incidental to (what I believe) should be the main focus of this library: crypto.
Cryptographic primitives understand one concept: bytes. Encoding data is, conceptually, a concern of transmission and storage layers. By handling encodings directly, this library takes on responsibilities which I believe are best suited for handling by other layers of an application.
For ease of use by tests (as @tarcieri mentioned earlier), a simple pair of helpers to convert between hex and binary is an easy solution.
In my mind, there is a clear separation of concerns for different parts of the "stack".
I still think that RbNaCl is far too low-level for an average programmer to use safely (and that's okay!). There's still too much that can go wrong: users can use poor sources of randomness for keys, they can reuse nonces, they can use a key across cryptographic contexts, and all sorts of other rookie mistakes. Having documentation that warns against these sorts of things has been repeatedly proven not to be good enough.
I'd much rather RbNaCl be considered a building-block for experienced folk to build "crypto for the masses" on top of, than for it to try and take on too much responsibility.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.