Asp.net code not working for implementing rijndael encryption, decryption? - asp.net

I'm reading a book entitled beginning asp.net security from wrox and I'm in this part where it shows a code snippet for using rijndael the problem this example is not included in the downloadable source codes. I decided to seek (professional)help here in the forums.
It would be awesome if you try and test it as well and hopefully give an example(codes) on how I could implement it.
Here is the code:
public class EncryptionRijndael
{
public EncryptionRijndael()
{
//
// TODO: Add constructor logic here
//
}
public static byte[] GenerateRandomBytes(int length)
{
byte[] key = new byte[length];
RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
provider.GetBytes(key);
return key;
}
public void GetKeyAndIVFromPasswordAndSalt(string password, byte[] salt,SymmetricAlgorithm symmetricAlgorithm,ref byte[] key, ref byte[] iv)
{
Rfc2898DeriveBytes rfc2898DeriveBytes =
new Rfc2898DeriveBytes(password, salt);
key =
rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.KeySize / 8);
iv =
rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.BlockSize / 8);
}
public static byte[] Encrypt(byte[] clearText, byte[] key, byte[] iv)
{
// Create an instance of our encyrption algorithm.
RijndaelManaged rijndael = new RijndaelManaged();
// Create an encryptor using our key and IV
ICryptoTransform transform = rijndael.CreateEncryptor(key, iv);
// Create the streams for input and output
MemoryStream outputStream = new MemoryStream();
CryptoStream inputStream = new CryptoStream(
outputStream,
transform,
CryptoStreamMode.Write);
// Feed our data into the crypto stream.
inputStream.Write(clearText, 0, clearText.Length);
// Flush the crypto stream.
inputStream.FlushFinalBlock();
// And finally return our encrypted data.
return outputStream.ToArray();
}
static byte[] Decrypt(byte[] cipherText, byte[] key, byte[] iv)
{
// Create an instance of our encyrption algorithm.
RijndaelManaged rijndael = new RijndaelManaged();
// Create an decryptor using our key and IV ;
ICryptoTransform transform = rijndael.CreateDecryptor(key, iv);
// Create the streams for input and output
MemoryStream outputStream = new MemoryStream();
CryptoStream inputStream = new CryptoStream(outputStream,transform,CryptoStreamMode.Write);
// Feed our data into the crypto stream.
inputStream.Write(cipherText, 0, cipher.Length);
// Flush the crypto stream.
inputStream.FlushFinalBlock();
// And finally return our decrypted data.
return outputStream.ToArray();
}
}
Sir/Ma'am your answers would be of great help. Thank you++
(it would be awesome if you could show me how to call encrypt and decrypt properly)

