Exchanging Symmetric Keys - encryption

I have a WinForms client that is sending encrypted data to a web service. The WinForms client creates a Symmetric RijndaelManaged sessionKey and also has a "hard-coded RSA asymmetric public key".
I am using the EncryptedXml class which makes it really easy to package up my data.
The Web Service has both the private and public keys "hardcoded" and can successfully decrypt the SessionKey and then use it to decrypt the actual data I am sending.
This is pretty much handled automatically by the EncryptedData class.
The problem I am having is that on the Web Service end when I want to reply, I can't seem to figure out how to get the SessionKey that was sent over.
Before I do any decrypting on the Web Service side, I can see the encrypted session key, but after I decrypt the XML, it's gone (and therefore I don't have any session keys for my reply).
Any ideas how I can get this unencrypted key?

The reason that you cannot see the session key is that it is automatically decrypted and used. Normally it is considered part of the XML. If you want to get at it, just use
encryptedxml.decryptencryptedkey
And you should be alright. Note that for all the less important security warnings, the code represented here is vulnerable to both man in the middle attacks and to a lesser extend to padding oracle attacks. It should help against most eavesdropping attempts though.
Finally, reusing a session key is considered pretty bad security practice too. If you reuse it, at least consider using an IV, e.g. a counter for each followup message.

Related

Is it secure to pass static value for CryptoJS AES encryption key?

