* mt_rand() isn't a CSPRNG and you can't use it to generate crypto parameters.
* You're using a table of very small primes to generate the RSA modulus.
* Real cryptosystems very rarely ever encrypt directly with RSA, and it's dangerous to do so. RSA is used to wrap a symmetric key, or to sign messages during key agreement.
* Given that the raw plaintext of these secret messages is running through the server anyways, you might as well get rid of the RSA and just use SQL "DELETE FROM" as your safeguard.
I understand why one would write an app like this: because it's fun. And that's fine! Just cast it as a game, not as a tool for people in oppressive countries who could be tortured for using something like this.
Any hints on a good way to encrypt the message itself instead of RSA?
And yes, it was created just for fun and as a learning experience for myself. I agree that it does look too serious for what it really is, will definitely change that.
On a side note, I'm genuinely honored and humbled that you took the time to look at my project and provide feedback! Matasano is absolutely killing it in the security field!
EDIT: First thing tomorrow morning (it's midnight here) I'll restyle the site to make it clear that it's just a game, not something you can bet your life on.
Just read random bytes from /dev/urandom. Smart people have already taken the time to work out how to give your platform fast random number generation.
Don't use a table of primes for p and q. Look at BN_generate_prime_ex() in OpenSSL for a simple sieve algorithm. Your RSA key size is a function of the product of p and q; they should be bignums.
Incorporate an AES library. Generate AES keys by reading 128 bits of random bytes from /dev/urandom. Generate a 64 bit random number the same way, then encrypt the message in CTR mode using that 64 bit number as the nonce; you'll need a new one for every message. After encrypting with AES to generate a ciphertext, run the ciphertext through HMAC-SHA2 and append that hash to the end of the ciphertext. Encrypt the keys & the nonce with RSA and append that to the message. The receiver verifies the HMAC hash before it attempts to decrypt the AES-CTR encrypted message.
This is advice given under the assumption that you're doing this to learn stuff. Again: strongly advise you make a game out of this instead of trying to supply secure messaging to people.
On some systems, random(4) can block, and urandom(4) can't. Blocking can harm program correctness. The security difference on systems where random(4) behaves differently from urandom(4) is marginal. I don't think this is a point worth sweating over, given that most systems use things like Mersenne Twister and LCG algorithms for their randomness.
I recommend that you take the Applied Cryptography course from Udacity. It is an excellent, fun, well taught practical course that will cover most of the things you asked about above.
This reference installation of the site doesn't use SSL/TLS, and sends the supposedly "secret" message in the clear over the wire to your server. The decryption key is also transmitted in this manner.
As someone else mentioned, the decryption key has almost no entropy at all.
Any upstream provider (your internet cafe, ISP, FBI, etc.) or the site operator (OP) can read your "secure" message with almost no effort. This is false security.
SSL is something to consider for the future, as is increasing the entropy. I removed the 'military grade' as that might be stretching the claim a bit. Thanks for your feedback!
Interesting: just last night I received an email from the founders of Askolo announcing the their pivot to a service that does exactly this. I believe the name is "Vapor Text".
Edit: here's the email, for reference:
Hi Max,
Since Askolo soft launched earlier this year, our team has been thrilled with the quality of discussion that's taken place on the site. We've realized however, that we could make a greater impact working on other projects and we've made the difficult decision of moving Askolo into maintenance mode. All existing content will remain available on the site but future updates and new features will be discontinued.
We've recently shifted our focus to a new product - Vapor Text - that we're really excited about. Vapor lets you send private messages to friends that disappear once they're read. You can download it now from the Apple App Store: http://itunes.apple.com/app/vapor-text/id563087964?mt=8.
Thanks for all your support and free feel to reach out to hello@ovenlabs.com if you have any questions.
Sorry to play the paranoiac, but that is the demographic you're trying to appeal to!
There seems to be a key element of trust required for using this site. How do we know the code cycret.com runs is the same as what's on Github? i.e. How do we know cycret isn't actually running different code that serves as a man-in-the-middle by creating RSA encrypted channels to both the sender and receiver, but archiving plain-text of all their communications as they pass through cycret.com? Programs like GPG can be compiled from source on your own computer so that, if you understand the code, you can trust it. This doesn't appear to have that advantage!
I don't know that much about web stuff, so if there is an easy and trustable way to see what code cycret is actually running without taking your word for it, I'd be very curious to know how!
Yes, trust is absolutely an issue here. I put the code on GitHub so people can run it themselves. On the other hand, people also trust websites like gmail, their bank accounts and government stuff with their private data, without knowing anything about the encryption/decryption process behind it...
Normal people are willing to trade a bit of security away for convenience. Your system might be easier to learn, but using it doesn't appear much more convenient than using GPG, so it is necessarily going to have to live up to the standards of a more paranoid crowd.
I count about 570 different primes there, so ~9.1 bits of entropy, but yeah. This is utterly trivial to brute force, with or without the given table of fixed primes, as it's very very easy to factor primes of this size. This is like 24-bit RSA.
"The advanced RSA-encryption will take a supercomputer thousands of years to break!"
The biggest problem with these types of apps is that taking a screenshot or copying the MSG is all it takes to destroy any encryption you might have had.
They are fun apps to write and think about though.
This has been done many times before, and all rely on a trusted 3rd party to do what they say. I spent a few years on and off toying with this idea, and came up with a solution that does not need any 3rd party middleman to transmit keys or delete messages after a period of time.
If you want a real challenge, figure out how to do that.
Yes, you're absolutely right that this has been done many times before. The goal was more in lines of a learning experience for myself than to create something unique. You have captured my attention, though, can you give me a hint into the right direction on how to avoid the 3rd party?
Back in high school I was an absolute numbskull when it came to math, or exact sciences in general. It wasn’t until I picked up programming that the most basic fundamentals of math sinked in. I’m a lot more advanced now, but I still learn new stuff every day. To get out of my comfort zone, I picked up a book called ‘The Code Book’ by Simon Singh a couple of months ago. The reviews on Amazon were great, but I didn’t expect it to be the pageturner it turned out to be. If you haven’t read it, you really should! It’s amazing how much cryptography changed our society. I particularly enjoyed the part on RSA encryption.
After reading the book I had the idea of creating a system for sending encrypted messages from one person to another. Something that spies in the cold war-era would use. The One Pad Cipher is unbreakable in theory, but is difficult to accomplish because you have to secure the key distribution. RSA encryption is really secure, but there still is no way to tell if the person you’re communicating with is actually the person you think he/she is.
Building cycret.com
After reading the book I started out creating a CodeIgniter library for the RSA-encryption part. This was particularly fun because math isn’t my strongest point, but figuring out exactly what does what proved to be really rewarding.
There are a number of threats when it comes to encrypting a message:
- Man in the Middle-attack: your message is intercepted
- Breaking the cipher (either by clever decrypting or brute-forcing)
- Evesdropping on the recipient
With Cycret, there are a number of steps to follow:
- The sender asks permission from the recipient to send him/her a message through Cycret
- When the recipient accepts, a keypair is shown. This keypair is shown only once, and isn’t stored in the database. Without this keypair, the message can’t be decrypted
- The sender is notified and enters a message. The message is encrypted with the RSA algorithm
- The recipient is notified, and decrypts the message with the keypair
- After decryption, the message along with email addresses and other data is removed from the database
This procedure seems a little cumbersome (it is!) but this procedure addresses the threats I mentioned earlier:
- The message isn’t being sent, but is only stored in the database for a short while (until it’s decrypted), in encrypted form. Even if the database is compromised the malicious hacker won’t be able to do anything with the messages.
- The message is encrypted with the RSA algorithm. The decryption key isn’t stored or sent anywhere, it is only shown to the recipient once.
- Because the message is deleted (burned) right after decryption brute-forcing and evesdropping on the recipient is difficult.
After the RSA encryption-part I built the rest of the website, so the notification system and the stages of the messages.
The ethical side
I like to build things that make people think, and cycret is no different. During building it, I realized that a secure communications system can be used for both good and bad. After decryption and burning, there are no traces left of the message itself. At most you have some emails in your inbox that hint to the fact that you used cycret, but there is no way to recover the message itself. This could be great for people that are suppressed by their government and want to cook up a revolution, but can also be used to plan terrorist attacks or to order a murder or something. So the ethical side to cycret raises a bigger question: should you invent something that can be used for both good and bad?
Is it useful?
Well, you all be the judge of that. I had fun building Cycret and learned a lot about encryption technology. If you would use Cycret, that would be great, but if you just had a good conversation about the ethics of inventions you made my day, too.
Anyway, the code is on Github if you want to use the CodeIgniter RSA library.
Let me know what you think!
* You're using a table of very small primes to generate the RSA modulus.
* Real cryptosystems very rarely ever encrypt directly with RSA, and it's dangerous to do so. RSA is used to wrap a symmetric key, or to sign messages during key agreement.
* Given that the raw plaintext of these secret messages is running through the server anyways, you might as well get rid of the RSA and just use SQL "DELETE FROM" as your safeguard.
I understand why one would write an app like this: because it's fun. And that's fine! Just cast it as a game, not as a tool for people in oppressive countries who could be tortured for using something like this.