I have found that it is best to create a class to wrap your credentials and a separate one to do the encryption. Here is what I created... sorry it's in vb instead of c#:
Public Class SymmetricEncryptionCredentials
Private _keyIterations As Integer
Public ReadOnly Property ivString As String
Get
Return Convert.ToBase64String(Me.iv)
End Get
End Property
Public ReadOnly Property saltString() As String
Get
Return Convert.ToBase64String(Me.salt)
End Get
End Property
Public ReadOnly Property keyIterations As Integer
Get
Return _keyIterations
End Get
End Property
Private Property keyPassword() As String
Private Property salt() As Byte()
Private ReadOnly Property key() As Security.Cryptography.Rfc2898DeriveBytes
Get
Return New Security.Cryptography.Rfc2898DeriveBytes(keyPassword, salt, keyIterations)
End Get
End Property
Private Property iv() As Byte()
''' <summary>
''' Creates a set of encryption credentials based on the
''' provided key, ivPassword, and salt string.
''' </summary>
''' <param name="keyPassword">The Secret key used for encryption</param>
''' <param name="salt">The salt string (not secret) from which the salt
''' bytes are derived.</param>
''' <remarks></remarks>
Public Sub New(ByVal keyPassword As String, ByVal salt As String, ByVal iv As String, ByVal keyIterations As Integer)
Me.keyPassword = keyPassword
Me.iv = Convert.FromBase64String(iv)
Me.salt = Convert.FromBase64String(salt)
_keyIterations = keyIterations
End Sub
''' <summary>
''' Creates a new set of encryption credentials based on the
''' provided key, while making a ivPassword and salt.
''' </summary>
''' <param name="keyPassword">The Secret key used for encryption</param>
''' <remarks>Creates a new set of encryption credentials based on the
''' provided key password, while making a ivPassword and salt.</remarks>
Public Sub New(ByVal keyPassword As String, ByVal keyIterations As Integer)
Me.keyPassword = keyPassword
Me.iv = Passwords.GetRandomPassword(16, 16)
Me.salt = Passwords.GetRandomPassword()
_keyIterations = keyIterations
End Sub
''' <summary>
''' Creates a new set of encryption credentials based on the
''' provided key, while making a ivPassword and salt. Uses
''' default PBKDF iteration count.
''' </summary>
''' <param name="keyPassword">The Secret key used for encryption</param>
''' <remarks>Creates a new set of encryption credentials based on the
''' provided key password, while making a ivPassword and salt.</remarks>
Public Sub New(ByVal keyPassword As String)
Me.New(keyPassword, AppSettings("defaultKeyPBKDFIterations"))
End Sub
''' <summary>
''' Gets an AES Encryptor with key derived from RFC2898.
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function GetAESEncryptor() As Security.Cryptography.ICryptoTransform
Dim aes As New Security.Cryptography.AesManaged
aes.KeySize = 256
aes.Key = Me.key.GetBytes(aes.KeySize / 8)
aes.IV = Me.iv
Return aes.CreateEncryptor()
End Function
Public Function GetAESDecryptor() As Security.Cryptography.ICryptoTransform
Dim aes As New Security.Cryptography.AesManaged
aes.KeySize = 256
aes.Key = Me.key.GetBytes(aes.KeySize / 8)
aes.IV = Me.iv
Return aes.CreateDecryptor
End Function
End Class
Public Class SymmetricEncryption
Public Shared Function Encrypt(ByVal unencryptedValue As String, creds As SymmetricEncryptionCredentials) As String
Dim inBytes() As Byte = System.Text.Encoding.UTF8.GetBytes(unencryptedValue)
Dim outBytes() As Byte
Using outStream As New IO.MemoryStream()
Using encryptStream As New System.Security.Cryptography.CryptoStream(outStream, creds.GetAESEncryptor, Security.Cryptography.CryptoStreamMode.Write)
encryptStream.Write(inBytes, 0, inBytes.Length)
encryptStream.FlushFinalBlock()
outBytes = outStream.ToArray
encryptStream.Close()
End Using
outStream.Close()
End Using
Dim outString As String = Convert.ToBase64String(outBytes)
Return outString
End Function
Public Shared Function Decrypt(ByVal encryptedValue As String, creds As SymmetricEncryptionCredentials) As String
Dim inBytes() As Byte = Convert.FromBase64String(encryptedValue)
Dim outString As String
Using outStream As New IO.MemoryStream
Using decryptionStream As New System.Security.Cryptography.CryptoStream(outStream, creds.GetAESDecryptor, Security.Cryptography.CryptoStreamMode.Write)
decryptionStream.Write(inBytes, 0, inBytes.Length)
decryptionStream.FlushFinalBlock()
Dim outBytes() As Byte = outStream.ToArray
outString = System.Text.Encoding.UTF8.GetString(outBytes)
decryptionStream.Close()
End Using
outStream.Close()
End Using
Return outString
End Function
End Class
Public Class Passwords
Public Shared Function GetRandomPassword(minLength As Integer, maxlength As Integer) As Byte()
' *** 1. Get how long the password will be
Dim rand As New Random
Dim passLength As Integer = rand.Next(minLength, maxlength)
' *** 2. Create an array of Bytes to hold the
' random numbers used to make the string's chars
Dim passBytes(passLength - 1) As Byte
' *** 3. Fill the array with random bytes.
Dim rng As New Security.Cryptography.RNGCryptoServiceProvider
rng.GetBytes(passBytes)
Return passBytes
End Function
Public Shared Function GetRandomPassword() As Byte()
Return GetRandomPassword(12, 32)
End Function
End Class

Related

Encryption (TripleDES) between Universal App and ASP.Net Web Service

I am totally lost. I build a Universal App (VB.net) which is consuming a web service on my (Azure Website Vb.net).
My Universal APP (UA) is sending userdata (Username an EmployeeNR) to a webservice and the Webservice is checking that data.
With TripleDES I encrypted the EmployeeNr and Username in the Universal and send it to the WebService. Now i am struggling how to decrypt the TripleDES on my WebService.
In the Universal App I work with Windows.Security.Cryptography which is not available on the Webservice site (asp.net).
I can only use System.Security.Cryptography.
I can encrypt and decrypt on Windows App site.
I also can encrpyt and decrypt on the Web Service site.
But if I pass an encrypted String form Win App to Web Service. Decryption is not working.
Problem is: On both sides, I use the same STRING, same Key and TripleDES encryption, but the result is different.
MY Encryption side - Windows Universal APP
Function myencrptor(ByVal Plaintext As String, ByVal mykey As String) As String
Dim crypt As SymmetricKeyAlgorithmProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.TripleDesCbcPkcs7)
Dim PlainTextbuffer As IBuffer = CryptographicBuffer.ConvertStringToBinary(Plaintext, BinaryStringEncoding.Utf8)
Dim mykeybuffer As IBuffer = CryptographicBuffer.ConvertStringToBinary(mykey, BinaryStringEncoding.Utf8)
Dim magickey As CryptographicKey = crypt.CreateSymmetricKey(mykeybuffer)
Dim signed As IBuffer = CryptographicEngine.Encrypt(magickey, PlainTextbuffer, Nothing)
Dim verschlüsselt As String = CryptographicBuffer.EncodeToBase64String(signed)
Return verschlüsselt
End Function
My Server Side
Partial Class regal_appsync_Default
Inherits System.Web.UI.Page
Public NotInheritable Class Simple3Des
Private xTripleDES As New TripleDESCryptoServiceProvider
Sub New(ByVal key As String)
' Initialize the crypto provider.
xTripleDES.Key = TruncateHash(key, xTripleDES.KeySize \ 8)
xTripleDES.IV = TruncateHash("", xTripleDES.BlockSize \ 8)
End Sub
Private Function TruncateHash(ByVal key As String, ByVal length As Integer) As Byte()
Dim sha1 As New SHA1CryptoServiceProvider
' Hash the key.
Dim keyBytes() As Byte = System.Text.Encoding.UTF8.GetBytes(key)
Dim hash() As Byte = sha1.ComputeHash(keyBytes)
' Truncate or pad the hash.
ReDim Preserve hash(length - 1)
Return hash
End Function
Public Function EncryptData(ByVal plaintext As String) As String
' Convert the plaintext string to a byte array.
Dim plaintextBytes() As Byte = System.Text.Encoding.UTF8.GetBytes(plaintext)
' Create the stream.
Dim ms As New System.IO.MemoryStream
' Create the encoder to write to the stream.
Dim encStream As New CryptoStream(ms,
xTripleDES.CreateEncryptor(),
System.Security.Cryptography.CryptoStreamMode.Write)
' Use the crypto stream to write the byte array to the stream.
encStream.Write(plaintextBytes, 0, plaintextBytes.Length)
encStream.FlushFinalBlock()
' Convert the encrypted stream to a printable string.
Return Convert.ToBase64String(ms.ToArray)
End Function
Public Function DecryptData(ByVal encryptedtext As String) As String
' Convert the encrypted text string to a byte array.
Dim encryptedBytes() As Byte = Convert.FromBase64String(encryptedtext)
' Create the stream.
Dim ms As New System.IO.MemoryStream
' Create the decoder to write to the stream.
Dim decStream As New CryptoStream(ms, xTripleDES.CreateDecryptor(), System.Security.Cryptography.CryptoStreamMode.Write)
' Use the crypto stream to write the byte array to the stream.
decStream.Write(encryptedBytes, 0, encryptedBytes.Length)
decStream.FlushFinalBlock()
' Convert the plaintext stream to a string.
Return System.Text.Encoding.UTF8.GetString(ms.ToArray)
End Function
End Class
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Lbl1.Text = myEncoding(Txt1.Text)
End Sub
Protected Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Lbl1.Text = myDecoding(Lbl1.Text)
End Sub
Function myEncoding(ByVal plainText As String) As String
Dim wrapper As New Simple3Des("012345678901234567891234")
Dim cipherText As String = wrapper.EncryptData(plainText)
Return cipherText
End Function
Function myDecoding(ByVal cipherText As String) As String
' DecryptData throws if the wrong password is used.
Dim wrapper As New Simple3Des("012345678901234567891234")
Try
Dim plainText As String = wrapper.DecryptData(cipherText)
Return plainText
Catch ex As System.Security.Cryptography.CryptographicException
Return "problem"
End Try
End Function
End Class
looking forward to any helpful tips!
best wishes
hendrik

Query string module encryption not working

I did the query string encryption of my project using the example provided here.
When I run the project locally it works fine:
But when I publish it to my server, the encryption simply doesn't work.
The application on the server is running on Windows Server 2008 R2 and IIS 7.
Maybe there is something I must change on IIS? I have no clue.
Anyone?
Thank you.
EDIT:
Here is the code of the QueryStringModule class:
Imports System
Imports System.IO
Imports System.Web
Imports System.Text
Imports System.Security.Cryptography
''' <summary>
''' Summary description for QueryStringModule
''' </summary>
Public Class QueryStringModule
Implements IHttpModule
#Region "IHttpModule Members"
Sub Init(context As HttpApplication) Implements System.Web.IHttpModule.Init
AddHandler context.BeginRequest, AddressOf context_BeginRequest
End Sub
Sub Dispose() Implements System.Web.IHttpModule.Dispose
' Nothing to dispose
End Sub
#End Region
Private Const PARAMETER_NAME As String = "enc="
Private Const ENCRYPTION_KEY As String = "key"
Private Sub context_BeginRequest(sender As Object, e As EventArgs)
Dim context As HttpContext = HttpContext.Current
If context.Request.Url.OriginalString.Contains("aspx") AndAlso context.Request.RawUrl.Contains("?") Then
Dim query As String = ExtractQuery(context.Request.RawUrl)
Dim path As String = GetVirtualPath()
If query.StartsWith(PARAMETER_NAME, StringComparison.OrdinalIgnoreCase) Then
' Decrypts the query string and rewrites the path.
Dim rawQuery As String = query.Replace(PARAMETER_NAME, String.Empty)
Dim decryptedQuery As String = Decrypt(rawQuery)
context.RewritePath(path, String.Empty, decryptedQuery)
ElseIf context.Request.HttpMethod = "GET" Then
' Encrypt the query string and redirects to the encrypted URL.
' Remove if you don't want all query strings to be encrypted automatically.
Dim encryptedQuery As String = Encrypt(query)
context.Response.Redirect(path + encryptedQuery)
End If
End If
End Sub
''' <summary>
''' Parses the current URL and extracts the virtual path without query string.
''' </summary>
''' <returns>The virtual path of the current URL.</returns>
Private Shared Function GetVirtualPath() As String
Dim path As String = HttpContext.Current.Request.RawUrl
path = path.Substring(0, path.IndexOf("?"))
path = path.Substring(path.LastIndexOf("/") + 1)
Return path
End Function
''' <summary>
''' Parses a URL and returns the query string.
''' </summary>
''' <param name="url">The URL to parse.</param>
''' <returns>The query string without the question mark.</returns>
Private Shared Function ExtractQuery(url As String) As String
Dim index As Integer = url.IndexOf("?") + 1
Return url.Substring(index)
End Function
#Region "Encryption/decryption"
''' <summary>
''' The salt value used to strengthen the encryption.
''' </summary>
Private Shared ReadOnly SALT As Byte() = Encoding.ASCII.GetBytes(ENCRYPTION_KEY.Length.ToString())
''' <summary>
''' Encrypts any string using the Rijndael algorithm.
''' </summary>
''' <param name="inputText">The string to encrypt.</param>
''' <returns>A Base64 encrypted string.</returns>
Public Shared Function Encrypt(inputText As String) As String
Dim rijndaelCipher As New RijndaelManaged()
Dim plainText As Byte() = Encoding.Unicode.GetBytes(inputText)
Dim SecretKey As New PasswordDeriveBytes(ENCRYPTION_KEY, SALT)
Using encryptor As ICryptoTransform = rijndaelCipher.CreateEncryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16))
Using memoryStream As New MemoryStream()
Using cryptoStream As New CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)
cryptoStream.Write(plainText, 0, plainText.Length)
cryptoStream.FlushFinalBlock()
Return "?" + PARAMETER_NAME + Convert.ToBase64String(memoryStream.ToArray())
End Using
End Using
End Using
End Function
''' <summary>
''' Decrypts a previously encrypted string.
''' </summary>
''' <param name="inputText">The encrypted string to decrypt.</param>
''' <returns>A decrypted string.</returns>
Public Shared Function Decrypt(inputText As String) As String
Dim rijndaelCipher As New RijndaelManaged()
Dim encryptedData As Byte() = Convert.FromBase64String(inputText)
Dim secretKey As New PasswordDeriveBytes(ENCRYPTION_KEY, SALT)
Using decryptor As ICryptoTransform = rijndaelCipher.CreateDecryptor(secretKey.GetBytes(32), secretKey.GetBytes(16))
Using memoryStream As New MemoryStream(encryptedData)
Using cryptoStream As New CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)
Dim plainText As Byte() = New Byte(encryptedData.Length - 1) {}
Dim decryptedCount As Integer = cryptoStream.Read(plainText, 0, plainText.Length)
Return Encoding.Unicode.GetString(plainText, 0, decryptedCount)
End Using
End Using
End Using
End Function
#End Region
End Class
Yes it's a ISS configuration issue.
The web.config for ISS 5 or 6 should contain a <httpModules> tag as is described on madskristensen.net.
<system.web>
<httpModules>
<add type="QueryStringModule" name="QueryStringModule"/>
</httpModules>
</system.web>
If your web application is running on IIS 7 then the setting should be in:
<system.webServer>
<modules>
<add type="QueryStringModule" name="QueryStringModule"/>
</modules>
</system.webServer>
This solution is also described here.
I just found a solution:
1-Open IIS on the server;
2-Select the desired web site;
3-Select Modules;
4-Right click then "Add managed modules";
5-Give a name to it and then find the module you you want to add in the dropdownlist;
6-Reset IIS.

