Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add simple "zerobinpaste" cli tool #39

Merged
merged 3 commits into from
Apr 22, 2013
Merged

Add simple "zerobinpaste" cli tool #39

merged 3 commits into from
Apr 22, 2013

Conversation

mk-fg
Copy link
Contributor

@mk-fg mk-fg commented Apr 20, 2013

Not sure how you'd feel about node-based js tool in the python app repo, but the first thing I needed to actually use the paste is to be able to do grep stuff file.log | zerobinpaste | xclip, so wrote the thing.

Initially I've started writing it in python (that's why I looked into encryption and found #38), but quickly discovered that:

  • Python lacks good aes-ccm support - it should be present in openssl-1.1.0, which hasn't yet arrived, and then there's a matter of support in bindings (or having to resort to e.g. cffi).
  • A lot of stuff way beyond aes-ccm algorithm itself is hardcoded into sjcl.js - from pbkdf2 iteration count to orthodox no-padding base64 encoding, trimming of pbkdf2 output, mac tag size and appending it to ciphertext, etc.

So the sanest way seem to be to reuse exactly the same weird code to reliably produce decryptable pastes, hence nodejs tool.

It should be easily buildable via make in "tools" path and produces self-sufficient js file, requiring only node.js to run.
make ugly can be used to also npm-install/run uglifyjs on it for 48K -> 32K size shrink.

CLI:

% zerobinpaste -h

  Usage: zerobinpaste [options] [ file ... ]

  Paste contents of file(s) or stdin to 0bin site.

  Options:

    -h, --help           output usage information
    -V, --version        output the version number
    -u, --url [url]      URL of a 0bin site
    -c, --config [path]  Path to zerobin configuration file (default: ~/.zerobinpasterc).
       Should be json-file with the same keys as can be specified on the command line.
       Example contents: {"url": "http://some-0bin.com"}

Feel free to just drop PR if you don't care about the thing (and don't want to sort out bugs filed against it), I'll be maintaining it for myself anyway.

Otherwise feel free to drop an ack and I'll go ahead and update the docs about it as well.

@sametmax
Copy link
Contributor

I'm ok with including the nodejs base tool, as it is better than
nothing.

You can update the doc, I'll include that. Thanks a lot for all your
recent bug reports.

However, my guts tells me that if the problem is that we use a a flaky
solution for encryption, the solution would be to change it for a
better one.

Indeed, we probably want something that any language can handle easily
if we want to provides plugins, API and such in the feature.

Do you have something better than sjcl in mind, or maybe juste better
settings ?

Le sam. 20 avril 2013 19:42:36 CEST, Mike Kazantsev a écrit :

Not sure how you'd feel about node-based js tool in the python app
repo, but the first thing I needed to actually use the paste is to be
able to do |grep stuff file.log | zerobinpaste | xclip|, so wrote the
thing.

Initially I've started writing it in python (that's why I looked into
encryption and found #38
#38), but quickly discovered
that:

Python lacks good aes-ccm support - it should be present in
openssl-1.1.0, which hasn't yet arrived, and then there's a matter
of support in bindings (or having to resort to e.g. cffi).
A lot of stuff way beyond aes-ccm algorithm itself is hardcoded
into sjcl.js - from pbkdf2 iteration count to orthodox no-padding
base64 encoding, trimming of pbkdf2 output, mac tag size and
appending it to ciphertext, etc.

So the sanest way seem to be to reuse exactly the same weird code to
reliably produce decryptable pastes, hence nodejs tool.

It should be easily buildable via |make| in "tools" path and produces
self-sufficient js file, requiring only node.js to run.
|make ugly| can be used to also npm-install/run uglifyjs on it for 48K
-> 32K size shrink.

CLI:

|% zerobinpaste -h

Usage: zerobinpaste [options] [ file ... ]

Paste contents of file(s) or stdin to 0bin site.

Options:

-h, --help           output usage information
-V, --version        output the version number
-u, --url [url]      URL of a 0bin site
-c, --config [path]  Path to zerobin configuration file (default: ~/.zerobinpasterc).
   Should be json-file with the same keys as can be specified on the command line.
   Example contents: {"url": "http://some-0bin.com"}

|
|

Feel free to just drop PR if you don't care about the thing (and don't
want to sort out bugs filed against it), I'll be maintaining it for
myself anyway.

