What does it mean to encrypt with a public key? [closed] - security

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
I've heard lots of public key theory, but I've never really understood how you can encrypt something that can be decrypted with a private key that you don't have.
How does encrypting a message with a public key make it so that only the person with the corresponding private key associated with that key can decrypt it?

Encryption keys come in a public/private pair. The private is closely held by the owner, but the public can be passed around to those who need to encrypt something in order to send it to the owner.
Something that has been encrypted by the public key can only be decrypted with the private key as it contains more details used by the encrypt/decrypt routines.
While this may not provide the technical details you may be looking for, hopefully it helps shed some light on the relationship between the keys.

This video by Youtube channel Art of the Problem does a good job of explaining it conceptually, before getting into the exact details of how the RSA algorithm implements it.
If you think of encryption as use of a lock and key to secure information, then standard shared-key encryption involves both you and your collaborator holding onto the same key. When you send a message, you take your message, shut it inside a locked box by using your key, then send the box to the recipient who opens it with a copy of the key that you have.
In public-private key encryption, you don't give out copies of your key; you keep your key private. Instead, you give out instructions on how to build a lock that only your key can open. You give this out to anyone who asks for it. They are responsible for building the lock and using it to secure their information before sending it back to you. If they do it correctly, then the lock they've built opens perfectly when you put your private key in it.
A different way to think about the encryption step is that you actually hand out copies of your lock to anyone who wants to send you a message. They can take this lock, slap it on their message and no one can open it to read the contents without the key - not even the original sender! This would be very expensive to do with physical locks, but is very easy to do digitally.
Public-private encryption relies on a One-way function (more correctly, a certain type of one-way function called a trapdoor function), a mathematical formula that is easy to compute, but hard to find the inputs if you only have the output. Analogously, you have a lock design such that it is easy to construct from a set of instructions, but hard to reverse engineer without seeing the actual key that fits the lock.
I tend to also think about this part in terms of tying knots. It's very easy to take a series of steps to tie a rope in knots. Even know what you did and in what order, some times it's impossible to reverse the order of the steps to undo the knot. Either you've put in a slip somewhere, or you need to get your secret knot-untying key to release the rope. (Hint: the secret knot untying key is a knife. Count your fingers when you're done.)

Look at it like this:
A message from Person B is being delivered to only Person A. Person A
has the key (Private Key) to open the Chest (Public Key) and read the
message. At this point, Person A can respond to the message and place
it back in the Chest (Public Key) and redeliver to Person B. Person B
can now use their key (Private Key of their own) to read the message in the Chest (Public Key)
Hopefully this analogy will help.

Related

Using asymmetric encryption to secure passwords

