Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Square Open-Sources Golang Crypto Package Based on JWE/JWS (github.com/square)
73 points by bigmac on Dec 19, 2014 | hide | past | favorite | 14 comments


The cipher subpackage is importing a third party package `github.com/apexskier/cryptoPadding` and uses only this part of it:

https://github.com/apexskier/cryptoPadding/blob/master/pkcs7...

I think it would be a good idea to avoid that otherwise small dependency with some copy-pasta/vendoring.


Good point, but apexskier/cryptoPadding doesn't have any license info, so it really shouldn't be used at all (importing, copying, or vendoring).


BTW, the author has done this, committed an hour ago. The "github.com/apexskier/cryptoPadding" dependency is removed, padBuffer() and unpadBuffer() functions which look very different than apexskier/cryptoPadding are inlined. He also added tests for the padding! Nice work!

https://github.com/square/go-jose/commit/6722e7b8407c4b2bbe2...


Dang, I was going to try to refute you by saying no license meant no restrictions, but nope! Creators of software (and any written work apparently [1]) are automatically granted copyright for their work (this makes sense) so without a license, copying it would be a violation of copyright. That's wild, but seems reasonable.

Posting it to Github isn't implicit permission, but it would probably be a factor if the author did try to sue people for using his or her copyrighted work without license/permission.

[1] http://en.wikipedia.org/wiki/Open-source_software#Open_softw...


There's also apparently terms in the Github ToS that allow viewing and forking of public projects regardless of license. What this means in a practical sense, I'm not sure.

https://help.github.com/articles/open-source-licensing/#what...


It's pretty simple. In a practical sense it means that the author of any license-free project on Github who finds their code used in other software can, very cheaply, C&D the authors of those packages.


Here are polished versions of my pkcs7 functions from the crypto challenges if anyone wants:

http://play.golang.org/p/xfAGpytsSI

Also, remember to not leak padding errors and always MAC your ciphertext. Wouldn't want you to spring a padding oracle.


If anyone was could publish a Golang crypto library I'd be inclined to trust, it'd be Square, but I think you should probably avoid JOSE.


Why?


Nothing to do with Javacript. JOSE is just very, very complicated. Until a few months ago, I reviewed systems like this professionally, and none of the good ones needed anything like the complexity of JOSE to solve their problems.

I'm automatically wary of meta-crypto-protocols. If it isn't designed against a very specific problem statement, cryptography is almost invariably bad.


Can't read tptacek's mind, but I'm guessing it has to do with the fact that javascript cryptography running in the browser cannot provide the guarantees necessary for a reliable cryptosystem. You can't tell whether the browser has been compromised or is malicious. Although strictly; speaking there may be other good reasons to use this standard and plenty of non-browser contexts for javascript execution do exist and aren't necessarily as vulnerable.


Every time I see JOSE/JWE/JWS/JWT I want to cry. SPKI did this, better, more readably and more attractively, back in 1999. It was also more reliable: JSON itself imposes no ordering on object elements (i.e., '{"foo": 1, "bar": 2}' and '{"bar": 2, "foo": 1}' are equivalent, but they will hash to entirely different values, while '((foo 1) (bar 2))' and '((bar 2) (foo 1))' are not at all equivalent).

Moreover, SPKI was flat-out more readable. Compare:

    (sequence
     (cert (issuer (hash sha256 |mbKsNmlDk1d1WGcl1s25LDCYeCGjDgC7FFNSdBK8PIE|))
           (subject (bearer))
           (valid (not-after 2011-03-22_12:43:00))
           (tag (http://example.com/is_root true)))
     (signature (hash sha256 |0XVRFpmUgNOep+Mud3FrmQC5d52r3PPVVnJyYtMK800=|)
                (hash sha256 |mbKsNmlDk1d1WGcl1s25LDCYeCGjDgC7FFNSdBK8PIE=|)
                (ecdsa-sha256
                 (r |xOUGRpq1a3V6cnn/fVgfEgCuxDCy9HO1Nyhni6NBgr8=|)
                 (s |miT9LZh7VlBDscXn++n2+zcjtoQejDJ8v0G37RQGsaQ=|))))
to:

    {
      "payload": "eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ",
      "protected": "eyJhbGciOiJFUzI1NiJ9",
      "header": {"kid":"e9bc097a-ce51-4036-9562-d2ade882db0d"},
      "signature": "DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3-Kg6NU1Q"
    }
By comparison, the SPKI version is a model of clarity: one can actually see the thing being attested-to; by contrast the JSON version base64-encodes its assertion '{"iss":"joe", "exp":1300819380, "http://example.com/is_root":true}' (the SPKI version is the '(cert …)' expression). Likewise, where the JSON version base64-encodes '{"alg":"ES256"}' the SPKI version just writes 'ecdsa-sha256'.

As noted, in the JSON '{"alg":"ES256"}', '{"alg": "ES256"}', '{"alg":\n"ES256"}' and '{"alg":\r\n"ES256"}' all are different values, even though they mean the exact same thing. In contrast, SPKI uses canonical S-expressions, so that 'ecdsa-sha256' encodes to '12:ecdsa-sha256'. Likewise, there are a literally infinite number of ways to encode the JSON payload, whereas with SPKI's canonical S-expressions the certificate will always encode to a string '(4:cert(6:issuer(4:hash6:sha25632:…))(7:subject' and so forth, meaning that the given attestation will always yield the exact same value, with the exact same hash.

Moreover, the key identification semantics are much cleaner in SPKI. In the JSON version, the key id 'kid' is an opaque value; in one example in the standard it's a date and in another it's a UUID of unknown provenance. In SPKI, keys (principals) are identified by their hashes (the JSON stuff can't do this since there's no repeatable way to hash a JSON-encoded key). So the signing key is referred to as '(hash sha256 |mbKsNmlDk1d1WGcl1s25LDCYeCGjDgC7FFNSdBK8PIE|)' and there's never any ambiguity or concern—and certainly no collisions!

And of course SPKI supports a whole lot more than just bearer tokens, being a complete PKI (better thought-out than XPKI too).

I propose a corollary to Greenspun's Tenth Law: Any sufficiently complicated data-representation contains an ad hoc, dubiously-specified, hideous, inelegant equivalent to S-expressions.


I dislike SPKI for the same reason as I dislike JOSE. Cryptographic security isn't a property of a data format, nor is there a clear way to layer it onto arbitrary data formats. Properly designed cryptography functions at a higher layer that that.


> I dislike SPKI for the same reason as I dislike JOSE.

They're different things though.

> Cryptographic security isn't a property of a data format…

True, although a data format can have cryptographic issues (e.g. there should be one and only one encoding for a particular datum, and if there're multiple encodings then there are issues).

> …nor is there a clear way to layer it onto arbitrary data formats.

True enough, which is why canonical S-expressions were invented by Ron Rivest in order to enable a particular type of PKI—the format was created in order to serve a purpose; the purpose wasn't crammed atop some random format.

> Properly designed cryptography functions at a higher layer that that.

You're of course correct. Fortunately, SPKI does work at a higher level than its (elegant) data format: it's actually all about trust calculus across certificate and name tuples. It's mostly orthogonal to encryption, but encryption just kinda falls out naturally from what it does handle.

And S-expressions are still so, so much nicer than JSON.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: