What is the best method for determination ASP.net website clients? - asp.net

I have a asp.net webapp, and runs in private network
I want determine PCs clients for
allow or block the requests
knows who is connected
connects only by special PCs
and more
I used IP Addresses, but anyone can connect when change the IP Address by one that passed in webapp, I want users login by just some PCs . any suggestions ?

LOGIN and PASSWORD going to a database of preferences... The best way to control everything about users (IP control can be bypassed, it´s not a valid control).
UPDATE
New method to pass info in URL:
To get hardware information:
Dim query As New SelectQuery("Win32_bios")
Dim search As New ManagementObjectSearcher(query)
Dim info As ManagementObject
For Each info In search.Get()
BIOS_Msg = info("version").ToString()
Next
Dim searchMainboard As New ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem")
Dim infoMain As ManagementObject
For Each infoMain In searchMainboard.Get()
Computer_Mainboard = infoMain("model").ToString()
Next
To encode Strings:
You may set a KEY and IV as byte array. The key may change according date and even some specific parameters according to the current time.
Add also:
Imports System.Security.Cryptography
Imports System.Text
Friend Function EncryptStringToBytes_Aes(ByVal plainText As String, ByVal Key() As Byte, ByVal IV() As Byte) As String
' Check arguments.
Dim encrypted() As Byte
' Create an AesCryptoServiceProvider object
' with the specified key and IV.
Using aesAlg As New AesCryptoServiceProvider()
aesAlg.Key = Key
aesAlg.IV = IV
Dim encryptor As ICryptoTransform = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV)
' Create the streams used for encryption.
Using msEncrypt As New MemoryStream()
Using csEncrypt As New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)
Using swEncrypt As New StreamWriter(csEncrypt)
'Write all data to the stream.
swEncrypt.Write(plainText)
End Using
encrypted = msEncrypt.ToArray()
End Using
End Using
End Using
' Return the encrypted bytes from the memory stream.
Return Convert.ToBase64(encrypted)
End Function 'EncryptStringToBytes_Aes
To decrypt it:
Friend Function DecryptStringFromBytes_Aes(ByVal cipherText As String, ByVal Key() As Byte, ByVal IV() As Byte) As String
Dim plaintext As String = Nothing
Dim SourceText as Byte() = Convert.FromBase64(CipherText)
' Create an AesCryptoServiceProvider object
' with the specified key and IV.
Using aesAlg As New AesCryptoServiceProvider()
aesAlg.Key = Key
aesAlg.IV = IV
' Create a decrytor to perform the stream transform.
Dim decryptor As ICryptoTransform = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV)
' Create the streams used for decryption.
Using msDecrypt As New MemoryStream(SourceText)
Using csDecrypt As New CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)
Using srDecrypt As New StreamReader(csDecrypt)
' Read the decrypted bytes from the decrypting stream
' and place them in a string.
plaintext = srDecrypt.ReadToEnd()
End Using
End Using
End Using
End Using
Return plaintext
End Function 'DecryptStringFromBytes_Aes
Using these functions, you can:
- Get specific hardware info;
- Encode any string and convert it to Base64
- Pass them in URL using normal convention.
- Receive them in your code-behind and translate them.
I guess that´s the best way to get reliable and specific information of each workstation instead IP-number. You may also work with the Windows Serial Number.

Related

XmlSerializer adding extra characters

