There ought to be a way for people to get 'writing some crypto code' out of their system without it being a part of a real project. A sort of play area where you can have a go but not harm anything and people can point out your errors.
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.
"Every time I write something that involves some crypto I get absolutely terrified of what I'm likely to mess up."
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.
I recommend Coursera's Crypto 1 course - it walks you through the internals of a lot of the crypto stuff, hammers "Don't do it yourself!" into you and there are programming challenges that involve breaking crypto constructions, finding hash collisions etc etc.
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 :)
The Matasano crypto challenges ( http://www.matasano.com/articles/crypto-challenges/ ) are a great way to do this. Not by implementing crypto, but by breaking crypto in ways that will scare you away from ever implementing crypto.
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:
> If I need to exchange encrypted messages in some store and forward style I'd likely use PGP.
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?
Can someone comment on how broken it was to use 1 as exponent? Is it just a theoretical concern or does it mean the crypto could have been easily broken (as we saw with cryptocat yesterday)?
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.
In the RSA cryptosystem there are three really important numbers N (which is the product of two large primes N=pq), e (the public exponent) and d (the private exponent). The public key in an RSA scheme is <N,e> and the private key is <N,d>. The only bit of the private key that's private is d.
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 :-)
On a scale of 1-10, it was about a 15 on the broken scale. As explained in the comments on the patch, a public exponent of 1 means a private exponent of 1 (it's the inverse). This makes it completely, trivially broken.
Also note that that quote from user madduck appears to be from a user of Salt in the issue tracker, not one of the project maintainers. It seems like they added a comment below and an edit to the first comment to clarify that.
There's an entry on the release notes [1], the changelog, etc; but unless I'm missing it, looks like there's not really proper management of security issues (same thing for the recent crypto.cat bug).
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.
It's amazing that this got through, you don't need to be a crypto expert for this to jump out as wrong. Anyone with undergrad number theory or crypto should easily be able to realize that using 1 is crazy.
I don't think you necessarily need special training. A value of 1 should immediately make you wonder why you are providing it as in input at all. Interestingly, even a small prime, like 3, has no known vulnerability (but it allows other vulnerabilities to be attacked faster)
Here's a ticket to track for following the state of crypto in Saltstack, https://github.com/saltstack/salt/issues/5913. It includes a lot of thoughts from the project founder on how to handle it.
This shows crypto is much too hard. You can configure a bunch of things, but half the choices you can make (key length, exponent, etc...) will render your encryption worthless. I shouldn't have to know about the chinese remainder theorem to use crypto properly.
> This shows crypto is much too hard. You can configure a bunch of things, but half the choices you can make (key length, exponent, etc...) will render your encryption worthless. I shouldn't have to know about the chinese remainder theorem to use crypto properly.
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.
Doing your own crypto is generally hard and risky, but with a little googling there are often reasonable defaults and suggestions available from trustworthy sources. The biggest danger seems to be that people pick some random set of values & constructions and assume that's good enough without further checking.
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.
[+] [-] jgrahamc|12 years ago|reply
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.
[+] [-] RyanZAG|12 years ago|reply
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.
[+] [-] Nursie|12 years ago|reply
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 :)
[+] [-] daeken|12 years ago|reply
[+] [-] 23david|12 years ago|reply
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:
http://zeromq.github.io/pyzmq/ssh.html
[+] [-] jbert|12 years ago|reply
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?
[+] [-] aidenn0|12 years ago|reply
[+] [-] simias|12 years ago|reply
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.
[+] [-] jgrahamc|12 years ago|reply
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
So what happens if e = 1? You get 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>)
If e = 1 then that's but, oh wait, m is always < N so m (mod N) is just m, i.e. 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
[+] [-] daeken|12 years ago|reply
[+] [-] po|12 years ago|reply
[+] [-] reidrac|12 years ago|reply
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...
[+] [-] throwaway125|12 years ago|reply
[+] [-] willvarfar|12 years ago|reply
So this bug was found and fixed by a proper professional audit. Neat.
[+] [-] StavrosK|12 years ago|reply
[+] [-] ig1|12 years ago|reply
[+] [-] gizmo686|12 years ago|reply
[+] [-] ipmb|12 years ago|reply
[+] [-] norswap|12 years ago|reply
[+] [-] homeomorphic|12 years ago|reply
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.
[+] [-] Nursie|12 years ago|reply
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.
[+] [-] nieve|12 years ago|reply
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.
[+] [-] unknown|12 years ago|reply
[deleted]
[+] [-] mikeash|12 years ago|reply
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.
[+] [-] raverbashing|12 years ago|reply
Item 4 here: https://en.wikipedia.org/wiki/RSA_(algorithm)#Key_generation
[+] [-] unknown|12 years ago|reply
[deleted]