Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple insecure two-way data "obfuscation"?

Tags:

c#

obfuscation

I'm looking for very simple obfuscation (like encrypt and decrypt but not necessarily secure) functionality for some data. It's not mission critical. I need something to keep honest people honest, but something a little stronger than ROT13 or Base64.

I'd prefer something that is already included in the .NET framework 2.0, so I don't have to worry about any external dependencies.

I really don't want to have to mess around with public/private keys, etc. I don't know much about encryption, but I do know enough to know that anything I wrote would be less than worthless... In fact, I'd probably screw up the math and make it trivial to crack.

like image 814
Matt Dawdy Avatar asked Oct 03 '08 05:10

Matt Dawdy


People also ask

What is the difference between data obfuscation and data encryption?

Encryption is used to protect sensitive data, such as payment card information (PCI), personally identifiable information (PII), financial account numbers, and more. Data masking, also called data obfuscation, is a data security technique to hide original data using modified content.

How do you obfuscate a value?

Three of the most common techniques used to obfuscate data are encryption, tokenization, and data masking. Encryption, tokenization, and data masking work in different ways. Encryption and tokenization are reversible in that the original values can be derived from the obfuscated data.

What is obfuscation in cyber security?

Obfuscation refers to the process of concealing something important, valuable, or critical. Cybercriminals use obfuscation to conceal information such as files to be downloaded, sites to be visited, etc.

Does privacy always guarantee integrity?

In short the answer is no. Message Integrity and Secrecy are different, and require different tools.


2 Answers