I have a method that serializes an object to a string, exhibit a:
Shared Function Serialize(ByVal o As Object) As String
Dim rtnVal As String = ""
Dim x As New System.Xml.Serialization.XmlSerializer(o.GetType())
Using memStream As New MemoryStream
Dim stWriter As New System.IO.StreamWriter(memStream)
x.Serialize(stWriter, o)
rtnVal = Encoding.UTF8.GetString(memStream.GetBuffer())
End Using
Return rtnVal
End Function
Using this serialized data, I'm now inserting it into an XML typed field in my SQL 2012 database. Most of the time, this code works very well, but for a particular object, I'm getting "invalid" characters, namely the error "parsing line 5 character 17 illegal xml character". I took a look at my data, and it's clean, as you can see here:
<?xml version="1.0" encoding="utf-8"?>
<RatingDetails xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<LenderName>dsfg</LenderName>
<VehiclePrice>345</VehiclePrice>
</RatingDetails>
Some snooping led me do the IsXMLChar method - http://msdn.microsoft.com/en-us/library/system.xml.xmlconvert.isxmlchar%28v=vs.100%29.aspx - and using this I was able to loop through each character in my serialized XML string. Low and behold, I DO have invalid data. I have 15 "" character's at the end of my string - WTF!?!
So my questions to you all are, where the heck are the extra "'s coming from, why cant I see them when I inspect the string in my quick watch, and how do I prevent em in the first place.
Yours in ASP.NET, ewitkows
The problem is you are calling MemoryStream.GetBuffer. According to the MSDN article:
Note that the buffer contains allocated bytes which might be unused. For example, if the string "test" is written into the MemoryStream object, the length of the buffer returned from GetBuffer is 256, not 4, with 252 bytes unused. To obtain only the data in the buffer, use the ToArray method; however, ToArray creates a copy of the data in memory.
To fix it, you could call ToArray instead:
Shared Function Serialize(ByVal o As Object) As String
Dim rtnVal As String = ""
Dim x As New System.Xml.Serialization.XmlSerializer(o.GetType())
Using memStream As New MemoryStream
Dim stWriter As New System.IO.StreamWriter(memStream)
x.Serialize(stWriter, o)
rtnVal = Encoding.UTF8.GetString(memStream.ToArray())
End Using
Return rtnVal
End Function
However, that's still not really efficient. If the stream contains a lot of data, it's going to copy the whole thing into a new array for no reason. For peace of mind, I would recommend using the StreamReader to read the MemoryStream rather than trying to decode it yourself (but don't forget to seek back to the beginning of the stream before reading it):
Public Function Serialize(ByVal o As Object) As String
Dim rtnVal As String = ""
Dim x As New System.Xml.Serialization.XmlSerializer(o.GetType())
Using memStream As New MemoryStream
Dim stWriter As New System.IO.StreamWriter(memStream)
x.Serialize(stWriter, o)
Dim reader As New StreamReader(memStream)
memStream.Position = 0 ' Seek to start of stream
rtnVal = reader.ReadToEnd()
End Using
Return rtnVal
End Function

first few characters lost during decryption

I am using AES CBC encryption in VB.Net and decryption is done using AS3Crypto. First few characters (about 16) are missing during decryption and replaced with random characters like below.
05[ÚðÊ\ÃPôôÄ]óbR
Here is my .net code. On AS3Crypto demo page, I use Secret Key > AES > CBC. I tried with different settings for Padding and Key Formats still no luck.
Thanks.
Dim plainText = txt2encrypt.Text.Trim
Dim encrypted() As Byte '
Using aesAlg As New AesCryptoServiceProvider()
aesAlg.Mode = CipherMode.CBC
' Create a decrytor to perform the stream transform.
Dim encryptor As ICryptoTransform = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV)
' Create the streams used for encryption.
Using msEncrypt As New MemoryStream()
Using csEncrypt As New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)
Using swEncrypt As New StreamWriter(csEncrypt)
'Write all data to the stream.
swEncrypt.Write(plainText)
End Using
encrypted = msEncrypt.ToArray()
End Using
End Using
Dim encryptedText = Convert.ToBase64String(encrypted)
txtkey.Text = Convert.ToBase64String(aesAlg.Key)
txtiv.Text = Convert.ToBase64String(aesAlg.IV)
txtkeysize.Text = aesAlg.KeySize
txtencrypted.Text = encryptedText
txtpadding.Text = aesAlg.Padding
End Using

Get the Progress of a Filestream?

I'm building an website that allows users to upload/download/delete/manage files in a database.
For clarification, the web application uploads files to a database, NOT the file system. This is because of server constraints and I have no control over it.
I use a filestream to convert the file into a blob and then stick it in the database. What I'd like to know is:
Is it possible to get the progress of a filestream for large files? See how much has been streamed so far or set a timer to update that value?
My code is as follows:
Dim fs As Stream = upload1.PostedFile.InputStream
Dim br As New BinaryReader(fs)
Dim bytes as Byte() = br.ReadBytes(fs.Length)
Dim length As Integer = fs.Length
Then I add "bytes" as a parameter to my Stored Procedure and run the query. What could I add to this to maybe get the status of the filestream?
I hope this is clear, if not I can clarify.
Thanks!
You could copy one stream to another using a code like this and insert your progress code in the middle:
Public Shared Sub Copy(ByVal source As Stream, ByVal destination As Stream, ByVal bufferSize As Integer)
Dim num As Integer
Dim buffer As Byte() = New Byte(bufferSize - 1) {}
Do While (num = source.Read(buffer, 0, buffer.Length) <> 0)
destination.Write(buffer, 0, num)
' insert progress code here
Loop
End Sub

dynamically change querystring in asp.net