Set password for active directory lightweight directory services (ad lds) on .net 2.0

I am trying to create a new user and set their password in AD LDS using asp.net vb. I'm binding to an instance of a directory entry, which is working fine. And I can add a user without a problem. The problem is that I can't seem to set the password when I add the user. Is this the right way to set the password?
Dim objADAM As DirectoryEntry = BindToInstance()
Dim objUser As DirectoryEntry = objADAM.Children.Add("CN=Jimmy", "User")
objUser.Properties("sn").Value = "lloyd"
objUser.Properties("givenName").Value = "Jimmy Smith"
objUser.Properties("userpassword").Value = "THEPASSWORD"
objUser.CommitChanges()
This is the error that I get :
System.DirectoryServices.DirectoryServicesCOMException (0x80072020): An operations error occurred. (Exception from HRESULT: 0x80072020) at System.DirectoryServices.DirectoryEntry.CommitChanges()
I've also tried this :
Dim objADAM As DirectoryEntry = BindToInstance()
Dim objUser As DirectoryEntry = objADAM.Children.Add("CN=Jimmy", "User")
objUser.Properties("sn").Value = "lloyd"
objUser.Properties("givenName").Value = "Jimmy Smith"
objUser.CommitChanges()
objUser.Invoke("SetPassword", New Object() {"123456789A$#"})
objUser.CommitChanges()
Which gave me this error :
System.Reflection.TargetInvocationException:
Exception has been thrown by the
target of an invocation. --->
System.Runtime.InteropServices.COMException
(0x8000500D): The directory property
cannot be found in the cache. --- End
of inner exception stack trace --- at
System.DirectoryServices.DirectoryEntry.Invoke(String
methodName, Object[] args)
My coworker found a solution. You call CreateUserSetPassword to create the user and setup the password in one function call.
FYI, if the set password fails, the user will already be set up, so you'll need to either delete the user or just call the SetPassword function again.
Class variables
Private Uri As String
' { get; set; }
Private OuUri As String
' { get; set;}
Private UserUri As String
' { get; set; }
'You will want to set these two parameters somewhere in .config and pass to
'or otherwise make available to this process
Private userid As String = "danny123"
Private pwd As String = "pa$$word1"
New function
Public Sub New(ByVal uri__1 As String, ByVal ou As String)
Uri = uri__1
OuUri = "LDAP://" & uri__1 & "/" & ou
UserUri = "LDAP://" & uri__1 & "/CN={0}," & ou
End Sub
CreateUserSetPassword
''' <summary>
''' Creates new user and sets password
''' </summary>
''' <param name="userName"></param>
''' <param name="password"></param>
Public Function CreateUserSetPassword(ByVal userName As String, ByVal password As String) As String
Dim oGUID As String = String.Empty
oGUID = CreateUserAccount(userName, password)
If oGUID = String.Empty Then
oGUID = SetPassword(userName, password)
If oGUID = String.Empty Then
oGUID = EnableUser(userName)
End If
End If
Return oGUID
End Function
CreateUserAccount
''' <summary>
''' Create user in the AD-LDS
''' </summary>
''' <param name="userName"></param>
''' <param name="userPassword"></param>
''' <returns></returns>
Public Function CreateUserAccount(ByVal userName As String, ByVal userPassword As String) As String
Dim oGUID As String = String.Empty
Try
Dim connectionPrefix As String = OuUri
Using dirEntry As New DirectoryEntry(connectionPrefix, userid, pwd)
Dim newUser As DirectoryEntry = dirEntry.Children.Add("CN=" & userName, "user")
newUser.Properties("userPrincipalName").Value = userName
newUser.CommitChanges()
newUser.Close()
End Using
'catch (System.DirectoryServices.DirectoryServicesCOMException E)
Catch E As Exception
oGUID = E.Message
End Try
Return oGUID
End Function
SetPassword
''' <summary>
''' Set password for the user in AD-LDS
''' </summary>
''' <param name="user"></param>
''' <param name="password"></param>
Public Function SetPassword(ByVal user As String, ByVal password As String) As String
Dim oGUID As String = String.Empty
Const adsOptionPasswordPortnumber As Long = 6
Const adsOptionPasswordMethod As Long = 7
Const adsPasswordEncodeClear As Integer = 1
Const intPort As Integer = 50000
Dim objUser As DirectoryEntry
' User object.
' Set authentication flags.
Dim AuthTypes As AuthenticationTypes = AuthenticationTypes.Signing Or AuthenticationTypes.Sealing Or AuthenticationTypes.Secure
' Bind to user object using LDAP port.
Try
objUser = New DirectoryEntry(String.Format(UserUri, user), userid, pwd, AuthTypes)
'Get object using GetDirectoryEntry
'objUser = GetDirectoryEntry(user);
objUser.RefreshCache()
objUser.Invoke("SetOption", New Object() {adsOptionPasswordPortnumber, intPort})
objUser.Invoke("SetOption", New Object() {adsOptionPasswordMethod, adsPasswordEncodeClear})
objUser.Invoke("SetPassword", New Object() {password})
objUser.CommitChanges()
Catch e As Exception
oGUID = e.Message & vbLf & vbCr & Convert.ToString(e.InnerException)
End Try
Return oGUID
End Function

