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;
}
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.
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);
}
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("-", "/");
// ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With