Results 1 to 2 of 2

Thread: FYI: Encryption thru the built-in cryptology

Threaded View

  1. #1

    Thread Starter
    C# Aficionado Lord_Rat's Avatar
    Join Date
    Sep 2001
    Location
    Cave
    Posts
    2,497

    FYI: Encryption thru the built-in cryptology

    VB supplies a strongly-encrypted service provider, the System.Security.Cryptography namespace.

    Unfortunately, after reading all the MSDN articles and the posts on these boards, I was none-the-better off with implementing those classes as when I started.

    It appears that people have been having a hard time understanding, much less implementing, this namespace.

    Well, my job required that I learn it, so I did. Because of the immense effort required, I wanted to provide my code here so that some other people will not have to go through the headache I had to go through.

    You may use it, as long as you follow the terms laid out in the beginning...

    VB Code:
    1. ''Cryptography wrapper classes
    2.     ''Programmed by Keith Ratliff
    3.     '' (c) 2003 Keith Ratliff
    4.     ''Uses code from the RSA library
    5.     '' - additional copyrights may need including with your application
    6.     ''You may use these classes, or modifications of them royalty-free under the
    7.     '' following terms:
    8.     '' 1) You must state somewhere within your program that you are using
    9.     ''    encryption routines supplied by Keith Ratliff
    10.     '' 2) You must email me ([email protected]) with the name of the
    11.     ''    application and Web site of that application
    12.     '' 3) You may not sell these routines in a non-compiled code
    13.     '' 4) If your program is a DLL, the parent program must comply with term 1
    14.     '' 5) This copyright and notice must remain intact.
    15.  
    16.     'to use this function, do something like this:
    17.     'Dim objCP As CryptoPass
    18.     'objCP = CreateHash(txtPassword.Text)
    19.     'MsgBox(DecryptHash(objCP))
    20.  
    21.     'The objCP will contain a .Hash and .Salt
    22.     'You need both to decrypt, so if you are storing the encrypted
    23.     'values, store both
    24.  
    25.     'Constants:
    26.     Const KeyLen = 31   '0-based key length
    27.     Const HKeyLen = 15  'half that size (also 0-based)
    28.  
    29.     'Create Salt Function
    30.     ' Salt is a generic term for random bits.
    31.     Private Function CreateSalt(ByVal size As Integer) As String
    32.         ' Create a cryptographically generated random number using the
    33.         ' cryptographic service provider
    34.         Dim rng As New System.Security.Cryptography.RNGCryptoServiceProvider()
    35.         ' Create a buffer to hold this information
    36.         Dim buff(size) As Byte
    37.         ' Fill the buffer with salt
    38.         rng.GetBytes(buff)
    39.         ' Convert to a string for returning.
    40.         ' Due to null-handling, we will not use this again
    41.         Return Convert.ToBase64String(buff)
    42.     End Function
    43.  
    44.     'Create Key Function
    45.     ' Uses the input key to create a cryptographic key in a byte array
    46.     Private Function CreateKey(ByVal Key() As Byte) As Byte()
    47.         'Create our object that will generate the key, based on the application name and
    48.         '  supplied key
    49.         Dim objPDB As New System.Security.Cryptography.PasswordDeriveBytes(Application.ProductName, Key)
    50.         'Send our key back as a byte array
    51.         Return objPDB.GetBytes(KeyLen + 1)
    52.     End Function
    53.  
    54.     'Create Salt Function
    55.     'Same as other function, except that it creates salt based on the
    56.     'KeySize constant and returns as a byte array.
    57.     Private Function CreateSalt() As Byte()
    58.         Dim abytSalt(KeyLen) As Byte
    59.         Dim rng As System.Security.Cryptography.RandomNumberGenerator = System.Security.Cryptography.RandomNumberGenerator.Create()
    60.         rng.GetBytes(abytSalt)
    61.         Return abytSalt
    62.     End Function
    63.  
    64.     'Create Hash function
    65.     'Takes the inputted text and makes a hash and salt value from it
    66.     ' In these functions, the salt is used to determine the key (randomly)
    67.     ' To decrypt, the salt has to be preserved which is the primary purpose
    68.     ' of the CryptoPass class.
    69.     Private Function CreateHash(ByVal sToEncrypt As String) As CryptoPass
    70.         Dim abytKey(KeyLen) As Byte
    71.         Dim PwdAndSalt As String       ' Will store our password, appended with salt
    72.         Dim objSalt() As Byte = CreateSalt()       ' Get a byte array of salt
    73.         PwdAndSalt = sToEncrypt    'Put our string in the PwdAndSalt string
    74.         PwdAndSalt += Chr(0)       'Place a null-terminator in the string manually
    75.         Dim tmpString As String    'For use with the BtoS function
    76.         BtoS(objSalt, tmpString)       'Convert the Salt Byte array to a string
    77.         PwdAndSalt += tmpString    'Add the salt to the end of the PwdAndSalt string
    78.         Dim abytEnc(255) As Byte       'Byte array for the encrypted data
    79.         Dim tmpByte(255) As Byte          'Byte array for the buffer
    80.         ' Create a buffer to allow the cryptography provider to do its thing
    81.         Dim objBuffer As New System.IO.MemoryStream(tmpByte, 0, tmpByte.Length, True, True)
    82.         ' Change our PwdAndSalt array to a byte array (for use in the cryptography provider)
    83.         StoB(PwdAndSalt, tmpByte)
    84.         ' Create a Symmetric Algorithm Provider (Key Keeper)
    85.         Dim objSymm As System.Security.Cryptography.SymmetricAlgorithm = System.Security.Cryptography.SymmetricAlgorithm.Create("Rijndael")
    86.         ' Create the key based on the salt
    87.         abytKey = CreateKey(objSalt)
    88.         objSymm.Key = abytKey
    89.         ' Save the salt for returning from the function since we are about to truncate it
    90.         CreateHash = New CryptoPass()
    91.         CreateHash.Salt = objSalt
    92.         ' And truncate to the shorter length for the IV
    93.         ReDim Preserve objSalt(HKeyLen)
    94.         ' And assign to the IV
    95.         objSymm.IV = objSalt
    96.         ' Create the stream object and give it our SymmetricAlgorithm so that it creates
    97.         ' a hash we can decrypt later
    98.         Dim objCrypto As New System.Security.Cryptography.CryptoStream(objBuffer, objSymm.CreateEncryptor(), Security.Cryptography.CryptoStreamMode.Write)
    99.         ' Have it do it's thing and output to the buffer
    100.         objCrypto.Write(tmpByte, 0, tmpByte.Length)
    101.         ' Tell it to expand to the rest of the buffer using padding
    102.         objCrypto.FlushFinalBlock()
    103.         ' Create a variable to keep the hash
    104.         Dim hashedPwd As String
    105.         ' Reset the buffer pointer
    106.         objBuffer.Seek(0, IO.SeekOrigin.Begin)
    107.         ' Retrieve the buffer as a byte array to the abytEnc byte array
    108.         abytEnc = objBuffer.GetBuffer()
    109.         ' Convert the byte array to a string
    110.         BtoS(abytEnc, hashedPwd)
    111.         ' Store in the object
    112.         CreateHash.Hash = hashedPwd
    113.         ' Close the crypto provider. We cannot close it before now since we needed the
    114.         '   buffer and closing the provider also closes the buffer.
    115.         objCrypto.Close()
    116.     End Function
    117.  
    118.     'Decrypt Function.
    119.     ' Expects the hash and the salt used to create the hash
    120.     ' Uses the CryptoPass class for this
    121.     Private Function DecryptPasswordHash(ByVal objCP As CryptoPass) As String
    122.         ' Recreate our Symmetric Algorithm using the settings from the encryption routine
    123.         Dim objSymm As System.Security.Cryptography.SymmetricAlgorithm = System.Security.Cryptography.SymmetricAlgorithm.Create("Rijndael")
    124.         Dim abytKey(KeyLen) As Byte
    125.         abytKey = CreateKey(objCP.Salt)
    126.         objSymm.Key = abytKey
    127.         Dim objSalt() As Byte = objCP.Salt
    128.         ReDim Preserve objSalt(HKeyLen)
    129.         objSymm.IV = objSalt
    130.  
    131.         ' Create a byte array so that we can pass the hash in to the buffer
    132.         Dim tmpByte() As Byte
    133.         ' Fill the byte array with the contents of the Hash from the CP object
    134.         StoB(objCP.Hash, tmpByte)
    135.         ' And now, create that buffer
    136.         Dim objBuffer As New System.IO.MemoryStream(tmpByte, 0, tmpByte.Length, True, True)
    137.         ' Create a decryptor using our Symmetric Alorithm
    138.         Dim csDecrypted As New System.Security.Cryptography.CryptoStream(objBuffer, objSymm.CreateDecryptor(), System.Security.Cryptography.CryptoStreamMode.Read)
    139.         ' Create a stream reader buffer to read from the csDecrypted, the decrypted value
    140.         Dim objBuffer2 As New System.IO.StreamReader(csDecrypted)
    141.         ' Create a string to hold the decrypted value and read it
    142.         Dim tmpString As String
    143.         tmpString = objBuffer2.ReadToEnd()
    144.         ' We dont need the decrytor any more, or the buffer, so close them
    145.         ' Remember that closing the cryptostream also closes the buffer
    146.         csDecrypted.Close()
    147.         tmpString = tmpString.Substring(0, tmpString.IndexOf(Chr(0)))
    148.         'our original string had a termination character.
    149.         'Once this is decrypted, attempting to use it results in expected behaviour, since it still has a null
    150.         'terminator, but since the btos function converts all of the byte stream (not stopping at the first instance
    151.         'of null) it will have a wrong .length size. This fixes that.
    152.         Return tmpString
    153.     End Function
    154.  
    155.     'Converts a string to a byte array
    156.     Private Function StoB(ByVal inString As String, ByRef outBytes() As Byte)
    157.         ReDim outBytes(inString.Length)
    158.         Dim i As Integer
    159.         For i = 0 To inString.Length - 1
    160.             outBytes(i) = Asc(inString.Substring(i, 1))
    161.         Next
    162.     End Function
    163.  
    164.     'converts a byte array to a string. Does not stop at the first null character
    165.     Private Function BtoS(ByVal inBytes() As Byte, ByRef outString As String)
    166.         outString = ""
    167.         Dim i As Integer
    168.         For i = 0 To inBytes.Length - 1
    169.             outString += Chr(inBytes(i))
    170.         Next
    171.     End Function
    172.  
    173.     'CryptoPass class. For keeping the hash with the salt
    174.     Private Class CryptoPass
    175.         Private _Hash As String
    176.         Private _Salt As Byte()
    177.         Public Property Hash() As String
    178.             Get
    179.                 Return _Hash
    180.             End Get
    181.             Set(ByVal Value As String)
    182.                 _Hash = Value
    183.             End Set
    184.         End Property
    185.  
    186.         Public Property Salt() As Byte()
    187.             Get
    188.                 Return _Salt
    189.             End Get
    190.             Set(ByVal Value As Byte())
    191.                 _Salt = Value
    192.             End Set
    193.         End Property
    194.     End Class
    Last edited by Lord_Rat; Nov 18th, 2003 at 02:38 PM.
    Need to re-register ASP.NET?
    C:\WINNT\Microsoft.NET\Framework\v#VERSIONNUMBER#\aspnet_regiis -i

    (Edit #VERSIONNUMBER# as needed - do a DIR if you don't know)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width