Error: Expecting state. Could not Deserialize JSON Object

We are trying to consume WCF service which returns employee details in JSON Format.
like:
{
"d": [{
"__type": "Employee:#",
"BigThumbNailURI": null,
"ID": 1,
"Name": "E1"
}, {
"__type": "Employee:#",
"BigThumbNailURI": null,
"ID": 2,
"Name": "E1"
}]
}
From VB.net code behind when I am trying to deserialize it it's stating that
"Expecting state 'Element'.. Encountered 'Text' with name '', namespace ''."
Deserialization code snippet:
Dim serializer = New DataContractJsonSerializer(GetType(List(Of Employee)))
Dim memoryStream = New MemoryStream()
Dim s = msg.Content.ReadAsString()
serializer.WriteObject(memoryStream, s)
memoryStream.Position = 0
' Code for Deserilization
Dim obj As List(Of Employee) = serializer.ReadObject(memoryStream)
memoryStream.Close()
'Employee Class
<DataContract()> _
Public Class Employee
Private _Name As String
<DataMember()> _
Public Property Name() As String
Get
Return _Name
End Get
Set(ByVal value As String)
_Name = value
End Set
End Property
Private _id As Integer
<DataMember()> _
Public Property ID() As Integer
Get
Return _id
End Get
Set(ByVal value As Integer)
_id = value
End Set
End Property
End Class
Has anyone encountered this problem?
Found resolution. To solve this issue, do not use that MemoryStream anymore.
Pass the JSON object to deserializer directly as follows:
Dim serializer = New DataContractJsonSerializer(GetType(List(Of Employee)))
' Code for Deserilization
Dim obj As List(Of Employee) = serializer.ReadObject(msg.Content.ReadAsString())
memoryStream.Close()
Here are two generic methods for serializing and deserializing.
/// <summary>
/// Serializes the specified object into json notation.
/// </summary>
/// <typeparam name="T">Type of the object to be serialized.</typeparam>
/// <param name="obj">The object to be serialized.</param>
/// <returns>The serialized object as a json string.</returns>
public static string Serialize<T>(T obj)
{
Utils.ArgumentValidation.EnsureNotNull(obj, "obj");
string retVal;
using (MemoryStream ms = new MemoryStream())
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
serializer.WriteObject(ms, obj);
retVal = Encoding.UTF8.GetString(ms.ToArray());
}
return retVal;
}
/// <summary>
/// Deserializes the specified json string into object of type T.
/// </summary>
/// <typeparam name="T">Type of the object to be returned.</typeparam>
/// <param name="json">The json string of the object.</param>
/// <returns>The deserialized object from the json string.</returns>
public static T Deserialize<T>(string json)
{
Utils.ArgumentValidation.EnsureNotNull(json, "json");
T obj = Activator.CreateInstance<T>();
using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
obj = (T)serializer.ReadObject(ms);
}
return obj;
}
You'll need these namespaces
using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;