Our client is asking to encrypt the URL because it is passing values in the query string. We have used encryption and are able to encrypt the URL; however, existing code uses querystring["var"] in so many places and fails because of the encrypted URL. Hence, on page load, we will have to decrypt the URL. If I decrypt and alter the query string using response.redirect, then again query string will be visible in the URL and can be misused.
Please help.
EDIT
I was reading about RESTfull web service. I have not yet understood entire concept. I wonder if I can use this with my application to hide query string. Please let me know if so.
Thanks.
One way to achieve this with little headache is to decrypt the query string as you currently do, then set its values to some object which can be stored in the session. Storing it in a session variable would be useful if you wanted to exclude this information (hide) from the query string - you'd essentially be passing the data around behind the scenes.
Once stored in session, you would then change your code, such that wherever you use querystring["var"], you will instead refer to the object that has been stored in the session.
Edit
Note, though, that this doesn't have to be relegated to a single value. This object can have multiple properties each representing a query string value:
MyQueryStringObject myQueryStringObject = new MyQueryStringObject(SomeUrl);
//MyQueryStringObject decrypts the query string and assigns the values to properties in its constructor
string abc = myQueryStringObject.abc;
string xyz = myQueryStringObject.xyz;
Now, that uses properties to represent each query string value. You may have tons of them. In that case, you can store the values into some sort of Dictionary or a NameValueCollection perhaps.
There are various ways to achieve this which I think is beyond topic, but, note that the key to all of this, the very essence is to simply decrypt the url on the server (during postback) and save the unencrypted data into a session variable should you want to hide it from the URL.
There is a much better way of going about this. I deal with a client with that has the same requirement. This class has soared through security scans as well.
Public Class QueryStringManager
Public Shared Function BuildQueryString(ByVal url As String, ByVal queryStringValues As NameValueCollection) As String
Dim builder As New StringBuilder()
builder.Append(url & "?")
Dim count = queryStringValues.Count
If count > 0 Then
For Each key In queryStringValues.AllKeys
Dim value As String = queryStringValues(key)
Dim param As String = BuildParameter(key, value)
builder.Append(param)
Next
End If
Return builder.ToString()
End Function
Public Shared Function DeconstructQueryString(ByVal Request As HttpRequest) As NameValueCollection
Dim queryStringValues As New NameValueCollection
For Each key In Request.QueryString.AllKeys
Dim value As String = Request.QueryString(key)
value = DeconstructParameter(value)
queryStringValues.Add(key, value)
Next
Return queryStringValues
End Function
Private Shared Function BuildParameter(ByVal key As String, ByVal value As String) As String
Dim builder As New StringBuilder()
builder.Append(key.ToString() & "=")
value = GetSafeHtmlFragment(value)
Dim encrypt As Security = New Security()
value = encrypt.Encrypt(value)
builder.Append(value)
builder.Append("&")
Return builder.ToString()
End Function
Public Shared Function DeconstructParameter(ByVal value As Object) As String
Dim decrypt As New Security()
value = decrypt.Decrypt(value)
value = GetSafeHtmlFragment(value)
End Function
End Class
Use
Dim nvc As NameValueCollection = New NameValueCollection()
nvc.Add("value", 1)
Dim builtUrl As String = QueryStringManager.BuildQueryString(url, nvc)
Response.Redirect(builtUrl, false);
Then when you get to the page you simply write:
Dim decryptedValues As NameValueCollection = QueryStringManager.DeconstructQueryString(Request)
The reason why I use NameValueCollection is because that's the same type as QueryString. You can build on to the class to add an object into the QueryString based on it's properties and their values as well. This keeps all of the complex and tedious logic encapsulated away.

ASP.NET Rijndael Encryption Error - Specified key is not a valid size for this algorithm

I can't seem to get past this problem, I've created what I assume to be a 256-bit key using the random generator at GRC and combined that with my IV. I keep getting the error below:
Specified key is not a valid size for this algorithm.
Any help is gratefully received, here is the code I am using to Encrypt/Decrypt:
Private Function Rijndael(ByVal sInput As String, ByVal bEncrypt As Boolean) As String
' Setup the Key and Initialization Vector.
Dim byteKey As Byte() = Encoding.UTF8.GetBytes("C3CA193570B26E5C3CBB50FD805A0E23BAFFABA135E82C41517EEDCB9B7C90AC")
Dim byteIV As Byte() = Encoding.UTF8.GetBytes("c+O2r)J~?L:$]u[2")
' Create an instance of the encyrption algorithm.
Dim _rijndael As New RijndaelManaged()
' Create an encryptor using our key and IV
Dim transform As ICryptoTransform
If bEncrypt Then
transform = _rijndael.CreateEncryptor(byteKey, byteIV)
Else
transform = _rijndael.CreateDecryptor(byteKey, byteIV)
End If
' Create the streams for input and output
Dim msOutput As New System.IO.MemoryStream()
Dim msInput As New CryptoStream(msOutput, transform, CryptoStreamMode.Write)
' Feed data into the crypto stream.
msInput.Write(Encoding.UTF8.GetBytes(sInput), 0, Encoding.UTF8.GetBytes(sInput).Length)
' Flush crypto stream.
msInput.FlushFinalBlock()
Return Convert.ToBase64String(msOutput.ToArray)
End Function
C3CA193570B26E5C3CBB50FD805A0E23BAFFABA135E82C41517EEDCB9B7C90AC is hex code for a 256-bit-long bitstream.
But Encoding.UTF8.GetBytes does not turn hex code into the corresponding bytes in the way you were thinking.
Because you had 64 characters in that string, you get 64 bytes of UTF-8 bytes. That's a 512-bit-long bitstream.

Resources