5

I want to encrypt a string of text securely and have the encrypted string different each time, but always be able to decrypt.

For example, if I encrypt the text "FooBar" at two separate times, I want the encrypted string to look different each time, how would I go about this?

Also, what is the most secure type of encryption that I can use to do this?

I want to use C# with .Net if possible but I am a total encryption noob!

Thanks

JMK
  • 27,273
  • 52
  • 163
  • 280
  • 1
    Just curious -- why do you need it to be different every time? I'm struggling to imagine a use case. – Justin Jan 30 '12 at 12:31
  • I'm assuming it is more secure this way as you couldn't analyse the data and work out what corresponds to an A, what corresponds to a B etc, am I wrong? – JMK Jan 30 '12 at 12:32
  • 1
    `Also, what is the most secure type of encryption that I can use to do this?` -- convert your string into random numbers. Noone is likely to decrypt it ever. (But seriously, +1 to Shai's salt suggestion.) – mah Jan 30 '12 at 12:38
  • If you were only encrypting one letter or word at a time, it would certainly be useful to prevent solving based on frequency. Good encryption schemes, though, have the property that changing a single letter in the original message will change every letter in the encrypted string, so your uniqueness requirement is usually not needed. – Justin Jan 30 '12 at 12:40
  • 2
    @Justin - by having the encrypted value different each time, it's not so easy to notice that two supposedly different encryptions are actually the same. For example, you want to encrypt two users' passwords and they happen to be identical... not varying the encryption reveals the ugly truth. – mah Jan 30 '12 at 12:41
  • I agree with Justin. I think you need encryption mechanisms which resist to known plain-text attacks, ie even with samples of plain-text and their resulting cypher-text an adversary cannot predict cyphertext for new inputs. – UmNyobe Jan 30 '12 at 12:41
  • @mah - Oh, good example. Maybe this isn't as unusual as I imagined. – Justin Jan 30 '12 at 12:45
  • 4
    @JMK: If you don't understand security, which by your own admission you are a "total encryption noob," **hire** an expert! Incorrectly or poorly implemented security is worse than no security. – jason Jan 30 '12 at 12:46
  • The "most secure type of encryption" is the one that *defeats the attack you actually face*. Since you have not stated what that attack is, it is impossible to say which is the "most secure." What's the attack you face? – Eric Lippert Jan 30 '12 at 15:48
  • @EricLippert Fair point, the same attack that everybody who wants to store confidential data faces, people hacking in and stealing our data, rogue insiders, malicious ex employees, legal sanctions for not storing data properly and securely etc etc. – JMK Jan 30 '12 at 16:22
  • @Jason I agree 100% but desperate times! – JMK Jan 30 '12 at 16:23
  • 2
    @JMK: OK, so how does encryption solve any of those problems? **It doesn't.** You have to understand what encryption actually does: **it turns a data management problem into a key management problem.** You still need to solve the key management problem, and you need to solve that problem *without encryption* to avoid an infinite regress of key management problems. How are you going to do that? – Eric Lippert Jan 30 '12 at 16:27
  • @JMK: If you have to deal with all of those threats, you seriously, desperately need an expert to help you. Encryption isn't a one-size fits all solution for all of those problems. – jason Jan 30 '12 at 16:27
  • @EricLippert I don't know! I guess we need to work out what data we need to store and what we don't so we are storing as little sensitive data as possible. Then encrypt that data, then store this data along with the private key on a computer not on the network, then control who knows the passphrase (ensuring this is as few people as possible), while making sure that if somebody gets hit by a truck the business can still function, then control physical access to this computer? Am I on the right track at least? – JMK Jan 30 '12 at 16:34
  • 3
    @JMK: You're getting there! But your sketch shows that you've made a number of assumptions. For example: you say that you need to store the "private key", which implies that you've already decided to use public key crypto. Public key crypto is far more complicated than secret key crypto; do you *need* to publish a public key to solve any problem? If not, then don't. And yes, maintaining *physical* control of assets is extremely important. But you really should be hiring an expert consultant rather than taking advice from strangers on the internet. – Eric Lippert Jan 30 '12 at 16:46

6 Answers6

10

I want to encrypt a string of text securely and have the encrypted string different each time, but always be able to decrypt.

This is an extremely common requirement.

Every answer so far says to use a salt. This is incorrect, as you'd know if you read the first sentence of the wikipedia page on the subject:

"In cryptography, a salt consists of random bits, creating one of the inputs to a one-way function."

Do you want a one-way function? No. You just said that you need to be able to decrypt the string, so it cannot be a one-way function.

What you want is an initialization vector.

"In cryptography, an initialization vector is a fixed-size input to a cryptographic primitive that is typically required to be random or pseudorandom. Randomization is crucial for encryption schemes to achieve semantic security, a property whereby repeated usage of the scheme under the same key does not allow an attacker to infer relationships between segments of the encrypted message."

You wisely point out:

I am a total encryption noob!

Then do not try to do this yourself; you will get it wrong. It is very easy to misuse crypto to build a system that you, the noob, cannot break. Remember, you goal is to make a system that someone who knows a lot more about crypto than you do cannot break.

Also, asking random strangers for help on the internet is a bad way to learn the truth about cryptography. Most people who can answer this question, myself included, are only slightly less noobish than you are. Just take a look at all the awful advice on this page so far. Two answers, for example, suggest to use the current time as a random salt. That is utter craziness; the whole point of a salt is that it is not predictable in advance! Get advice from real experts who know what they are talking about.

My advice: hire an expert to solve your particular problem. To learn about crypto, start with some introductory texts like "Applied Cryptography" so that you understand what problems crypto actually solves and how to use it effectively. Crypto is not magic pixie dust that you sprinkle on data to make it secure; it is only one small part of a whole strategy for securing data against attacks.

svick
  • 236,525
  • 50
  • 385
  • 514
Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 1
    Thanks Eric, I will check out "Applied Cryptography" – JMK Jan 30 '12 at 16:43
  • 2
    Hmm, I wonder how well Applied Crypto will help a Noob. I personally don't think Applied Crypto fits as an introduction to safely apply crypto, its much more mathematical than the title applies, and certainly isn't a book that says: you've got problem X here, now here's solutions A, B and C to choose from. – Maarten Bodewes Jan 30 '12 at 18:19
  • @owlstead: Good point. "Writing Secure Code" might be a more pragmatic introduction to security topics. – Eric Lippert Jan 30 '12 at 18:31
  • "Writing Secure Code" it is then! – JMK Jan 30 '12 at 20:48
4

If you want the encryption to be different, you'll have to use a different salt each time. which means - for each encryption, you'll have to to save it's salt along with it.

Condiser the following approach:

For the 1st time, you could encrypt "FooBar" as is. lets assume it's encryption equals to X.

For the 2nd time, you could encrypt "FooBar" as "FooBar " (note the SPACE), using the SAME salt, which will result in an encryption equals to Y, because of the changes in the string.

This means, you can use the same salt for the decryption procedure, and then remove trailing spaces.

This will result in different encryption, for the same (virtually) string.

Shai
  • 25,159
  • 9
  • 44
  • 67
  • Really nice solution, but It add trouble but do not increase security. 1) You have to remember all the messages you have encrypted and how many times you did 2) Security depends mostly on the encryption function and the encryption key. 3) In security you need to assume everyone know exactly how you are encrypting. – UmNyobe Jan 30 '12 at 12:49
  • 1) You can use a random number of spaces and by that increase your domain (still, depending on the variable you're using to choose the # of spaces, there's a probability that two matching strings will result in the same encryption). 2) He can use the same key for all encryptions. 3) Why? I wouldn't want my customers to know how I'm encrypting their passwords. I wouldn't want _anyone_ to know. makes me feel safer. meh. – Shai Jan 30 '12 at 12:55
  • My point is security must depend only on the encryption function and the key. It make you feel safer but all modern system follow the Kerckhoffs principle — "only secrecy of the key provides security". Otherwise you are adding weaknesses for no good reasons. What if a past employee is angry at you and want to steal your data??? – UmNyobe Jan 30 '12 at 13:02