How can I encrypt a querystring in asp.net?

I need to encrypt and decrypt a querystring in ASP.NET.
The querystring might look something like this:
http://www.mysite.com/report.aspx?id=12345&year=2008
How do I go about encrypting the entire querystring so that it looks something like the following?
http://www.mysite.com/report.aspx?crypt=asldjfaf32as98df8a
And then, of course, how to I decrypt it? What's the best encryption to use for something like this? TripleDES?
Here is a way to do it in VB From: http://www.devcity.net/Articles/47/1/encrypt_querystring.aspx
Wrapper for the encryption code: Pass your querystring parameters into this, and change the key!!!
Private _key as string = "!#$a54?3"
Public Function encryptQueryString(ByVal strQueryString As String) As String
Dim oES As New ExtractAndSerialize.Encryption64()
Return oES.Encrypt(strQueryString, _key)
End Function
Public Function decryptQueryString(ByVal strQueryString As String) As String
Dim oES As New ExtractAndSerialize.Encryption64()
Return oES.Decrypt(strQueryString, _key)
End Function
Encryption Code:
Imports System
Imports System.IO
Imports System.Xml
Imports System.Text
Imports System.Security.Cryptography
Public Class Encryption64
Private key() As Byte = {}
Private IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}
Public Function Decrypt(ByVal stringToDecrypt As String, _
ByVal sEncryptionKey As String) As String
Dim inputByteArray(stringToDecrypt.Length) As Byte
Try
key = System.Text.Encoding.UTF8.GetBytes(Left(sEncryptionKey, 8))
Dim des As New DESCryptoServiceProvider()
inputByteArray = Convert.FromBase64String(stringToDecrypt)
Dim ms As New MemoryStream()
Dim cs As New CryptoStream(ms, des.CreateDecryptor(key, IV), _
CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
Return encoding.GetString(ms.ToArray())
Catch e As Exception
Return e.Message
End Try
End Function
Public Function Encrypt(ByVal stringToEncrypt As String, _
ByVal SEncryptionKey As String) As String
Try
key = System.Text.Encoding.UTF8.GetBytes(Left(SEncryptionKey, 8))
Dim des As New DESCryptoServiceProvider()
Dim inputByteArray() As Byte = Encoding.UTF8.GetBytes( _
stringToEncrypt)
Dim ms As New MemoryStream()
Dim cs As New CryptoStream(ms, des.CreateEncryptor(key, IV), _
CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Return Convert.ToBase64String(ms.ToArray())
Catch e As Exception
Return e.Message
End Try
End Function
End Class
Encryption in C# using AES encryption-
protected void Submit(object sender, EventArgs e)
{
string name = HttpUtility.UrlEncode(Encrypt(txtName.Text.Trim()));
string technology = HttpUtility.UrlEncode(Encrypt(ddlTechnology.SelectedItem.Value));
Response.Redirect(string.Format("~/CS2.aspx?name={0}&technology={1}", name, technology));
}
AES Algorithm Encryption and Decryption functions
private string Encrypt(string clearText)
{
string EncryptionKey = "hyddhrii%2moi43Hd5%%";
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
private string Decrypt(string cipherText)
{
string EncryptionKey = "hyddhrii%2moi43Hd5%%";
cipherText = cipherText.Replace(" ", "+");
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}
To Decrypt
lblName.Text = Decrypt(HttpUtility.UrlDecode(Request.QueryString["name"]));
lblTechnology.Text = Decrypt(HttpUtility.UrlDecode(Request.QueryString["technology"]));
I can't give you a turn key solution off the top of my head, but you should avoid TripleDES since it is not as secure as other encryption methods.
If I were doing it, I'd just take the entire URL (domain and querystring) as a URI object, encrypt it with one of the built-in .NET libraries and supply it as the crypt object. When I need to decrypt it, do so, then create a new URI object, which will let you get everything back out of the original querystring.
I was originally going to agree with Joseph Bui on the grounds that it would be more processor efficient to use the POST method instead, web standards dictate that if the request is not changing data on the server, the GET method should be used.
It will be much more code to encrypt the data than to just use POST.
Here's a sort of fancy version of the decrypt function from Brian's example above that you could use if you were only going to use this for the QueryString as it returns a NameValueCollection instead of a string. It also contains a slight correction as Brian's example will break without
stringToDecrypt = stringToDecrypt.Replace(" ", "+")
if there are any 'space' characters in the string to decrypt:
Public Shared Function DecryptQueryString(ByVal stringToDecrypt As String, ByVal encryptionKey As String) As Collections.Specialized.NameValueCollection
Dim inputByteArray(stringToDecrypt.Length) As Byte
Try
Dim key() As Byte = System.Text.Encoding.UTF8.GetBytes(encryptionKey.Substring(0, encryptionKey.Length))
Dim IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}
Dim des As New DESCryptoServiceProvider()
stringToDecrypt = stringToDecrypt.Replace(" ", "+")
inputByteArray = Convert.FromBase64String(stringToDecrypt)
Dim ms As New MemoryStream()
Dim cs As New CryptoStream(ms, des.CreateDecryptor(key, IV), CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
Dim decryptedString As String = encoding.GetString(ms.ToArray())
Dim nameVals() As String = decryptedString.Split(CChar("&"))
Dim queryString As New Collections.Specialized.NameValueCollection(nameVals.Length)
For Each nameValPair As String In nameVals
Dim pair() As String = nameValPair.Split(CChar("="))
queryString.Add(pair(0), pair(1))
Next
Return queryString
Catch e As Exception
Throw New Exception(e.Message)
End Try
End Function
I hope you find this useful!
Why are you trying to encrypt your query string? If the data is sensitive, you should be using SSL. If you are worried about someone looking over the user's shoulder, use form POST instead of GET.
I think it is pretty likely that there is a better solution for your fundamental problem than encrypting the query string.

Resources