Saltstack: Changing RSA public exponent from 1 to 65537
github.com
github.com
Every time I write something that involves some crypto I get absolutely terrified of what I'm likely to mess up. For that reason I almost always use an existing system or protocol. For example, on one of the projects I'm working on at CloudFlare we needed a secure connection across the Internet so I went with TLS 1.2. For another I needed the same thing but with better authentication: TLS 1.2 with client and server certificates. If I need to exchange encrypted messages in some store and forward style I'd likely use PGP.
And then for another project I needed to actually get something someone else had encrypted with RSA and decrypt it. Nightmare. If you find yourself calling low-level crypto APIs start to worry.
I'm really hoping crypto 2 actually starts in about 10 days as it seems to have been put back a lot.
--edit-- Just to sell it further, it also goes into padding oracles, timing attacks and a variety of clever stuff to show you just how easy it is to screw up :)
My mind was blown on every course video.
Good!
" For that reason I almost always use an existing system or protocol."
Excellent! If only every was like you we wouldn't have these problems.
The key to understanding this is to understand that cryptography is not 'writing some crypto code'. No part of cryptography has anything to do with the code. Cryptography is about math - feel free to do some cryptography math and work on a mathematical algorithm. Once you have a perfect algorithm that has been peer reviewed, then you can transcribe that mathematical algorithm into code.
Failing to understand the math first means you have already failed and simply should not have even begun.
Cryptography: math first, code later. Failure to follow this sequence means you will be ridiculed and any excuse is simply not good enough.
That's just how it is, and if I had to highlight one sentence from your comment it would be "Failing to understand the math first means you have already failed and simply should not have even begun."
I wish people would understand this instead of thinking trial and error works for cryptography. I mean, heck, most of us learned to code through trial and error, and I can understand why people think they can learn cryptography the same way, but that is not true, and a very toxic mindset.
> No part of cryptography has anything to do with the code.
There have been successful attacks against cryptography based on attacking the implementation. For example if two code paths take different time to execute, it is possible that this leaks information.
This is another reason why you should use a well honed library implementation of cryptography, for example OpenSSL.
This does of course not imply that the crypto–the maths of it–is broken. One just needs to be aware that it is not, in fact, sufficient to implement the maths correctly.
Generally, however, nearly all failures of security come from misunderstanding the math when creating the implementation. So I'd say that at least ensuring anybody writing crypto has a completely understanding of the crypto math before touching the code is a very good first step in getting somewhere.
# TODO add crypto
vs
# TODO get someone to review the crypto later
Do you or others have any recommendations for cross-platform library code (at least OSX, Windows, Android, Linux, Windows 8) for this purpose?
I may have understood incorrectly, but I thought that using gpg from code required launching a sub-process (e.g. via gpgme). That makes me very nervous from a library point of view, perhaps I'm wrong to be nervous.
Is the answer still "use PGP/GPG" or is there somewhere else I could look to avoid home-made cryptosystem here?
If you want the PGP-level stuff then there's GPGME: http://www.gnupg.org/related_software/gpgme/index.en.html
And I think GPGME is a lib which "under the hood" spawns a command-line gpg process? http://www.gnupg.org/faq/GnuPG-FAQ.html#cant-we-have-a-gpg-l...
At the moment it looks like my choice is between implementing a cryptosystem on top of crypto primitives (from openssl or libcrypt) or seeing if I can get away with shipping a lib which spawns child processes via gpgme.
I think a major issue is the lack of understanding of best-practices with regards to security. So we tend to rely on the security of systems that aren't battle-proven. But even battle-proven solutions still have vulnerabilities, so we need to rely on multiple layers of security.
For me at least, this reinforces the lesson to put systems as much as possible behind multiple layers of security such as firewalls and VPN. And I should be careful to architect salt systems in a hub/spoke topology using salt-master and syndics. And encrypt any traffic from the salt-master to groups of servers using ssh tunneling. Looks like pyzmq now supports ssh tunneling, so maybe this would work:
I'm asking because they seem to treat it like a minor issue:
It's of course questionable whether 1 (not a prime) was a good choice for the exponent to begin with, but it's hardly necessary to lose faith over this.
A large part of the security of RSA relies on you not being able to figure out d from N and e. Now the key element of RSA is that
de = 1 mod (p-1)(q-1)
So what happens if e = 1? You get d = 1 mod (p-1)(q-1)
So you know the value of d. So you know the private key. So you can decrypt everything.But you don't actually need to do that because what is RSA encryption? It's computing the following (c is the cipher text you'll transmit, m is the message being sent which is to be encrypted with the public key <N,e>)
c = m^e (mod N)
If e = 1 then that's c = m (mod N)
but, oh wait, m is always < N so m (mod N) is just m, i.e. c = m
i.e. the encryption does nothing.Looking on the bright side an exponent of 1 does make RSA quite fast :-)
PS Test code for those interested showing the same N with exponents 1 and 65537 and effect of encryption: https://gist.github.com/jgrahamc/5933984
The 1 mod (p-1)(q-1) comes from Euler's theorem and (p-1)(q-1) is how you calculate the totient for numbers that are the product of 2 primes p and q
May be I'm old-school but when a project goes over certain size and there's no prominent "security" section (as important as downloads, IMHO), that's a red flag for me.
This is the way you do it:
- http://httpd.apache.org/security_report.html
- http://openssh.org/security.html
- http://nginx.org/en/security_advisories.html
All projects doing sensible tasks have a security history. Don't hide it, make it public and accessible to your users.
[1]: http://docs.saltstack.com/topics/releases/0.15.1.html#rsa-ke...
So this bug was found and fixed by a proper professional audit. Neat.
Crypto is hard, and you shouldn't really be making these choices.
>> I shouldn't have to know about the chinese remainder theorem to use crypto properly.
Then stay out of it. Choose a library/framework that is popular, well tested and high level enough that you don't have to make these choices.
NaCl in particular provides simple Public/Private and Symmetric modes. The Authenticated Encryption Symmetric mode here is good - http://nacl.cr.yp.to/secretbox.html
Yes, and if you're going to use low level constructions he's right, and that will never change.
>> This is a valid complaint and "don't do it" isn't a valid solution.
Except that's not what I said, I said find a higher level library. When he asked I gave examples.
>> Too many "libraries" consist only of implementations of the crypto algorithms, but don't give any help with the proper use.
Then these may be the wrong libraries to use to secure your application. Great libs to poke around in the lower levels for a variety of other purposes of course.
On the flip side this should have set off warning bells for them - it can be a little bit of a code smell to pick 1 for a configurable value in your encryption. Not always a bad choice, but 1 has a lot of properties that can simplify various mathematical operations and Basically setting a crypto value to the smallest positive integer (and a non-prime at that!) is like deciding that a set of numbers in your code should always be represented by two-byte signed ints. Sometimes that's _exactly_ what you want (say, various fast math libraries), but if you're doing general purpose code you should really stop and think about whether you might end up with a value outside that.
This attitude scares me. Some things really are hard to do. Some things really are hard to understand. Some are even both. Remember what Euclid is supposed to have said to Ptolemy I of Egypt when the king complained that geometry was hard to learn: There is no royal road to mathematics!
There's no shame in not being able to do or understand every difficult thing under the sun, but don't complain that such things "shouldn't be so hard". They often are. I think it's part of what makes life interesting.
Of course cryptography is hard, and it is an interesting topic (one I know a few things about as it turns out).
That's not even really a "security" concern, that's just good software engineering. Passing this function something that fails the prerequisites ought to be checked. (And yes, I'd check that it's prime, too. It's an expensive check once, but trivially memoized, and you can even prefill the memoization with the usual 65537 value to make it even cheaper. In this particular case, IIRC, the exponent is always or nearly always simply reused,)
I shouldn't have to know about gasoline to drive a car.
What's wrong with these statements?
The universe doesn't care that something "should" be easy.
A crypto library is the pilot. A crypto library that allows you to use insecure settings is a pilot who crashes the plane into a mountain because you asked him to.
Item 4 here: https://en.wikipedia.org/wiki/RSA_(algorithm)#Key_generation