Otherwise feel free to drop an ack and I'll go ahead and update the
docs about it as well.


    You can merge this Pull Request by running

git pull https://github.com/mk-fg/0bin add_zerobinpaste_cli_tool

Or view, comment on, or merge it at:

#39

    Commit Summary

@mk-fg
Copy link
Contributor Author

mk-fg commented Apr 21, 2013

Will do wrt docs.

And I'm afraid I have no experience with js-based crypto - heard in the news that web-crypt-api is on the horizon, but I guess it shouldn't be relied upon yet.

I don't think that sjcl is that bad solution, and the most evil thing I see there is using it's "convenience.js" lib:

Now, how convenience.js uses these is imho is the problem, and one solution would be to ditch it and instead of old obscure "what is this?" json return new one, like:

ccm:
  prf:
    cipher: aes
    key: XXX
  auth_tag: YYY
  ctr_size: L
  nonce: ZZZ
  auth_data:

That provides all the parameters as per RFC.

I'm fairly certain that PBKDF2 is only used in these convenience functions to bump work-factor in case of low-entropy keys like "admin123", for - well - convenience.
Since 0bin has random password, derived from some seeded RC4 or whatever cipher, I think it should be same high-entropy thing already, but dunno about js-based RNGs - maybe not really.

In any case, I'd propose to just ditch PBKDF2 entirely and just use AES-CCM directly with an explicit set of parameters which will be returned in output JSON.

That should work with newer openssl and isn't that hard to implement by hand (provided just aes primitive) (e.g. this code).

Using OCB2 in a similar direct way might be better, as it seem to be more widespread, but I didn't looked at that closely enough.

Ditching all these block-chaining stuff and going for just stream cipher (e.g. XSalsa20), where you need just a (for salsa) 64b nonce, 256b key and whatever-length plaintext - no padding, modes and such - might be another solution.
It'd sacrifice integrity/authentication though (or some hash would have to be added to key in url).
And the only "sane" widely-available (more than e.g. ccm mode) stream cipher in openssl is rc4, and that looks like a damn bad choice these days.

Maybe some ultra-fast public-key ec stuff like ed25519 would also be a good option, but I'd rather trust some stanford-aes thing than hip js non-djb implementation of that.

So in summary, I think just going for aes-ccm or aes-ocb2 with explicit parameters from sjcl.js is a good enough option and not ditching sjcl would allow for compatibility with old pastes that are still around.

@sametmax
Copy link
Contributor

Ok. It's a big decision so I'll need time to process that. I'm going to
give some calls to some encryption nerds before taking a decision,
cause I'm pretty sure my intuition is not the best bet when it comes to
this field of expertise.

Le dim. 21 avril 2013 08:55:51 CEST, Mike Kazantsev a écrit :

Will do wrt docs.

And I'm afraid I have no experience with js-based crypto - heard in
the news that web-crypt-api is on the horizon, but I guess it
shouldn't be relied upon yet.

I don't think that sjcl is that bad solution, and the most evil thing
I see there is using it's "convenience.js" lib:

AES (128-bit Rijndael) is good enough and is better than AES-256
in practice.

In fact, lots of sources seem to indicate that attacks on AES-256
either downgrade it to 128-bit complexity or make it more
vulnerable than 128-bit AES. Last link is similar attack on AES-192.

  o http://crypto.stackexchange.com/questions/5118/is-aes-256-weaker-than-192-and-128-bit-versions
  o http://eprint.iacr.org/2009/374
  o http://lukenotricks.blogspot.ru/2010/04/aes-128-versus-aes-256-encryption.html
  o http://www.schneier.com/blog/archives/2009/07/new_attack_on_a.html

Add to that the fact that 128-bit AES is more widely implemented
and gives superior performance to AES-256 and AES-192 - about 30%
here in |openssl speed aes| - without aes-ni hw acceleration.
CCM, while not yet widely implemented, seem to be simple (reusing
aes for mac as well), secure, patent-free and fairly well-exposed
(every wifi access point iirc, ipsec). Looks like a simpliest mode
to implement.

GCM seem to be hated due to implementation complexity and the fact
that no one really understands it, yet doesn't require doing 2x
encryption operations like CCM does, so seem to be most widespread.

