-1

Is there an existing secure implementation to achieve following:


Guid original = Guid.NewGuid();

Guid inverted = MysteryImplementation(original, salt); // salt is some sort of input

Guid shouldBeOriginal = MysteryImplementation(inverted, salt);

Assert.AreEqual(original, shouldBeOriginal, "MysteryImplementation did no work");

EDIT:

As this got down voted (although I'm a bit unsure why), I think more background is needed:

In a place far far away, there is an application in which primary keys are stored as GUIDs. In this application these GUIDs are exposed to web clients.

In my pursuit of improving status quo I had an idea to map these GUIDs with user session data in order mitigate the risk of an accidental/malicious leakage of primary keys. Mapping these GUIDs has the added benefit that it would also allow easier implementation of working-copies for those objects that the GUIDs refer to.

Those were the reasons why I decided to start looking for "secure" way to map GUIDs.

To answer comments:

-Mapping should preserve the global uniqueness when compared to all other GUIDs (I wouldn't want those mapped GUIDs to collide with existing GUIDs).

-"Secure" in this context means that it should be impossible to figure out the original GUIDs without knowing the cipher key (a typical crypto req, which I think translates that the mapped GUIDs should have normalized distribution).

Fdr
  • 3,726
  • 5
  • 27
  • 41
  • http://stackoverflow.com/questions/202011/encrypt-decrypt-string-in-net – Dave Bish Apr 23 '13 at 13:28
  • 2
    "Secure" **against what attack**? It doesn't make any sense to ask about security in the abstract; there's no such thing as secure in the abstract. There's only the ability to mitigate *specific attacks*. – Eric Lippert Apr 23 '13 at 13:49
  • Does `inverted` need to be globally unique when compared to all other GUIDs? Or does it just need to be unique when compared to the encryption of other GUIDs? Since your input (GUIDs) are unique, and the encryption algorithm is 1 to 1, the outputs will be unique (when compared to each other). – mbeckish Apr 23 '13 at 14:33
  • Thanks for the update. Let me propose an attack. Suppose an attacker obtains a pair of the encrypted and unencrypted guids. Is it a requirement that the attacker be *unable to use this information to mount an attack against other guids*? For example, suppose we chose as our cryptosystem "xor every guid with key X". If a pair of encrypted and unencrypted GUIDs is known then X is also known, which means that *every* encrypted guid can be decrypted. Must your security system provide security against this attack? – Eric Lippert Apr 23 '13 at 17:50
  • @EricLippert I was thinking of using user/organization specific keys. In that case I don't see it as a requirement as the user specific keys greatly mitigate the impact of leakage. Although if it is possible to achieve then why not require it. – Fdr Apr 23 '13 at 18:05
  • OK, then another question: do the encrypted GUIDs have to continue to be meaningful forever, or are they limited in time? For example, can we say that the encryption of guid g1 is g2 *for the duration of this session* and after the session ends, g2 is no longer an equivalent to g1? Or must the client be able to cache g2 and always use it to access the table keyed by g1? – Eric Lippert Apr 23 '13 at 18:08
  • @EricLippert There is no that kind of requirement. GUID mapping should be done per session so that cached GUIDs cannot be used for malicous purposes (i.e. gaining access) if leaked. – Fdr Apr 23 '13 at 18:17
  • 4
    OK, so how about when a session starts you make a two-way-dictionary on the server side of the session. The dictionary maps guids to guids. When a guid is going out to the hostile client that has not gone out before in this session, make a fresh tasty new guid, stick the pair in the dictionary, and from that time on, the new guid is the "client-facing-alias" for the in-database guid. When the session ends the dictionary is destroyed. No encryption required, no keys to manage, and the client never sees the internals of your database. No replay attacks possible either. – Eric Lippert Apr 23 '13 at 18:55
  • And bonus, in this scheme every guid is a real guid. – Eric Lippert Apr 23 '13 at 18:56
  • @EricLippert Sounds feasible. I guess I have to abandon this quest of symmetric GUID mapping. Thank you for pointing out my cognitive error of fixating on one idea. Albeit this proposed solution will introduce extra round-trips to a distributed key-value store, it is straightforward to implement. – Fdr Apr 23 '13 at 19:27
  • 1
    Awesome. Basically my attitude is that unless you are *transmitting a secret message between mutually-non-hostile parties*, you're probably using encryption wrong. There's almost always a non-encryption solution. Also, *good on you* for identifying that leaking the details of an internal data structure is a bad practice. Defense in depth! – Eric Lippert Apr 23 '13 at 19:36
  • Thank you for advice. This sure has been an interesting discussion. – Fdr Apr 23 '13 at 20:04

3 Answers3

6

You can easily do this:

Guid original = Guid.NewGuid();
byte[] encrypted = Encrypt(original, key);
Guid decrypted = Decrypt(encrypted, key);

Any symmetric encoding algorithm will do, from ROT13 on up. However, that's not what you asked for. What you asked for is an algorithm that has two properties:

  • The encrypt and decrypt algorithms are exactly the same.
  • The encrypted form of a GUID is also a valid globally unique identifier.

There are plenty of algorithms where the encryption and decryption processes are different but not actually that many where they are exactly the same. The simplest algorithm where encryption and decryption are the same is:

  • Generate a crypto-strength random one-time pad of the same length as the plaintext.
  • XOR the plaintext with the pad to produce the ciphertext.
  • To decrypt, XOR the ciphertext with the pad.

However that algorithm does not necessarily maintain the property that the ciphertext is a valid GUID.

Can you explain why it is that you need the ciphertext to be a valid GUID? The property that a GUID has to have is that it needs to be globally unique; how are you planning on guaranteeing global uniqueness? What stops you from encrypting one GUID that you generated into another GUID that someone else has generated unbeknownst to you?

More generally, can you explain what problem you are trying to solve in the first place? Nine times out of ten that I see someone trying to use cryptography, they're using it for the wrong purpose.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • Thank you for answering - as a fanboy I value it highly :) I edited OP to provide more info as why I started thinking these heretical thoughts. – Fdr Apr 23 '13 at 17:46
3

Yes. Those mystery algorithms are called symmetric ciphers. What you call salt is just the key for the algorithm.

However, it might be a bit harder getting a GUID back from that since encryption algorithms usually operate either on streams or blocks of data and by modifying a GUID you compromise it's GU property.

Joey
  • 344,408
  • 85
  • 689
  • 683
  • So what specific cipher would be suitable for guids? – Fdr Apr 23 '13 at 13:29
  • 1
    GUIDs are just data. Any algorithm would work. Of course, you probably have to convert it into a `byte[]` and back because that's what encryption algorithms work on. Also a word of caution: Naïve use of cryptographic primitives is very easy to get wrong and then the results can vary between useless and dangerous. – Joey Apr 23 '13 at 13:32
  • @Joey I refined question to focus more on the implementation. So I'll accept answer as soon as I get sophisticated symmetric cipher implementation for GUIDs. – Fdr Apr 23 '13 at 13:37
0

any symetric encrytion will do

http://msdn.microsoft.com/en-us/library/as0w18af(v=vs.110).aspx

Nahum
  • 6,959
  • 12
  • 48
  • 69