280 lines
No EOL
13 KiB
VB.net
280 lines
No EOL
13 KiB
VB.net
Imports System.Security.Cryptography
|
|
Imports System.IO
|
|
Imports System.Text
|
|
Imports System.Web
|
|
Imports BaseClasses.Resources
|
|
|
|
'SymmCrypto is a wrapper of System.Security.Cryptography.SymmetricAlgorithm classes
|
|
'and simplifies the interface. It supports customized SymmetricAlgorithm as well.
|
|
'Original Code from Frank Fang
|
|
'Revised by Jerome Howard to remove Bad Data errors, create seperate CryptoIV and
|
|
'use the maximum legal keysize for each encryption algorithm
|
|
|
|
Namespace Persons.Data
|
|
|
|
Public Class Crypto
|
|
'256 Bit IV Key that is truncated when a smaller keys are required
|
|
Private bytIV() As Byte = _
|
|
{78, 90, 23, 7, 54, 109, 34, 231, 90, 66, 109, 185, 228, 143, 89, 77, 190, 89, 103, 148, 54, 4, 98, 67, 243, 162, 68, 201, 73, 59, 184, 52}
|
|
'Supported .Net intrinsic SymmetricAlgorithm classes.
|
|
Public Enum Providers
|
|
DES
|
|
RC2
|
|
Rijndael
|
|
End Enum
|
|
|
|
Private _CryptoService As SymmetricAlgorithm
|
|
|
|
Public Sub New()
|
|
' Use the default provider of DES.
|
|
Me.New(Crypto.Providers.DES)
|
|
End Sub
|
|
|
|
'Constructor for using an intrinsic .Net SymmetricAlgorithm class.
|
|
Public Sub New(ByVal NetSelected As Providers)
|
|
Select Case NetSelected
|
|
Case Providers.DES
|
|
_CryptoService = New DESCryptoServiceProvider
|
|
Case Providers.RC2
|
|
_CryptoService = New RC2CryptoServiceProvider
|
|
Case Providers.Rijndael
|
|
_CryptoService = New RijndaelManaged
|
|
End Select
|
|
End Sub
|
|
|
|
'Constructor for using a customized SymmetricAlgorithm class.
|
|
Public Sub New(ByVal ServiceProvider As SymmetricAlgorithm)
|
|
_CryptoService = ServiceProvider
|
|
End Sub
|
|
|
|
'Depending on the legal key size limitations of a specific CryptoService provider
|
|
'and length of the private key provided, padding the secret key with a character
|
|
'or triming it to meet the legal size of the algorithm.
|
|
Private Function GetLegalKey(ByVal Key As String) As Byte()
|
|
'key sizes are in bits
|
|
Dim sTemp As String
|
|
Dim dValue As Integer
|
|
If (_CryptoService.LegalKeySizes.Length > 0) Then
|
|
Dim maxSize As Integer = _CryptoService.LegalKeySizes(0).MaxSize
|
|
dValue = CInt(maxSize / 8)
|
|
If Key.Length * 8 > maxSize Then
|
|
sTemp = Key.Substring(0, dValue)
|
|
Else
|
|
Dim moreSize As Integer = _CryptoService.LegalKeySizes(0).MinSize
|
|
Do While (Key.Length * 8 > moreSize)
|
|
moreSize += _CryptoService.LegalKeySizes(0).SkipSize
|
|
Loop
|
|
sTemp = Key.PadRight(dValue, "X".Chars(0))
|
|
End If
|
|
Else
|
|
sTemp = Key
|
|
End If
|
|
|
|
'Ensure that the IV Block size is also correct for the specific CryptoService provider
|
|
If (_CryptoService.LegalBlockSizes.Length > 0) Then
|
|
Dim maxSize As Integer = _CryptoService.LegalBlockSizes(0).MaxSize
|
|
dValue = CInt(maxSize / 8)
|
|
ReDim Preserve bytIV(sTemp.Length - 1)
|
|
If sTemp.Length * 8 > maxSize Then
|
|
ReDim Preserve bytIV(dValue - 1)
|
|
End If
|
|
End If
|
|
'convert the secret key to byte array
|
|
Return ASCIIEncoding.ASCII.GetBytes(sTemp)
|
|
End Function
|
|
|
|
Public Overridable Function Encrypt(ByVal Source As String, Optional ByVal includeSession As Boolean = True) As String
|
|
If (Source Is Nothing) Then
|
|
Return ""
|
|
End If
|
|
Dim s As String = ""
|
|
Try
|
|
If includeSession Then
|
|
s = Me.Encrypt(Source, Me.GetCryptoKey(), False)
|
|
s = System.Web.HttpUtility.UrlEncode(s)
|
|
Else
|
|
s = Me.Encrypt(Source, Me.GetCryptoKeyWithoutSessionVariable(), False)
|
|
End If
|
|
Catch ex As Exception
|
|
' In case of error, just return the source itself without encryption.
|
|
s = Source
|
|
End Try
|
|
Return s
|
|
End Function
|
|
|
|
Public Function Encrypt(ByVal Source As String, ByVal Key As String, Optional ByVal Encoded As Boolean = True) As String
|
|
Return Me.Encrypt(Source, Key, System.Text.Encoding.ASCII, Encoded)
|
|
End Function
|
|
|
|
Public Function Encrypt(ByVal Source As String, ByVal Key As String, ByVal Encoding As System.Text.Encoding, Optional ByVal Encoded As Boolean = True) As String
|
|
If Source Is Nothing OrElse Source.Trim.Length = 0 Then
|
|
Return Source
|
|
End If
|
|
|
|
|
|
If Encoded Then
|
|
Source = System.Web.HttpUtility.UrlEncode(Source)
|
|
End If
|
|
Dim bytIn As Byte()
|
|
|
|
|
|
If Encoding.EncodingName = System.Text.Encoding.ASCII.EncodingName Then
|
|
bytIn = System.Text.ASCIIEncoding.GetEncoding(System.Globalization.CultureInfo.CurrentUICulture.TextInfo.ANSICodePage).GetBytes(Source)
|
|
ElseIf Encoding.EncodingName = System.Text.Encoding.Unicode.EncodingName Then
|
|
bytIn = System.Text.UnicodeEncoding.GetEncoding(System.Globalization.CultureInfo.CurrentUICulture.TextInfo.ANSICodePage).GetBytes(Source)
|
|
Else
|
|
bytIn = System.Text.ASCIIEncoding.GetEncoding(System.Globalization.CultureInfo.CurrentUICulture.TextInfo.ANSICodePage).GetBytes(Source)
|
|
End If
|
|
'= System.Text.ASCIIEncoding.ASCII.GetBytes(Source)
|
|
Dim ms As MemoryStream = New MemoryStream
|
|
|
|
'set the keys
|
|
_CryptoService.Key = GetLegalKey(Key)
|
|
_CryptoService.IV = bytIV
|
|
|
|
'create an Encryptor from the Provider Service instance
|
|
Dim encrypto As ICryptoTransform = _CryptoService.CreateEncryptor()
|
|
|
|
'create Crypto Stream that transforms a stream using the encryption
|
|
Dim cs As CryptoStream = New CryptoStream(ms, encrypto, CryptoStreamMode.Write)
|
|
|
|
'write out encrypted content into MemoryStream
|
|
cs.Write(bytIn, 0, bytIn.Length)
|
|
cs.FlushFinalBlock()
|
|
cs.Close()
|
|
Dim bytOut() As Byte = ms.ToArray()
|
|
ms.Close()
|
|
|
|
Return Convert.ToBase64String(bytOut) 'convert into Base64 so that the result can be used in xml
|
|
End Function
|
|
|
|
Public Overridable Function Decrypt(ByVal Source As String, Optional ByVal includeSession As Boolean = True) As String
|
|
Dim s As String = ""
|
|
Try
|
|
' First try decrypting as is.
|
|
If includeSession Then
|
|
s = Me.Decrypt(Source, Me.GetCryptoKey(), False)
|
|
s = System.Web.HttpUtility.UrlDecode(s)
|
|
Else
|
|
s = Me.Decrypt(Source, Me.GetCryptoKeyWithoutSessionVariable(), False)
|
|
End If
|
|
Catch ex As Exception
|
|
Try
|
|
' If the first try of decrypting does not work, then
|
|
' URL decode it and try again. This is to ensure that if
|
|
' the encrypted key is passed through the URL, it needs to
|
|
' be decoded first.
|
|
Source = System.Web.HttpUtility.UrlDecode(Source)
|
|
s = Me.Decrypt(Source, GetCryptoKey(), False)
|
|
Catch ex1 As Exception
|
|
' In case of error, throw new Exception: do not allow to access encrypted page with non-encrypted URL
|
|
Throw New System.UriFormatException(RU.GetErrMsg(RU.ErrRes.GetRecords))
|
|
End Try
|
|
End Try
|
|
|
|
If ((Source IsNot Nothing AndAlso Source.Trim() <> "") AndAlso (s Is Nothing OrElse s.Trim() = "")) Then
|
|
Throw New System.UriFormatException(RU.GetErrMsg(RU.ErrRes.GetRecords))
|
|
End If
|
|
|
|
Return s
|
|
End Function
|
|
|
|
Public Function Decrypt(ByVal Source As String, ByVal Key As String, Optional ByVal Encoded As Boolean = True) As String
|
|
Return Me.Decrypt(Source, Key, System.Text.Encoding.ASCII, Encoded)
|
|
End Function
|
|
|
|
Public Function Decrypt(ByVal Source As String, ByVal Key As String, ByVal Encoding As System.Text.Encoding, Optional ByVal Encoded As Boolean = True) As String
|
|
If Source Is Nothing OrElse Source.Trim.Length = 0 Then
|
|
Return Source
|
|
End If
|
|
|
|
'convert from Base64 to binary
|
|
Dim bytIn As Byte()
|
|
Dim ms As MemoryStream
|
|
Try
|
|
bytIn = System.Convert.FromBase64String(Source)
|
|
ms = New MemoryStream(bytIn)
|
|
Catch ex As Exception
|
|
bytIn = System.Convert.FromBase64String(Source.Replace(" ", "+"))
|
|
ms = New MemoryStream(bytIn)
|
|
End Try
|
|
|
|
Dim bytKey() As Byte = GetLegalKey(Key)
|
|
Dim bytTemp(bytIn.Length) As Byte
|
|
|
|
'set the private key
|
|
_CryptoService.Key = bytKey
|
|
_CryptoService.IV = bytIV
|
|
|
|
'create a Decryptor from the Provider Service instance
|
|
Dim encrypto As ICryptoTransform = _CryptoService.CreateDecryptor()
|
|
|
|
'create Crypto Stream that transforms a stream using the decryption
|
|
Dim cs As CryptoStream = New CryptoStream(ms, encrypto, CryptoStreamMode.Read)
|
|
Dim output As String = ""
|
|
Try
|
|
'read out the result from the Crypto Stream
|
|
Dim sr As StreamReader
|
|
If Encoding.EncodingName = System.Text.Encoding.ASCII.EncodingName Then
|
|
sr = New StreamReader(cs, System.Text.ASCIIEncoding.GetEncoding(System.Globalization.CultureInfo.CurrentUICulture.TextInfo.ANSICodePage))
|
|
ElseIf Encoding.EncodingName = System.Text.Encoding.Unicode.EncodingName Then
|
|
sr = New StreamReader(cs, System.Text.UnicodeEncoding.GetEncoding(System.Globalization.CultureInfo.CurrentUICulture.TextInfo.ANSICodePage))
|
|
Else
|
|
sr = New StreamReader(cs, System.Text.ASCIIEncoding.GetEncoding(System.Globalization.CultureInfo.CurrentUICulture.TextInfo.ANSICodePage))
|
|
End If
|
|
output = sr.ReadToEnd
|
|
sr.Close()
|
|
ms.Close()
|
|
cs.Close()
|
|
Catch ex As Exception
|
|
bytIn = System.Convert.FromBase64String(Source.Replace(" ", "+"))
|
|
ms = New MemoryStream(bytIn)
|
|
bytKey = GetLegalKey(Key)
|
|
|
|
'set the private key
|
|
_CryptoService.Key = bytKey
|
|
_CryptoService.IV = bytIV
|
|
encrypto = _CryptoService.CreateDecryptor()
|
|
|
|
Try
|
|
'create Crypto Stream that transforms a stream using the decryption
|
|
cs = New CryptoStream(ms, encrypto, CryptoStreamMode.Read)
|
|
Dim sr As StreamReader
|
|
If Encoding.EncodingName = System.Text.Encoding.ASCII.EncodingName Then
|
|
sr = New StreamReader(cs, System.Text.ASCIIEncoding.GetEncoding(System.Globalization.CultureInfo.CurrentUICulture.TextInfo.ANSICodePage))
|
|
ElseIf Encoding.EncodingName = System.Text.Encoding.Unicode.EncodingName Then
|
|
sr = New StreamReader(cs, System.Text.UnicodeEncoding.GetEncoding(System.Globalization.CultureInfo.CurrentUICulture.TextInfo.ANSICodePage))
|
|
Else
|
|
sr = New StreamReader(cs, System.Text.ASCIIEncoding.GetEncoding(System.Globalization.CultureInfo.CurrentUICulture.TextInfo.ANSICodePage))
|
|
End If
|
|
output = sr.ReadToEnd
|
|
sr.Close()
|
|
ms.Close()
|
|
cs.Close()
|
|
Catch
|
|
End Try
|
|
|
|
End Try
|
|
If Encoded Then
|
|
output = System.Web.HttpUtility.UrlDecode(output)
|
|
End If
|
|
Return output
|
|
End Function
|
|
|
|
' The URLEncryptionKey is specified in the web.config. The rightmost six characters of the current
|
|
' Session Id are concatenated with the URLEncryptionKey to provide added protection. You can change
|
|
' this to anything you like by changing this function for the application.
|
|
' This function is private and not overridable because each page cannot have its own key - it must
|
|
' be common across the entire application.
|
|
Private Function GetCryptoKey() As String
|
|
Return Left(System.Web.HttpContext.Current.Session.SessionID, 6) & BaseClasses.Configuration.ApplicationSettings.Current.URLEncryptionKey & Right(System.Web.HttpContext.Current.Session.SessionID, 6)
|
|
End Function
|
|
|
|
Private Function GetCryptoKeyWithoutSessionVariable() As String
|
|
Return Left("ffx4ypamvvcs4knwbxxehl45", 6) & BaseClasses.Configuration.ApplicationSettings.Current.URLEncryptionKey & Right("ffx4ypamvvcs4knwbxxehl45", 6)
|
|
End Function
|
|
|
|
|
|
End Class
|
|
|
|
End Namespace |