3

You'll want to use a salt to accomplish what you're asking. Here's an article that should help you get started.

Stephen Gilboy
  • 5,572
  • 2
  • 30
  • 36
3

A salt is preferable but it is sufficient to add a small varying piece of text:

static int count = 0;

string textToSend = ...;
string textToEncryp =  count.ToString("D4") + "." textToSend;  // prefix with "0021."
count++;

// encryp + decrypt

string decryptedText = ...;
string receivedText = decryptedText.Copy(5);  // remove "0021."
H H
  • 263,252
  • 30
  • 330
  • 514
1

For encryption with C#, see: http://msdn.microsoft.com/en-us/library/system.security.cryptography.rsacryptoserviceprovider.aspx .

If you want to store a password, this talks about it. https://stackoverflow.com/a/1054033/939213

Community
  • 1
  • 1
ispiro
  • 26,556
  • 38
  • 136
  • 291
-3

You can use DateTime.Now.Ticks as salt.

beltry
  • 73
  • 1
  • 3
  • 3
    Using the current time is a poor choice for a salt. Remember, the purpose of a salt is typically to increase the computational burden on an attacker who wishes to precompute the hashes of common passwords. **If the salt can be predicted easily then you have not increased the attacker's burden**. If the attackers know roughly when the salt was generated -- and why shouldn't they know that? They know that no one was generating passwords *in the future* or *fifty years in the past* -- then they can narrow down the number of salts significantly. – Eric Lippert Jan 30 '12 at 17:00