I want to encrypt all my form data with crypto js AES encryption. Is it good to keep the encrypt key value in client side like below.Kindly suggest.
var key = CryptoJS.enc.Utf8.parse("234234234DFDFDF343434DFDFDF")
, iv = CryptoJS.enc.Utf8.parse("234234324234324")
, data = CryptoJS.enc.Utf8.parse(str)
, encryptedData = CryptoJS.AES.encrypt(data, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
No, this is generally not secure.
First of all, you wrongly state your goal. AES encryption is not a goal, it is a means to an end. What you want to do is to keep your form data confidential. The form data is called "the message" in crypto terminology.
If you need to send your message to a server, and then let the server have the decrypted form, then you need transport security. It's best to use TLS for that. Commonly JavaScript doesn't have any means to create a trust relationship with the server (your browser uses it's certificate store with trusted certificates for that). So in that case you cannot rely on JavaScript security.
Sometimes you want to keep your front end from decrypting the messages. In that case you could send a public key such as an RSA public key over the secure channel. Then you could encrypt the form data using RSA and AES (hybrid cryptography). Your backend would then be able to decrypt the messages. This scheme still fails if your front end sends the wrong key though, as the message would be encrypted with a public key from another party. So this assumes that the front end software cannot be easily hacked (or replaced altogether by a different server, subverting the traffic).
Even if you could use a trusted AES key then using CBC for transport mode security will definitely enable plaintext or padding oracle attacks. You're lacking way too much experience with crypto to pull this off. Use TLS, that's hard enough (to secure, using it is relatively easy).

Asymmetric Encryption (Public-Key encryption) I need clarification

I have searched for HOURS on how this works and I just can't get how this can be. The only given definitions are that public keyed encrypted message can only be decrypted by private key. To me, that's just nonsense and I will explain.
A website needs to be downloaded by your browser which also means that Javascript scripts and all the other stuff are accessible to anyone that catches your website if he wishes too. This also means that now, this person knows how you calculate your stuff with your public key making it possible WITHOUT the private key to decrypt it.
I'm just trying to figure out how this works and to me it does not make sens that you CANNOT decrypt an ecrypted text from a public key when you have access to all the calculations made from the side it encrypted.
I mean, when you send a password for example, first, on YOUR end, the browser's end, it encrypts the data to be recieved by the server. By encrypting the data from the browser's end, anyone that took a look on your source code can know how you encrypted it which now can be used to decrypt it. I am creating a new encryption system for our website where the server randomly creates a session key that can only be used by the user with the corresponding session. So only the 2 computers can talk to each other with the same key so if you use the same key on another computer, it just won't work as each key is stored for each session which the key dies after a set amount of time. With what I read, this seams to be called a symetric key system. I want to try and program my own assymetric key system but in all cases when I read, I can only figure out that no matter what happens as an encryption on the client's side, if a malicious person intercepts just before sending the information, he has access to how the encryption worked and therefor, does not need the private key on the server side as he just needs to reverse the process knowing how it was done on the client's side.
I'm starting to think myself as stupid thinking that way.
I'll add a little more information as I think we don't quite catch what I mean. When sending a password, say my name "David" and let's name our user WebUser. We will name our maleficient user BadGuy. So BadGuy hapopens to integrate himself in between WebUser and his browser. BadGuy also recieves ALL javascripts of the webpage permitting him to see how the calculations work before it is sent. WebUser enters his password "David" which is submitted to the javascript encryption system. Right off the bat, BadGuy does not need to decrypot anything as he already caught the password. BUT when the website responds, BadGuy has all the calculations and can use the receieved encrypted data and decrypt it using the decryption calculations he can see in the recieved web pages code.
So the only thing I can understand is that Assymetric keys are used for encryption which technically is decryptable using public known numbers. But in cas of RSA, these 2 numbers are so large that it would take years to figure out the known decryptor. As I can also undersnat is that it is pretty much easier to create the 2 numbers from the private number. But in any case, the encryption process usually ends up with a shared temporary intimate key between the two parties for for faster commuinication and that noone can ever prevent a BagGuy between User and Browser but with todays technocolgies, the real threat is more MiTM attacks where one will sniff the network. In all cases, there is no definate way to communicate 100% of the data in a undecryptable way as at least 50% of it is decryptable i/e data coming from one side or data going to the other side.
Assymetric encryption has two keys, a public and a private key, as you correctly described, so don't feel stupid. Both keys can be used for encryption and decryption, however, if data encrypted by the public key can only be decrypted by the private key and data encrypted by the private key can only be decrypted by the public key.
As a result, in order to be successfully involved in a communication using assymetric encryption you will need to have both a public and a private key.
You share your public key with others, that is, whatever data you receive, it will be encrypted with the public key. You will subsequently be able to decrypt it using your private key, which is your secret. When you send data to the other side of the communication, you encrypt it using your private key and the other side, which has your public key will be able to decrypt it.
Consider the example of versioning. You are involved in a project with some team members. When you pull the commits of others, it is encrypted with your public key, so once it is downloaded at your end, you will be able to decrypt it via your private key. As you work and do your commits, you will push the changes into the repository, encrypted using your private key. The other side of the communication already has your public key and will be able to decrypt it. It is important that you do not share your private key with anyone, so your team-mates will not be able to impersonate you, committing malicious code in your name. You can share your public key with anyone, but it is recommended to share it only with trusted people, like your team-mates, so no one else will be able to decrypt anything encrypted by your private key.
Essentially your public key is a ridiculously large number, which is the result by multiplying two primes (private key). The two primes could be found out by prime factorization, but since the public key is a very very large number, doing the prime factorization would take such a looong time that no one will sit and wait for the time (centuries) while the factorization is being executed and the results are found out.
A session id is a value which identifies a session. If there is a single such value, then it is not an assymetric encryption, as there is no public and private key involved and once someone steals the session ID, as you correctly pointed out, the malicious third person/system can impersonate the actual user and do nasty things. So the problem you have identified actually exists, but this is not a new problem and solutions were implemented. The solution you are looking for is HTTPS. Once your site gets a proper certificate, you will be able to use assymetric encryption safe and sound. Under the hood the server will have the public key of the user's session, while the user will use the private key to encrypt/decrypt and if a middle man intercepts the public key of the session (which is not a session id), the malicious third person will not be able to impersonate the actual user. Read more here:
https://en.wikipedia.org/wiki/Transport_Layer_Security
extending the previous answer
I'm just wandering how an attacker positionned between the user and his browser cannot intercept the connection details when they are clear texte to beggin with and to end with.
The magic here is called DH key exchange.
The symmetric encryption key is derived using Diffie–Hellman key exchange, where the common encryption key is exchanged.
Any "listening" party (your BadGuy) woudn't be able to derive the session key even by sniffing out the whole communications. The server will use its certificate and private key to make sure the client communicates with the legitimate target. This prevents an active "man in the middle" to pose as a false server.
it does not make sens that you CANNOT decrypt an ecrypted text from a public key when you have access to all the calculations made from the side it encrypted.
Asymmetric cryptography is based on so called "trapdoor" funtions. It means it is easy to calculate the function one way (e.g. encrypt data), but very difficult (not feasible) to od it opposite way without some secret value (private key). Indeed sometimes it is difficult to understand it and there are a lot of constraints under the asymmetric encryption is really secure. That's why you would always use some trusted library than do it yourself.
By encrypting the data from the browser's end, anyone that took a look on your source code can know how you encrypted it which now can be used to decrypt it.
Not without the random secret key, which is derived between the client and server during the key exchange (see the first paragraph).
I am creating a new encryption system for our website where the server randomly creates a session key that can only be used by the user with the corresponding session.
It's one of the rules in the field of cryptography - do not design your own crypto!
That's usually a bad idea. Please note the currently used secure channels (SSL, TLS, .. based on RSA, ECC) are designed, reviewed and used by a lot of smart people who know what they are doing, how to mitigate different attack vectors. And IMHO it is still not perfect, but it's the best we have.

Asymmetrical encryption for more that two recipients?

I want to create an application, where multiple people should be able to communicate with each other securely (think of a decentral group chat) - sounds easy, but here is my problem:
As far as I understood, with asymmetrical encryption you have a public key and a private key. Everyone who wants to send a message to someone has to encrypt it with the public key and the recipient can decrypt it with the private key.
But if there are more than two people that should be able to read all messages, I don´t know how this should work...
Either everyone has the public and the private key - which I think is a bad idea - or everyone has to have everybodys public key and has to send a seperate message to each recipient.
Also, I want to make a 100% sure, that the one who sends a message really is who he pretends to be. (so nobody is able to "fake" messages)
Is there an encryption algorithm that solves my problem?
Controlling the extend of the recipient group
In a comment to Richard Schwartz' good answer, you ask
Is it possible with this algorithm to ensure that only one is able to invite others? As far as I understood, everybody could distribute the decrypted session key.
When applying the protocol in a group chat scenario, don't let the term "session key" mislead you. Rather, think of the key for symmetric encryption as a "message key": Each time someone sends a message to the group, they should generate a new random symmetric key, encrypt it with every legit receiver's public key separately and prepend all these cryptograms to the symmetrically encrypted message. This way, each sender decides independently whom they consider a part of the legit recipients group of their own sent messages.
This will give the protocol some more transmission overhead, but this probably won't matter in practice. What could matter is the 'cost' of getting larger amounts of 'good' randomness (entropy) to generate sufficiently unpredictable message keys. So an acceptable optimization might be that, if the group of legit recipients has remained the same, a sender might re-use the session key of their own previously sent message. Never though should they re-purpose a sessions key received from another group member for sending messages of their own.
Off course, even if each sender decides independently whom they consider a legit recipient of their message, you can't keep any legit recipient from compromising messages they received: They can simply forward the messages unencrypted (or encrypted for someone not in the original recipient group) to whomever they want.
Ensuring authenticity
In an edit to your original question, you added
Also, I want to make a 100% sure, that the one who sends a message really is who he pretends to be. (so nobody is able to "fake" messages)
Encryption can't do that, but cryptography has another way to make sure that
the message actually comes from whom claimed to have sent it
the message hasn't been tampered with since
And the way of ensuring these things is signatures, which also are something that public-private-key cryptography enables. Let senders sign their messages with their private key. (Which usually means 'encrypting' a cryptographically secure hash of the message with the private key.) And let receivers verify the signatures (by 'decrypting' the signature with the sender's public key and comparing the result with a hash of the message they computed themselves.)
Don't roll your own anything (except when you should)
Richard's answers advices you to not roll your own (pseudo) random number generator. For anything you plan to use in production, I'd extend this to anything encryption:
Don't invent your own protocols
Don't invent your own cyphers, signatures or hash functions
Don't invent your own way of gathering entropy
Don't roll your own implementations of any of the above, even if invented by others
Instead, use well-established cryptography libraries. These are written and reviewed by experts in both cryptographic theory and in the practices of writing secure software. And while even these libraries are often enough found to have (sometimes embarrassing) security issues, nothing you'll come up with yourself will be nearly as secure as them.
Though, for learning, implementing any or all of the listed stuff (including pseudo random number generators) is great exercise and helps you understand at least some aspects of the underlying cryptography. And this understanding is important, as it's often difficult enough to correctly and securely use the well-established libraries, even when you do have some knowledge of the concepts they reveal through their interfaces.
And of course for innovating within cryptography, inventing new stuff (and getting it scrutinizingly reviewed by the community of experts in the field) is necessary, too. That new stuff just shouldn't be used for anything serious before it has passed that review successfully.
I assume you mean asymmetric encryption, not asynchronous encryption.
In most cases, we don't actually use an asymmetric cipher to encrypt the content of messages. That's because messages can be large, and asymmetric ciphers are slow in comparison to symmetric ciphers. It's also because of the issue you are contending with here: in a multi-party commmunicaiton, you'd like to be able to just send the message once and have everybody be able to read it. So the trick is that we combine asymmetric and symmetric techniques into a protocol that solves the problem.
First, we generate a random symmetric key which we can call the "session key". We're going to distribute this session key to all recipients, but we need to do this securely. Here's where we're actually going to use asymmetric encryption. We encrypt the session key once for each recipient using each of their public keys and an asymmetric cipher (such as RSA), and we send the encrypted session key to each recipeint. We can send it to each recipient separately, or we can just build a structure that looks like this:
"recip1|recip1EncryptedSessionKey|recip2|recip2EncryptesSessionKey..."
and send the whole thing out to all recipients, each of whom will be able to parse it and decrypt their own encrypted copy of the session key. (This is generally how it's done in encrypted email: the list of all encrypted versions of the session key for all recipients is enclosed with the message, and everyone gets the exact same email.)
Once we've securely distributed the session key to all recipients, we can use the session key to encrypt each message just once with a symmetric cipher (such as AES), and send the same encrypted message to all recipients. Since they all have received a copy of the session key, they can all read it and act on it.
Note that as in all things having to do with encryption, it is crucial that the session key is really random. Don't just rely on a plain vanilla random number generator for it, and for heavens sake don't roll your own. Make sure that you use a cryptographically secure pseudorandom number generator.
A real chat system would likely be quite a bit more complicated, probably with a mechanism for re-establishing a new session key periodically, and the details of a secure protocol can be quite intricate. I.e., consider how you would protect against a bad-guy stepping in and fooling everyone into using a session key of his choosing! But the basics are as above.

Change encryption key without exposing plaintext

We're designing a database system to store encrypted strings of information, with encryption and decryption performed client side using public-key cryptography.
If the key was ever changed though, this would necessitate reencrypting all the records client side, which is very impractical.
Is there any way this could be performed server side without exposing either the original (old) decryption key, or the message text?
I guess what I'm after is an associative cipher, something like this:
T( Eo(m) ) = En( Do(Eo(m) ))
where Eo(m) is the cipher text, Eo/Do the old pub/priv key pair, En the new pub key, m the message text and T the magical reencryption function.
Edit: T is calculated clientside and then sent to the server to be used.
You can't retroactively disable the old key anyway. Anyone who has access to the old data and the old key can decrypt the data no matter what you do.
I would suggest simply keeping a ring of keys. Add the new key to the ring and mark it active. Mark the old key expired. Code the client so that if it finds any data that's encrypted with an expired key, it re-encrypts it with the active key. (Or don't. What's needed depends on details of your implementation requirements.)
If desired, after a period of time, you can sweep for any data still encrypted with the old key and re-encrypt it.
You can't eliminate the exposure of the old key anyway, ever -- anyone who can find a backup or copy of data encrypted with the old key can decrypt it if they have the old key. Encryption keys must be protected forever or you get the fiasco that released the Wikileaks diplomatic cables to the public with the names of informants intact.
Think about your security perimeters. If you're worried about the server being compromised, consider building a harder-to-break subsystem which carried out the transcryption. You could do this with a non-network-attached server which was contacted only over a very tightly verified link protocol (over, say, a serial line), or a dedicated hardware security module. However, if you do something like this, you must think about how your keys are protected; if an attacker could steal the transient plaintext from your server, could they also steal the keys protecting it?

AES encryption and the need for Integrity

I did some research on the topic but could not find anything similar to my question. So I hope some of you great guys may help me out.
I want to use AES128 encryption (CFB-Mode) for the networking in my application between two individual clients. The data being exchanged consists only of textual strings of a specific structure, for example, the first bytes allways tell the recipient the kind of message they are receiving, so they can process them. With AES I want to ensure the confidentiality of the message, but now the question of "integrity" arises.
Normaly you would consider using a MAC. But isn't it guaranteed that nobody has altered the message, if the recipient is able to decrypt it correctly, i.e. that the message can be used correctly in his application because of the string's format? Wouldn't altering (even 1 bit) the encrypted message by a third party result in garbage during decryption?
Furthermore let's assume that the application is a multi-party peer-to-peer-game, where two of the players are communicating with each other on a private but AES-encrypted channel. Now the originator of the message is not playing fair and intentionally sending a fraudulent encrypted message to convey an impression that the message has been altered by a random third party (to force a player to quit). Now the recipient would have no chance to determine if the message has been altered or if the sender acts fraudulent, am I right? So Integrity would not be of much use in such a situation and could be neglected?
This may sound like an odd and out of world example. But it's something I recently encountered in a similar application and I am asking myself if there is a solution to the problem or if I got the basic Idea of AES encryption.
As you said, you may detect changes in the format of the plain text message after encryption. But at what level would it go wrong? Do you have something that is large and redundant enough to be tested? What are you going to do if the altered plain text results in some obscure exception somewhere down the line? With CFB (like most modes) an attacker can make sure that only the last part of the message is altered, for instance, and leave the first blocks intact.
And you are worried about cheats as well.
In my opinion, you are much better off using a MAC or HMAC algorithm, or a cipher mode that provides integrity/authentication on top of confidentiality (EAX or GCM for instance). If you are sure nobody else has the symmetric key, an authentication check (such as a MAC) will prove that the data has been signed by the correct key. So no, the user cannot claim that the data has been changed in transport if the authenticity checks succeed.
The next question becomes: can you trust that the symmetric key is only in possession of the other player? For this you might want to use some sort of PKI scheme (using assymetric keys) together with a key exchange mechanism such as DH. But that is for a later, if you decide to go that way.
This is a bit out of my depth, but...
Yes, modifying the encrypted bytes of an AES encrypted message should cause the decryption to fail (this has been my experience with the c# implementation). The client who decrypts will know the message is invalid. EDIT: apparently this is not the case. Looks like you'd need a CRC or hash to verify the message was successfully decrypted. The more serious problem is if the secret AES key is leaked (and in a peer-to-peer environment, the key has to be sent so the receiver can decrypt the message at all). Then a 3rd party can send messages as if they were a legitimate client, and they will be accepted as OK.
Integrity is much harder. I'm not entirely sure how robust you want things to be, but I suspect you want to use public key encryption. This allows you to include a hash of the message (like a signature or MAC) based on the private key to assert the message validity. The receiver uses the public key to verify the hash and thus the original message is OK. The main advantage of public key encryption over symmetric encryption like AES is you don't have to send the private key, only the public key. This makes it much harder to impersonate a client. SSL/TLS uses public key encryption.
In any case, once you have identified a client sending invalid messages, you're in the world of deciding to trust that client or not. That is, is the corruption due to malicious behaviour (what you're worried about)? Or a faulty client implementation (incompetence)? Or a faulty communications link?. And this is where encryption (or at least my knowledge of it) won't help you any more!
Additional regarding integrity:
If you assume no one else has access to your secret key, a CRC, hash, or HMAC would all suffice to ensure you detected changes. Simply take the body of your message, calculate the CRC, hash, whatever and append as a footer. If the hash doesn't match when you decrypt, the message has been altered.
The assumption that the secret key remains secret is quite reasonable. Especially if after some number of messages you generate new ones. SSH and WiFi's WPA both generate new keys periodically.
If you can't assume the secret key is secret, then you need to go to PKI to sign the message. With the AES key in a malicious 3rd party, they'll just generate whatever messages they want with the key.
There may be some mileage in including a sequence number in your message based on a RNG. If you use the same RNG and same seed for both parties, they should be able to predict what sequence number comes next. A 3rd party would need to intercept the original seed, and know how many messages have been sent to send valid but forged messages. (This assumes no messages can ever be lost or dropped.)

Resources