Other answers here work fine, but AES is a more secure and up-to-date encryption algorithm. This is a class that I obtained a few years ago to perform AES encryption that I have modified over time to be more friendly for web applications (e,g. I've built Encrypt/Decrypt methods that work with URL-friendly string). It also has the methods that work with byte arrays.

NOTE: you should use different values in the Key (32 bytes) and Vector (16 bytes) arrays! You wouldn't want someone to figure out your keys by just assuming that you used this code as-is! All you have to do is change some of the numbers (must be <= 255) in the Key and Vector arrays (I left one invalid value in the Vector array to make sure you do this...). You can use https://www.random.org/bytes/ to generate a new set easily:

  • generate Key
  • generate Vector

Using it is easy: just instantiate the class and then call (usually) EncryptToString(string StringToEncrypt) and DecryptString(string StringToDecrypt) as methods. It couldn't be any easier (or more secure) once you have this class in place.


using System; using System.Data; using System.Security.Cryptography; using System.IO;   public class SimpleAES {     // Change these keys     private byte[] Key = __Replace_Me__({ 123, 217, 19, 11, 24, 26, 85, 45, 114, 184, 27, 162, 37, 112, 222, 209, 241, 24, 175, 144, 173, 53, 196, 29, 24, 26, 17, 218, 131, 236, 53, 209 });      // a hardcoded IV should not be used for production AES-CBC code     // IVs should be unpredictable per ciphertext     private byte[] Vector = __Replace_Me__({ 146, 64, 191, 111, 23, 3, 113, 119, 231, 121, 2521, 112, 79, 32, 114, 156 });       private ICryptoTransform EncryptorTransform, DecryptorTransform;     private System.Text.UTF8Encoding UTFEncoder;      public SimpleAES()     {         //This is our encryption method         RijndaelManaged rm = new RijndaelManaged();          //Create an encryptor and a decryptor using our encryption method, key, and vector.         EncryptorTransform = rm.CreateEncryptor(this.Key, this.Vector);         DecryptorTransform = rm.CreateDecryptor(this.Key, this.Vector);          //Used to translate bytes to text and vice versa         UTFEncoder = new System.Text.UTF8Encoding();     }      /// -------------- Two Utility Methods (not used but may be useful) -----------     /// Generates an encryption key.     static public byte[] GenerateEncryptionKey()     {         //Generate a Key.         RijndaelManaged rm = new RijndaelManaged();         rm.GenerateKey();         return rm.Key;     }      /// Generates a unique encryption vector     static public byte[] GenerateEncryptionVector()     {         //Generate a Vector         RijndaelManaged rm = new RijndaelManaged();         rm.GenerateIV();         return rm.IV;     }       /// ----------- The commonly used methods ------------------------------         /// Encrypt some text and return a string suitable for passing in a URL.     public string EncryptToString(string TextValue)     {         return ByteArrToString(Encrypt(TextValue));     }      /// Encrypt some text and return an encrypted byte array.     public byte[] Encrypt(string TextValue)     {         //Translates our text value into a byte array.         Byte[] bytes = UTFEncoder.GetBytes(TextValue);          //Used to stream the data in and out of the CryptoStream.         MemoryStream memoryStream = new MemoryStream();          /*          * We will have to write the unencrypted bytes to the stream,          * then read the encrypted result back from the stream.          */         #region Write the decrypted value to the encryption stream         CryptoStream cs = new CryptoStream(memoryStream, EncryptorTransform, CryptoStreamMode.Write);         cs.Write(bytes, 0, bytes.Length);         cs.FlushFinalBlock();         #endregion          #region Read encrypted value back out of the stream         memoryStream.Position = 0;         byte[] encrypted = new byte[memoryStream.Length];         memoryStream.Read(encrypted, 0, encrypted.Length);         #endregion          //Clean up.         cs.Close();         memoryStream.Close();          return encrypted;     }      /// The other side: Decryption methods     public string DecryptString(string EncryptedString)     {         return Decrypt(StrToByteArray(EncryptedString));     }      /// Decryption when working with byte arrays.         public string Decrypt(byte[] EncryptedValue)     {         #region Write the encrypted value to the decryption stream         MemoryStream encryptedStream = new MemoryStream();         CryptoStream decryptStream = new CryptoStream(encryptedStream, DecryptorTransform, CryptoStreamMode.Write);         decryptStream.Write(EncryptedValue, 0, EncryptedValue.Length);         decryptStream.FlushFinalBlock();         #endregion          #region Read the decrypted value from the stream.         encryptedStream.Position = 0;         Byte[] decryptedBytes = new Byte[encryptedStream.Length];         encryptedStream.Read(decryptedBytes, 0, decryptedBytes.Length);         encryptedStream.Close();         #endregion         return UTFEncoder.GetString(decryptedBytes);     }      /// Convert a string to a byte array.  NOTE: Normally we'd create a Byte Array from a string using an ASCII encoding (like so).     //      System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();     //      return encoding.GetBytes(str);     // However, this results in character values that cannot be passed in a URL.  So, instead, I just     // lay out all of the byte values in a long string of numbers (three per - must pad numbers less than 100).     public byte[] StrToByteArray(string str)     {         if (str.Length == 0)             throw new Exception("Invalid string value in StrToByteArray");          byte val;         byte[] byteArr = new byte[str.Length / 3];         int i = 0;         int j = 0;         do         {             val = byte.Parse(str.Substring(i, 3));             byteArr[j++] = val;             i += 3;         }         while (i < str.Length);         return byteArr;     }      // Same comment as above.  Normally the conversion would use an ASCII encoding in the other direction:     //      System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();     //      return enc.GetString(byteArr);         public string ByteArrToString(byte[] byteArr)     {         byte val;         string tempStr = "";         for (int i = 0; i <= byteArr.GetUpperBound(0); i++)         {             val = byteArr[i];             if (val < (byte)10)                 tempStr += "00" + val.ToString();             else if (val < (byte)100)                 tempStr += "0" + val.ToString();             else                 tempStr += val.ToString();         }         return tempStr;     } } 
like image 160
Mark Brittingham Avatar answered Oct 17 '22 20:10

Mark Brittingham


I cleaned up SimpleAES (above) for my use. Fixed convoluted encrypt/decrypt methods; separated methods for encoding byte buffers, strings, and URL-friendly strings; made use of existing libraries for URL encoding.

The code is small, simpler, faster and the output is more concise. For instance, [email protected] produces:

SimpleAES: "096114178117140150104121138042115022037019164188092040214235183167012211175176167001017163166152" SimplerAES: "YHKydYyWaHmKKnMWJROkvFwo1uu3pwzTr7CnARGjppg%3d" 

Code:

public class SimplerAES {     private static byte[] key = __Replace_Me__({ 123, 217, 19, 11, 24, 26, 85, 45, 114, 184, 27, 162, 37, 112, 222, 209, 241, 24, 175, 144, 173, 53, 196, 29, 24, 26, 17, 218, 131, 236, 53, 209 });      // a hardcoded IV should not be used for production AES-CBC code     // IVs should be unpredictable per ciphertext     private static byte[] vector = __Replace_Me_({ 146, 64, 191, 111, 23, 3, 113, 119, 231, 121, 221, 112, 79, 32, 114, 156 });      private ICryptoTransform encryptor, decryptor;     private UTF8Encoding encoder;      public SimplerAES()     {         RijndaelManaged rm = new RijndaelManaged();         encryptor = rm.CreateEncryptor(key, vector);         decryptor = rm.CreateDecryptor(key, vector);         encoder = new UTF8Encoding();     }      public string Encrypt(string unencrypted)     {         return Convert.ToBase64String(Encrypt(encoder.GetBytes(unencrypted)));     }      public string Decrypt(string encrypted)     {         return encoder.GetString(Decrypt(Convert.FromBase64String(encrypted)));     }      public byte[] Encrypt(byte[] buffer)     {         return Transform(buffer, encryptor);     }      public byte[] Decrypt(byte[] buffer)     {         return Transform(buffer, decryptor);     }      protected byte[] Transform(byte[] buffer, ICryptoTransform transform)     {         MemoryStream stream = new MemoryStream();         using (CryptoStream cs = new CryptoStream(stream, transform, CryptoStreamMode.Write))         {             cs.Write(buffer, 0, buffer.Length);         }         return stream.ToArray();     } } 
like image 42
Mud Avatar answered Oct 17 '22 20:10

Mud