Due to our customer's demands, user passwords must be kept in some "readable" form in order to allow accounts to be converted at a later date. Unfortunately, just saving hash values and comparing them on authentication is not an option here. Storing plain passwords in the database is not an option either of course, but using an encryption scheme like AES might be one. But in that case, the key to decrypt passwords would have to be stored on the system handling authentication and I'm not quite comfortable with that.
Hoping to get "best of both worlds", my implementation is now using RSA asymmetric encryption to secure the passwords. Passwords are salted and encrypted using the public key. I disabled any additional, internal salting or padding mechanisms. The encrypted password will be the same every time, just like a MD5 or SHA1 hashed password would be. This way, the authentication system needs the public key, only. The private key is not required.
The private key is printed out, sealed and stored offline in the company's safe right after it is created. But when the accounts need to be converted later, it will allow access to the passwords.
Before we deploy this solution, I'd like to hear your opinion on this scheme. Any flaws in design? Any serious drawbacks compared to the symmetric encryption? Anything else we are missing?
Thank you very much in advance!
--
Update:
In response to Jack's arguments below, I'd like to add the relevant implementation details for our RSA-based "hashing" function:
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher rsa = Cipher.getInstance("RSA/None/NoPadding");
rsa.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cryptRaw = rsa.doFinal(saltedPassword.getBytes());
Having quickly skimmed over the paper mentioned by Jack, I think I somewhat understand the importance of preprocessing such as OAEP. Would it be alright to extend my original question and ask if there is a way to apply the needed preprocessing and still have the function return the same output every time for each input, just as a regular hashing function would? I would accept an answer to that "bonus question" here. (Or should I make that a seperate question on SOF?)
--
Update 2:
I'm having a hard time accepting one of the present answers because I feel that none really does answer my question. But I no longer expect any more answers to come, so I'll accept the one that I feel is most constructive.
I'm adding this as another answer because instead of answering the question asked (as I did in the first response) this is a workaround / alternative suggestion.
Simply put:
Use hashes BUT, whenever a user changes their password, also use your public key as follows:
Generate a random symmetric key and use it to encrypt the timestamp, user identifier, and new password.
The timestamp is to ensure you don't mess up later when trying to find the current / most up-to-date password.
Username so that you know which account you're dealing with.
Password because it is a requirement.
Store the encrypted text.
Encrypt the symmetric key using your public key.
Store the public key encrypted symmetric key with the encrypted text.
Destroy the in-memory plaintext symmetric key, leaving only the public key encrypted key.
When you need to 'convert' the accounts using the current password, you use the private key and go through the password change records. For each one:
Using the private key, decrypt the symmetric key.
Using the symmetric key, decrypt the record.
If you have a record for this user already, compare timestamps, and keep the password that is most recent (discarding the older).
Lather, rinse, repeat.
(Frankly I'm probably overdoing things by encrypting the timestamp and not leaving it plaintext, but I'm paranoid and I have a thing for timestamps. Don't get me started.)
Since you only use the public key when changing passwords, speed isn't critical. Also, you don't have to keep the records / files / data where the plaintext password is encrypted on the server the user uses for authentication. This data can be archived or otherwise moved off regularly, as they aren't required for normal operations (that's what the hash is for).
There is not enough information in the question to give any reasonable answer. Anyway since you disable padding there is a good chance that one of the attacks described in the paper
"Why Textbook ElGamal and RSA Encryption are Insecure" by
D. Boneh, A. Joux, and P. Nguyen is applicable.
That is just a wild guess of course. Your proposal could be susceptible to a number of other attacks.
In terms of answering your specific question, my main concern would have been management of the private key but given it's well and truly not accessible via any computer system breach, you're pretty well covered on that front.
I'd still question the logic of not using hashes though - this sounds like a classic YAGNI. A hashing process is deterministic so even if you decided to migrate systems in the future, so long as you can still use the same algorithm, you'll get the same result. Personally, I'd pick a strong hash algorithm, use a cryptographically strong, unique salt on each account and be done with it.
It seems safe enough in terms of what is online but have you given full consideration to the offline storage. How easy will it be for people within your company to get access to the private key? How would you know if someone within your company had accessed the private key? How easy would it be for the private key to be destroyed (e.g. is the safe fireproof/waterproof, will the printed key become illegible over time etc).
You need to look at things such as split knowledge, dual control, tamper evident envelopes etc. As a minimum I think you need to print out two strings of data which when or'd together create the private key and then have one in your office and one in your customers office,
One serious drawback I've not seen mentioned is the speed.
Symmetric encryption is generally much much faster than asymmetric. That's normally fine because most people account for that in their designs (SSL, for example, only uses asymmetric encryption to share the symmetric key and checking certificates). You're going to be doing asymmetric (slow) for every login, instead of cryptographic hashing (quite fast) or symmetric encryption (pretty snappy). I don't know that it will impact performance, but it could.
As a point of comparison: on my machine an AES symmetric stream cipher encryption (aes-128 cbc) yields up to 188255kB/s. That's a lot of passwords. On the same machine, the peak performance for signatures per second (probably the closest approximation to your intended operation) using DSA with a 512 bit key (no longer used to sign SSL keys) is 8916.2 operations per second. That difference is (roughly) a factor of a thousand assuming the signatures were using MD5 sized checksums. Three orders of magnitude.
This direct comparison is probably not applicable directly to your situation, but my intention was to give you an idea of the comparative algorithmic complexity.
If you have cryptographic algorithms you would prefer to use or compare and you'd like to benchmark them on your system, I suggest the 'openssl speed' command for systems that have openssl builds.
You can also probably mitigate this concern with dedicated hardware designed to accelerate public key cryptographic operations.

Authenticating addons and files

If you ever played the original startcraft and selected an official map made by Blizzard you would notice a little "Blizz" icon next to the map to let you know that it was official and not made by third-party.
I wish to implement a similar system in my application whereby addons and files can be authenticated to let the user know whether or not they came from me or somebody else.
I know very little about security and would appreciate any help in this matter.
Public key cryptography. The client application has a copy of the official author's public signing key, and verifies a signature applied to the addon/file made with the author's private key.
Mac's answer is absolutely correct. To be more specific, the process generally would go as follows:
Signing:
A hash (e.g. SHA-1) is created from the content.
The hash is then signed using the private key, resulting in a signature (e.g. using DSA or RSA algorithm).
The signature is included with the content. If the content changes, the signature will become invalid.
Verification:
Client calculates a hash from the content.
The signature is decrypted with the known public key of the author (i.e. you).
If the hash inside the signature matches the calculated hash from #1 then it's OK. Otherwise the content was modified / isn't really from the author (i.e. you).
Some considerations:
You need to use a key size large enough to deter brute forcing.
These algorithms require a source of random data - both when generating keys and when signing, for example. If this is violated, then often the private key can be trivially revealed.
"Encrypting the hash with the public key" is a simplistic explanation. For example, with RSA - the hash needs to be padded with other data. On verification, the padding has to be checked as well. Otherwise, the signatures may be able to be forged easily. (See: OpenSSL debacle from a few years ago).
The standard advice is to use a proven, off-the-shelf cryptography library written by those with more experience. You need to be able to feed the library the key pair, and data to be signed/verify and say "sign/verify this" with minimal code involved. If you're worrying about the details of padding, or anything like that - you're probably doing it wrong. See: System.Security.Cryptography namespace in Microsoft .NET (very easy to use), or Microsoft CryptoAPI if you're doing standard Windows C/C++ programming. Other cross-platform libs exist too: pick something that works well on your platform.

Cracking a secure key