This blogpost
<http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html>
by someone who seem to know this stuff well lists good number of
alternatives with short summary of pros/cons.

Now, how convenience.js
https://github.com/bitwiseshiftleft/sjcl/blob/master/core/convenience.js
uses these is imho is the problem, and one solution would be to ditch
it and instead of old obscure "what is this?" json return new one, like:

|ccm:
prf:
cipher: aes
key: XXX
auth_tag: YYY
ctr_size: L
nonce: ZZZ
auth_data:
|

That provides all the parameters as per RFC
http://datatracker.ietf.org/doc/rfc3610/.

I'm fairly certain that PBKDF2 is only used in these convenience
functions to bump work-factor in case of low-entropy keys like
"admin123", for - well - convenience.
Since 0bin has random password, derived from some seeded RC4 or
whatever cipher, I think it should be same high-entropy thing already,
but dunno about js-based RNGs - maybe not really.

In any case, I'd propose to just ditch PBKDF2 entirely and just use
AES-CCM directly with an explicit set of parameters which will be
returned in output JSON.

That should work with newer openssl and isn't that hard to implement
by hand (provided just aes primitive) (e.g. this code
http://sd-xbmc.googlecode.com/svn-history/r113/trunk/xbmc-addons/src/plugin.video.polishtv.live/resources/lib/crypto/cipher/ccm.py).

Using OCB2 in a similar direct way might be better, as it /seem to be/
more widespread, but I didn't looked at that closely enough.

Ditching all these block-chaining stuff and going for just stream
cipher (e.g. XSalsa20), where you need just a (for salsa) 64b nonce,
256b key and whatever-length plaintext - no padding, modes and such -
might be another solution.
It'd sacrifice integrity/authentication though (or some hash would
have to be added to key in url).
And the only "sane" widely-available (more than e.g. ccm mode) stream
cipher in openssl is rc4, and that looks like a damn bad choice these
days.

Maybe some ultra-fast public-key ec stuff like ed25519
http://ed25519.cr.yp.to/ would also be a good option, but I'd rather
trust some stanford-aes thing than hip js non-djb implementation of that.

So in summary, I think just going for aes-ccm or aes-ocb2 with
explicit parameters from sjcl.js is a good enough option and not
ditching sjcl would allow for compatibility with old pastes that are
still around.


Reply to this email directly or view it on GitHub
#39 (comment).

@mk-fg
Copy link
Contributor Author

mk-fg commented Apr 22, 2013

Pushed the doc updates, please check if readthedocs handles these correctly (especially unsure about internal links / new rst there).

@mk-fg
Copy link
Contributor Author

mk-fg commented Apr 22, 2013

Wrt crypto - cryptocat seem to have fairly well-exposed and apparently useable ed25519 implementation, which has python-ed25519 module, supported by pycryptopp, libsodium, rbnacl, reference djb's NaCl lib and seem to be fairly trendy and popular in that regard.

I plan to take a stab at replacing sjcl with that thing with much shorter native urls (url shorteners leak keys to google of all things), interoperability and smple black-box implementation being the main goals.

Should be fairly simple if js from cryptocat will "just work", but I plan to also make paste ids shorter (or rather have configurable length) - even 6 base64 chars should provide 7e10 combinations - which is not remotely close to number of pastes on even most popular sites (guessing). ed25519 should allow for much shorter key part as well.

sametmax added a commit that referenced this pull request Apr 22, 2013
@sametmax sametmax merged commit 09d7bb4 into Tygs:master Apr 22, 2013
@sametmax
Copy link
Contributor

I merged and will test read the doc.

For the crypto issue, I open #40.

@sametmax
Copy link
Contributor

I translated the doc to french. Thanks a lot, you took a lot of time for this.

@mk-fg mk-fg deleted the add_zerobinpaste_cli_tool branch April 23, 2013 06:02
@gebi
Copy link

gebi commented Aug 15, 2014

From a security point of view using using aes256/chacha20 instead of using a hybrid scheme with ed25519 is always preferred.

Currently the best recommendation would be to use chacha20poly1305. But as this is quite "new", xsalsa20poly1305 would be the more compatible choice regarding different implementations.
(chacha20poly1305 was also recently proposed as an additional cipher spec for TLS, and is already used between chrome/android and google servers in production).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants