5

I need to encrypt and decrypt string values such as Email address and numeric values, but the encrypted string should not have a '/' in it because I am using that in a URL and using '/' for a separator to get some values.

I am currently using following method:

    string passPhrase = "Pas5pr@se";        // can be any string
    string saltValue = "s@1tValue";        // can be any string
    string hashAlgorithm = "SHA1";             // can be "MD5"
    int passwordIterations = 2;                  // can be any number
    string initVector = "@1B2c3D4e5F6g7H8"; // must be 16 bytes
    int keySize = 256;                // can be 192 or 128

    public string Encrypt(string plainText)
    {            
        byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
        byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);         
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
        PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase,saltValueBytes,hashAlgorithm,passwordIterations);
        byte[] keyBytes = password.GetBytes(keySize / 8);
        RijndaelManaged symmetricKey = new RijndaelManaged();
        symmetricKey.Mode = CipherMode.CBC;            
        ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes,initVectorBytes);
        MemoryStream memoryStream = new MemoryStream();
        CryptoStream cryptoStream = new CryptoStream(memoryStream,encryptor,CryptoStreamMode.Write);           
        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);            
        cryptoStream.FlushFinalBlock();
        byte[] cipherTextBytes = memoryStream.ToArray();
        memoryStream.Close();
        cryptoStream.Close();
        string cipherText = Convert.ToBase64String(cipherTextBytes);
        return cipherText;
    }
Chatur
  • 331
  • 1
  • 8
  • 17
  • 1
    What about just replacing that `/` with some other character? – Hans Kesting Feb 27 '13 at 10:10
  • 4
    If you're using it in an URL, wouldn't `UrlEncode` and `UrlDecode` work? – Corak Feb 27 '13 at 10:11
  • Try this links 1. [Link1](http://stackoverflow.com/questions/10168240/encrypting-decrypting-a-string-in-c-sharp) 2. [Link2](http://stackoverflow.com/questions/202011/encrypt-decrypt-string-in-net) Thanks Abiruban – Niventh Feb 27 '13 at 10:13
  • 1
    @AbiRuban the problem in this case is not "how to encrypt/decrypt" - it relates more to representing the encrypted data ***in a url*** - an issue that is not addressed by either of those posts. – Marc Gravell Feb 27 '13 at 10:16

3 Answers3

11

If you're doing it for passing in the URL only, I suggest you generating any encrypted string (no matter if it has / or not), and do:

var sanitized = HttpUtility.UrlEncode(encryptedString);

As you can see, / becomes %2f. Then you can simply do:

var encryptedString = HttpUtility.UrlDecode(sanitized)

and you will get the same string again.

Edit: HttpUtility is in the System.Web assembly.

Oscar Mederos
  • 29,016
  • 22
  • 84
  • 124
4

The encryption itself simply outputs bytes, not characters. So this question is quite unrelated to encryption/decryption. Your actual problem is converting arbitrary bytes into a string that can be used in a url. I recommend using URL safe Base64 over normal Base64 for this.

Those / characters are produced by the Base64 encoding you apply to the ciphertext. Base64 uses ASCII letters and digits (62 total), plus / and + and finally = as padding.

Padding is pretty useless, so I'd strip it.

Then replace / with _ and + with -. This is called URL safe Base64 or base64url. It's described in RFC4648.

public static string Base64UrlEncode(byte[] bytes)
{
    return Convert.ToBase64String(bytes).Replace("=", "").Replace('+', '-').Replace('/', '_');
}

public static byte[] Base64UrlDecode(string s)
{
    s = s.Replace('-', '+').Replace('_', '/');
    string padding = new String('=', 3 - (s.Length + 3) % 4);
    s += padding;
    return Convert.FromBase64String(s);
}
Community
  • 1
  • 1
CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
2

Convert.ToBase64String uses letters, numbers, + and / so you can simply switch the / out for something else that's not a letter, number or +:

Encoding:

// ...
string cipherText = Convert.ToBase64String(cipherTextBytes);
string ctWithoutSlashes = cipherText.Replace("/", "-");

Decoding

string cipherText = ctWithoutSlashes.Replace("-", "/");
// ...
Rawling
  • 49,248
  • 7
  • 89
  • 127