Another simple question from silly old me.
We keep hearing big numbers being thrown around, for example the key:
234234-234WEF-ER334AS-3535FWF
Would take 20 billion gazillion years for anyone to crack.
Could someone explain how you even know when you have cracked it? If you have permutated a trillion combinations how do you know if you have passed the correct one? Surely you would have to test it on the live system which wouldn't be able to handle that many requests so fast, and a half brained system admin would notice the attack.
I keep seeing competitions to 'crack the key ############', how are you meant to know when you have a solution? You magically come across the english phrase "Ha you wont find me!" or something?
What am I missing?
If you are talking about public key cryptography you can tell when you have cracked the key if you have access to the public key (and you often do - it's typically made public, hence its name). This means you can do the attack offline and you can easily verify that you have found the private key by performing decrypt(encrypt(message)) for a message of your choice and check that you get the correct result back.
You can also often verify the result mathematically. For example with the RSA algorithm if you can factorize the number in the public key then you can prove that you have found the correct private key because the prime factors are used in the generation of the private key.
the key picking process has two steps:
Pick next key (bruteforce or dictionary)
Validate, if failed goto 1
If you are cracking remote application owner can prevent picking by limiting validations in some way. (3 attempts, then pause for example). If you are cracking something local, like encrypted rar file then owner can make picking hard by making validation heavy operation, like encode it several times.
how are you meant to know when you
have a solution?
When the program/algorithm/system/whatever validating the key accepts it.
Depending on what they are trying to crack, the attacker can do the validation him/herself.

How does two party encryption work?

I am able, with pidgin otr for example, capable of communicating with anyone and it is secure.
We haven't exchanged a secret passkey or anything else, the program just sets up the encryption and everyone assures me it is secure.
So what I have is this:
Person1 talking to Person2 (Assuming people really are who they say they are)
Since no info was ever exchanged between person1 and person2, what's to stop a badperson3 from intercepting all the traffic and deciphering all the messages?
I read about PGP, about how each machine has a private key and a public key that is shared between the two computers, but I don't fully get how this can work. It's not like person2 can encode messages using person1's private key, and if it uses the public key, anyone listening can decipher.
I'm a bit confused.
Without getting into technical details, the whole idea of public key cryptography like RSA is that the public key can be used to encrypt data, but cannot be used to decrypt what it just encrypted (without breaking the encryption, of course -- in the case of RSA that normally means factoring the product of two large primes).
There is, of course, still some data exchanged: you still need to get a person's public key before you can encrypt data using that public key. It's also worth noting that public key cryptography is generally a lot slower than symmetric cryptography. That being the case, most protocols that use public key cryptography try to minimize the amount of data encrypted using the public key algorithm. Typically, the sender will pick a random number of the right size to use as a key with a symmetric algorithm, encrypt it with the public-key algorithm, and send it to the receiver. The rest of the data is encrypted with the symmetric algorithm, using that key.
As such, in a typical case you're retrieving a public key, then generating, encrypting, and sending a private key, then sending data encrypted with that private key.
There is a good description written up on wikipedia: http://en.wikipedia.org/wiki/Public-key_cryptography
Messages encoded with someone's private key can only be decoded using the matching public key. Likewise, messages encoded with someone's public key can only be decoded with that person's private key.
If I encode a message with my private key and your public key, then you know that the message is guaranteed to be from me and only you can read it. You would decode it using my public key (to prove that the message came from me) and your private key (proving that only you can read it).
Here are the rules for public key encryption:
A public key may be used to encrypt a message that only the corresponding private key can decrypt.
A private key may be used to encrypt a message that only the corresponding public key can decrypt.
So, it works both ways. The public key being public isn't a problem.
The reason it works is a lot more complicated and involves some interesting math.
Now, OTR doesn't exactly use standard public key encryption. Their algorithms are based on public key encryption but have a small twist in them to allow either party to convincingly deny the conversation ever happened.
Also, OTR isn't secure if you don't actually talk to the person. It's susceptible to a man-in-the-middle attack. This isn't because the encryption can be broken or anything like that. No, a man-in-the-middle attack is where someone interposes themselves between you and the party you want to talk to.
If you are A and you are trying to talk to person B and there's a man in the middle, M, then the attack works like this.
You start talking to B, but unbeknownst to you, you start talking to M who is pretending to be B. When you start talking to M, M initiates a conversation with B pretending to be you. You encrypt all of your stuff to M (who you think is B). M decrypts it, and re-encrypts it to B (who thinks M is you).
If M can always stay in the middle, none of your conversations with B will be secure. If you can ever talk to B without M in the middle, OTR will complain that Bs public key has changed (which is basically because you were really using Ms public key and are just now getting Bs real public key). Of course, OTR might also be complaining because M is trying to interpose (him/her)self and the key you think is the right one really is.
The way to defeat a man-in-the-middle attack is for you and B to talk in some way where you can be certain for other reasons that you're talking to B. Then you can share information about your public key with B, and B can share information about h(is/er) public key with you. You can do this in a coffee shop or over the phone. It doesn't matter if anyone overhears the details, just that you know that it's the person you expect giving them to you.
There is also a fancier way to do this involving secrets that only you and B know. OTR has a mode for asking a question design to elicit a secret in such a way that M cannot provide the proper answer for you, only B can. M will be able to overhear the answer B provides, but will not be able to give it to you.
OTR does exchange information. You have to accept the other person's key and verify it's trusted. Then it all just goes back to normal asymmetric encryption. Which ... boils down to verifying that the one giving you the key and the one you want to talk to are the same person. Nothing magically happening here.
You can encode with a public key, but you have to have the private key to decode.
So if two people have public keys and share these with each other, then they can share information that can only be decoded with the receiver's private key.
Public key encryption works like this: You freely give out your public key. People use your public key to encrypt messages that can only be decrypted with your private key (which you do not share). Your private key acts like "the missing piece" that is used when decrypting the information insofar as it is the only part of the equation that can actually decrypt anything. If someone encrypts something with your public key, you cannot use your public key to decrypt the data afterwards. This is accomplished by using very large prime numbers and some very specific equations.
You have asked two questions:
There are ways to exchange keys securely, e.g. with the Diffie Hellman protocol. It's safe even if an attacker is listening to all the messages.
With public key cryptography each key has a public and a secret component. With the public component you can encrypt or verify a signature, with the secret component you can decrypt or create a signature. There's a lot of number theory to see how this works, but it's worth to learn it.

Is there any benefit to encrypting twice using pgp? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I am asking from a "more secure" perspective. I can imagine a scenario with two required private keys needed for decryption scenarios that may make this an attractive model. I believe it is not adding any additional security other than having to compromise two different private keys. I think that if it was any more secure than encrypting it one million times would be the best way to secure information.
Update a couple of years later: As Rasmus Faber points out 3DES encryption was added to extend the life of DES encryption which had widespread adoption. Encrypting twice using the same key suffers from the Meet in the Middle Attack while encrypting a third time does in fact offer greater security
I understand that it is more secure provided you use different keys. But don't take my word for it. I'm not a crypto-analyst. I don't even play one on TV.
The reason I understand it to be more secure is that you're using extra information for encoding (both multiple keys and an unknown number of keys (unless you publish the fact that there's two)).
Double encryption using the same key makes many codes easier to crack. I've heard this for some codes but I know it to be true for ROT13 :-)
I think the security scheme used by Kerberos is a better one than simple double encryption.
They actually have one master key whose sole purpose is to encrypt the session key and that's all the master key is used for. The session key is what's used to encrypt the real traffic and it has a limited lifetime. This has two advantages.
Evil dudes don't have time to crack the session key since, by the time they've managed to do it, those session keys are no longer in use.
Those same evil dudes don't get an opportunity to crack the master key simply because it's so rarely used (they would need a great many encrypted packets to crack the key).
But, as I said, take that with a big grain of salt. I don't work for the NSA. But then I'd have to tell you that even if I did work for the NSA. Oh, no, you won't crack me that easily, my pretty.
Semi-useful snippet: Kerberos (or Cerberus, depending on your lineage) is the mythological three-headed dog that guards the gates of Hell, a well-chosen mascot for that security protocol. That same dog is called Fluffy in the Harry Potter world (I once had a girlfriend whose massive German Shepherd dog was called Sugar, a similarly misnamed beast).
It is more secure, but not much. The analogy with physical locks is pretty good. By putting two physical locks of the same type on a door, you ensure that a thief that can pick one lock in five minutes now need to spend ten minutes. But you might be much better off by buying a lock that was twice as expensive, which the thief could not pick at all.
In cryptography it works much the same way: in the general case, you cannot ensure that encrypting twice makes it more than twice as hard to break the encryption. So if NSA normally can decrypt your message in five minutes, with double encryption, they need ten minutes. You would probably be much better off by instead doubling the length of the key, which might make them need 100 years to break the encryption.
In a few cases, it makes sense to repeat the encryption - but you need to work the math with the specific algorithm to prove it. For instance, Triple-DES is basically DES repeated three times with three different keys (except that you encrypt-decrypt-encrypt, instead of just encrypting three times). But this also shows how unintuitive this works, because while Triple-DES triples the number of encryptions, it only has double the effective key-length of the DES algorithm.
Encryption with multiple keys is more secure than encryption with a single key, it's common sense.
My vote is that it is not adding any additional security
No.
other than having to compromise two different private keys.
Yes, but you see, if you encrypt something with two ciphers, each using a different key, and one of the ciphers are found to be weak and can be cracked, the second cipher also must be weak for the attacker to recover anything.
Double encryption does not increase the security.
There are two modes of using PGP: asymmetric (public key, with a private key to decrypt), and symmetric (with a passphrase). With either mode the message is encrypted with a session key, which is typically a randomly generated 128-bit number. The session key is then encrypted with the passphrase or with the public key.
There are two ways that the message can be decrypted. One is if the session key can be decryped. This is going to be either a brute-force attack on the passphrase or by an adversary that has your private key. The second way is an algorithmic weakness.
If the adversary can get your private key, then if you have two private keys the adversary will get both.
If the adversary can brute-force your passphrase or catch it with a keystroke logger, then the adversary can almost certainly get both of them.
If there is an algorithmic weakness, then it can be exploited twice.
So although it may seem like double encryption helps, in practice it does not help against any realistic threat.
The answer, like most things, is "it depends". In this case, it depends on how the encryption scheme is implemented.
In general, using double encryption with different keys does improve security, but it does not square the security, due to the meet-in-the-middle attack.
Basically, the attacker doesn't HAVE to break all possible combinations of the first key and the second key (squared security). They can break each key in turn (double security). This can be done in double the time of breaking the single key.
Doubling the time it takes isn't a significant improvement however, as others have noted. If they can break 1 in 10mins, they can break two in 20mins, which is still totally in the realm of possibility. What you really want is to increase security by orders of magnitude so rather than taking 10mins it takes 1000 years. This is done by choosing a better encryption method, not performing the same one twice.
The wikipedia article does a good job of explaining it.
Using brute force to break encryption, the only way they know they got the key, is when the document they've decrypted makes sense. When the document is double encrypted, it still looks like garbage, even if you have the right key - hence you don't know you had the right key.
Is this too obvious or am I missing something?
Its depends on the situation.
For those who gave poor comparison like "locks on doors", think twice before you write something. That example is far from the reality of encryption. Mine is way better =)
When you wrap something, you can wrap it with two diferent things, and it becomes more secure from the outside... true. Imagine that to get to your wrapped sandwitch, instead of unwrap, you cut the wrapping material. Double wrapping now makes no sense, you get it???
WinRAR is VERY secure. There's a case where the goverment couldnt' get into files on a laptop a guy was carrying from Canada. He used WinRAR. They tried to make him give them the password, and he took the 5th. It was on appeal for 2 years, and the courts finally said he didn't have to talk (every court said that during this process). I couldn't believe someone would even think he couldn't take the 5th. The government dropped the case when they lost their appeal, because they still hadn't cracked the files.

Resources