url with token parameter
Hi Nice day for you, Today I thought
before starting my work Let me pass some information to google search content.
I got lot of help from Google search to
do my work easier. Sometime I think myself as selfish not contributing back to the search content. So some bit of
information which might help somebody else.
Okay.. Yesterday my boss asked me, we
need to send a token while we send mails to customers either using Direct CRM
features or third party using extracted list from CRM.
That token should help customer to do
some action in CRM without much authentication issues. Like... they can change
their phone number by clicking a link. They were able to update their marketing
mail preferences with the help of URL and so on...
Indeed there are lot of concerns while
we go to security team with the solution. They are asking about, Validity of
token, Guest authentication, Defense against reply attacks, Defense against
identifier misuse, Defense against Man in middle attack blah blah blah…. :-)
I got confused about the solution as
always. Does it have SAML Token, Web token, Identify provider required, Encryption
required, Counter required, time stamp required.. Lot of thoughts.
At last some solution which worked for me. may be it has some issues, If you are expert on it, please comment. That will help me.
So ... Created a Function which will provide
me a URL If I pass an ID and KeY. Internally it is using encryption
public string DoEncryptedUrl(string PlainText, string Key)
{
String EncryptedString = "";
if (PlainText == null || PlainText.Length <= 0)
throw new ArgumentNullException("CipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
byte[] IV = GenerateRandomNumber(16);
#region Adding Time Stamp
DateTime epochStart = new DateTime(1970, 01, 01, 0, 0, 0, 0, DateTimeKind.Utc);
TimeSpan ts = DateTime.UtcNow - epochStart;
string stamp = Convert.ToUInt64(ts.TotalDays).ToString();
#endregion
//Create
the token text appending Time Stamp
string TempText = "text=" + PlainText + "&stamp=" + stamp;
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = System.Text.ASCIIEncoding.ASCII.GetBytes(Key);
aesAlg.IV = IV;
ICryptoTransform Encryptor = aesAlg.CreateEncryptor(aesAlg.Key,
aesAlg.IV);
using (MemoryStream msEnrypt = new MemoryStream())
{
using (CryptoStream
csEncrypt = new CryptoStream(msEnrypt, Encryptor, CryptoStreamMode.Write))
{
using (StreamWriter
srEecrypt = new StreamWriter(csEncrypt))
{
srEecrypt.Write(TempText);
}
EncryptedString = Convert.ToBase64String(msEnrypt.ToArray());
}
}
}
return "token=" + EncryptedString + "&iv=" + Convert.ToBase64String(IV);
}
This function will provide Encrypted
url token content which can append to the URL while sending email. You can utilize
this function anywhere.
Yes, you can attach this function as part of your work
flow assembly and utilize the value in email templates in CRM. It can be
service utilized by JS. It can be part of ETL program, so that you can
process bulk data …..
Now we have to decrypt it.
Here is the method which I used
public string DoDecryptionUrl(string CipherText, string Key)
{
String Originaltext = "";
if (CipherText == null || CipherText.Length <= 0)
throw new ArgumentNullException("CipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
//Getting
Encrypted Token & iv separte
NameValueCollection QueryString = FillFromString(CipherText);
if (QueryString["iv"] == null || QueryString["iv"].Length <= 0)
throw new ArgumentNullException("IV");
//Reverse
URL ezcape characters
//
QueryString["token"] = QueryString["token"].Replace('+',
'/');
byte[] encrypteddata = Convert.FromBase64String(QueryString["token"]);
byte[] IV = Convert.FromBase64String(QueryString["iv"]);
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = System.Text.ASCIIEncoding.ASCII.GetBytes(Key);
//aesAlg.Key
= System.Text.ASCIIEncoding.ASCII.GetBytes("Informat");
aesAlg.IV = IV; ;
//
aesAlg.Padding = PaddingMode.None;
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key,
aesAlg.IV);
using (MemoryStream msDecrypt = new MemoryStream(encrypteddata))
{
using (CryptoStream
csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader
srDecrypt = new StreamReader(csDecrypt))
{
Originaltext =
srDecrypt.ReadToEnd();
}
}
}
//Getting
Decrypted Token as text and stamp
NameValueCollection OriginaltextCollection = FillFromString(Originaltext);
//Validating
Time Stamp. Token will have 3 days validity
DateTime epochStart = new DateTime(1970, 01, 01, 0, 0, 0, 0, DateTimeKind.Utc);
TimeSpan ts = DateTime.UtcNow - epochStart;
if ((Convert.ToUInt64(OriginaltextCollection["stamp"])) - (Convert.ToUInt64(ts.Days))
> 3)
{
throw new TimeoutException("Token Time Out");
}
else
{
return OriginaltextCollection["text"];
}
}
}
Oh
sorry! I forgot to add an identifier for which entity is encrypted. I think you
can manage it. I will update it later. Time to start my regular work:-)
Happy
Coding!
Look. Send your friends
a note every now and then which can save their time and enjoy a coffee with
somebody :-)
They need to know you
care about them. Share!
Comments