본문 바로가기
VB.net

SHA256 암복호화

by 호야호잇 2018. 5. 11.



Imports System

Imports System.IO

Imports System.Security.Cryptography

Imports System.Text



Module PW

    '//*********************************************************

    '// 스트링/파일 암/복호화 클래스(비대칭 알고리즘 사용)

    '//*********************************************************

    Public Class Crypto


        '//*********************************************************

        '// 비대칭 암/복호화 알고리즘 상수

        '//*********************************************************

        Public Enum CryptoTypes

            encTypeDES = 0

            encTypeRC2

            encTypeRijndael

            encTypeTripleDES

        End Enum


        Const CRYPT_DEFAULT_PASSWORD As String = "ChangDol"   '// abcd!@#"

        Const CRYPT_DEFAULT_METHOD As CryptoTypes = CryptoTypes.encTypeDES


        Dim mKey() As Byte = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}

        Dim mIV() As Byte = {65, 110, 68, 26, 69, 178, 200, 219}

        Dim SaltByteArray() As Byte = {&H49, &H76, &H61, &H6E, &H20, &H4D, &H65, &H64, &H76, &H65, &H64, &H65, &H76}

        Dim mCryptoType As CryptoTypes = CRYPT_DEFAULT_METHOD

        Dim mPassword As String = CRYPT_DEFAULT_PASSWORD


        Dim sInputFile As String = String.Empty, sOutputFile = String.Empty





        '//*********************************************************

        '// 디폴트 생성자

        '//     VB.NET 에서 생성자는 항상 New()이다.....

        '//     C#.NET 에셔는 클래스 이름과 같으면 된다...

        '//*********************************************************

        Sub New()

            calculateNewKeyAndIV()

        End Sub




        '//*********************************************************

        '// 생성자(암/복호화 타입을 지정)

        '//*********************************************************

        '// <param name="CryptoType"></param>

        Sub New(ByVal CryptoType As CryptoTypes)

            Me.mCryptoType = CryptoType

        End Sub



        '//*********************************************************

        '// 암호화 복호화 사용

        '// Private Property CryptoType() As CryptoTypes

        '//*********************************************************


        Property CryptoType() As CryptoTypes

            Get

                Return mCryptoType

            End Get


            Set(ByVal value As CryptoTypes)


                '//if mCryptoType != value then

                mCryptoType = value

                calculateNewKeyAndIV()


                '// end if

            End Set

        End Property



        '//*********************************************************

        '//  암호화 비밀번호

        '//  The password key used when encrypting / decrypting

        '//*********************************************************

        Public Property Password() As String

            Get

                Return mPassword

            End Get


            Set(ByVal value As String)

                If mPassword <> value Then

                    mPassword = value

                    calculateNewKeyAndIV()

                End If

            End Set

        End Property




        '//*********************************************************

        '// 텍스트를 암호화한다.

        '// <param name="inputText">암호화할 텍스트</param>

        '// <returns>암호화된 텍스트</returns>

        '//*********************************************************

        Function Encrypt(ByVal inputText As String) As String


            '//declare a new encoder

            Dim UTF8Encoder As System.Text.UTF8Encoding = New System.Text.UTF8Encoding


            '//get byte representation of string

            Dim inputBytes() As Byte = UTF8Encoder.GetBytes(inputText)


            '//convert back to a string

            Return Convert.ToBase64String(EncryptDecrypt(inputBytes, True))


        End Function



        '//*********************************************************

        '// 사용자가 지정한 패스워드로 암호화한다.

        '// <param name="inputText">암호화할 텍스트</param>

        '// <param name="password">암호화에 사용할 패스워드</param>

        '// <returns>암호화된 텍스트</returns>

        '//*********************************************************

        Public Function Encrypt(ByVal inputText As String, ByVal password As String) As String

            Me.mPassword = password

            Return Me.Encrypt(inputText)



        End Function




        '//*********************************************************

        '// 사용자가 지정한 cryptoType과 패스워드로 텍스트를 암호화한다.

        '// <param name="inputText">암호화할 텍스트</param>

        '// <param name="password">암호화에 사용할 패스워드</param>

        '// <param name="cryptoType">암호화 타입</param>

        '// <returns>암호화된 텍스트</returns>

        '//*********************************************************

        Public Function Encrypt(ByVal inputText As String, ByVal password As String, ByVal cryptoType As CryptoTypes) As String

            Me.mCryptoType = cryptoType

            Return Me.Encrypt(inputText, password)

        End Function



        '//*********************************************************

        '// 사용자가 지정한 cryptoType으로 텍스트를 암호화한다.

        '// <param name="inputText">암호화할 텍스트</param>

        '// <param name="cryptoType">암호화 타입</param>

        '// <returns>암호화된 텍스트</returns>

        '//*********************************************************

        Public Function Encrypt(ByVal inputText As String, ByVal cryptoType As CryptoTypes) As String

            Me.mCryptoType = cryptoType

            Return Me.Encrypt(inputText)

        End Function




        '//*********************************************************

        '// 텍스트를 복호화한다.

        '// <param name="inputText">복호화할 텍스트</param>

        '// <returns>복호화된 텍스트</returns>

        '//*********************************************************


        Public Function Decrypt(ByVal inputText As String) As String

            '//declare a new encoder

            Dim UTF8Encoder As UTF8Encoding = New UTF8Encoding()


            '//get byte representation of string

            Dim inputBytes() As Byte = Convert.FromBase64String(inputText)


            '//convert back to a string

            Return UTF8Encoder.GetString(EncryptDecrypt(inputBytes, False))

        End Function



        '//*********************************************************

        '// 사용자가 지정한 패스워드키에 의해 텍스트를 복호화한다.

        '// <param name="inputText">복호화할 텍스트</param>

        '// <param name="password">복호화할 때 사용할 패스워드</param>

        '// <returns>복호화된 텍스트</returns>

        '//*********************************************************


        Public Function Decrypt(ByVal inputText As String, ByVal password As String) As String

            Me.mPassword = password

            Return Decrypt(inputText)


        End Function




        '//*********************************************************

        '// 사용자가 지정한 cryptoType과 패스워드로 텍스트를 복호화한다.

        '// <param name="inputText">복호화할 텍스트</param>

        '// <param name="password">복호화에 사용할 패스워드</param>

        '// <param name="cryptoType">복호화 타입</param>

        '// <returns>복호화된 텍스트</returns>

        '//*********************************************************

        Public Function Decrypt(ByVal inputText As String, ByVal password As String, ByVal cryptoType As CryptoTypes) As String

            Me.mCryptoType = cryptoType

            Return Decrypt(inputText, password)


        End Function



        '//*********************************************************

        '// 사용자가 지정한 cryptoType으로 텍스트를 복호화한다.

        '// <param name="inputText">복호화할 텍스트</param>

        '// <param name="cryptoType">복호화 타입</param>

        '// <returns>복호화된 텍스트</returns>

        '//*********************************************************

        Public Function Decrypt(ByVal inputText As String, ByVal cryptoType As CryptoTypes) As String

            Me.mCryptoType = cryptoType

            Return Decrypt(inputText)

        End Function



        '//*********************************************************

        '//     performs the actual enc/dec.

        '// <param name="inputBytes">input byte array</param>

        '// <param name="Encrpyt">wheather or not to perform enc/dec</param>

        '// <returns>byte array output</returns>

        '//*********************************************************

        Private Function EncryptDecrypt(ByRef inputBytes() As Byte, ByVal Encrpyt As Boolean) As Byte()

            '//get the correct transform

            Dim transform As ICryptoTransform = getCryptoTransform(Encrpyt)


            '//memory stream for output

            Dim memStream As MemoryStream = New MemoryStream()


            Try

                '//setup the cryption - output written to memstream

                Dim cryptStream As CryptoStream = New CryptoStream(memStream, transform, CryptoStreamMode.Write)


                '//write data to cryption engine

                cryptStream.Write(inputBytes, 0, inputBytes.Length)


                '//we are finished

                cryptStream.FlushFinalBlock()


                '//get result

                Dim output() As Byte = memStream.ToArray()


                '//finished with engine, so close the stream

                cryptStream.Close()

                Return output


            Catch e As Exception

                '//throw an error

                Throw New Exception("Error in symmetric engine. Error : " + e.Message, e)


            End Try


        End Function



        '//*********************************************************

        '//     returns the symmetric engine and creates the encyptor/decryptor

        '// <param name="encrypt">whether to return a encrpytor or decryptor</param>

        '// <returns>ICryptoTransform</returns>

        '//*********************************************************

        Private Function getCryptoTransform(ByVal encrypt As Boolean) As ICryptoTransform

            Dim SA As SymmetricAlgorithm = selectAlgorithm()

            SA.Key = mKey

            SA.IV = mIV

            If encrypt Then

                Return SA.CreateEncryptor()

            Else

                Return SA.CreateDecryptor()

            End If

        End Function



        '//*********************************************************

        '//     returns the specific symmetric algorithm acc. to the cryptotype

        '// <returns>SymmetricAlgorithm</returns>

        '//*********************************************************

        Private Function selectAlgorithm() As SymmetricAlgorithm

            Dim SA As SymmetricAlgorithm

            Select Case mCryptoType

                Case CryptoTypes.encTypeDES

                    SA = DES.Create()

                Case CryptoTypes.encTypeRC2

                    SA = RC2.Create()

                Case CryptoTypes.encTypeRijndael

                    SA = Rijndael.Create()

                Case CryptoTypes.encTypeTripleDES

                    SA = TripleDES.Create()

                Case Else

                    SA = TripleDES.Create()

            End Select


            Return SA


        End Function


        '//*********************************************************

        '//     calculates the key and IV acc. to the symmetric method from the password

        '//     key and IV size dependant on symmetric method

        '//*********************************************************

        Private Sub calculateNewKeyAndIV()

            '// 새로운 메서드로 대체되었다.

            '// Dim pdb As PasswordDeriveBytes = New PasswordDeriveBytes(mPassword, SaltByteArray)

            Dim pdb As Rfc2898DeriveBytes = New Rfc2898DeriveBytes(mPassword, SaltByteArray)

            Dim algo As SymmetricAlgorithm = selectAlgorithm()

            mKey = pdb.GetBytes(algo.KeySize / 8)

            mIV = pdb.GetBytes(algo.BlockSize / 8)


        End Sub



        '//*********************************************************

        '// 암호화 처리 함수(DES 알고리즘)

        '// <param name="sInputFile">입력 파일</param>

        '// <param name="sOutputFile">출력 파일</param>

        '//*********************************************************

        Public Sub EncryptFile(ByVal sInputFile As String, ByVal sOutputFile As String)

            EncryptOrDecryptFile(sInputFile, sOutputFile, 1)


        End Sub




        '//*********************************************************

        '// 복호화 처리 함수(DES 알고리즘)

        '// <param name="sInputFile">입력 파일</param>

        '// <param name="sOutputFile">출력 파일</param>

        '//*********************************************************

        Public Sub DecryptFile(ByVal sInputFile As String, ByVal sOutputFile As String)

            EncryptOrDecryptFile(sInputFile, sOutputFile, 2)

        End Sub



        '//*********************************************************

        '// 암호화/복호화 처리 함수(DES 알고리즘)

        '// <param name="sInputFile">입력 파일</param>

        '// <param name="sOutputFile">출력 파일</param>

        '// <param name="Direction">암호화(1)/복호화(2) 여부</param>

        '//*********************************************************

        Private Sub EncryptOrDecryptFile(ByVal sInputFile As String, ByVal sOutputFile As String, ByVal Direction As Integer)

            '// byte[] byteDESKey = GetKeyByteArray(password);

            '// byte[] byteDESIV = GetKeyByteArray(ivpassword);

            '// 파일 스트림을 만들어 입력 및 출력 파일을 처리합니다.


            Dim fsInput As FileStream = New FileStream(sInputFile, FileMode.Open, FileAccess.Read)

            Dim fsOutput As FileStream = New FileStream(sOutputFile, FileMode.OpenOrCreate, FileAccess.Write)

            fsOutput.SetLength(0)



            '// 암호화/암호 해독 프로세스 중 필요한 변수입니다.

            Dim byteBuffer(4096) As Byte '//  = New Byte() '// 처리를 위해 바이트 블록을 보유합니다.

            Dim nBytesProcessed As Long = 0 '// 암호화된 바이트의 실행 카운트

            Dim nFileLength As Long = fsInput.Length

            Dim iBytesInCurrentBlock As Integer

            Dim csMyCryptoStream As CryptoStream


            Select Case mCryptoType

                Case CryptoTypes.encTypeDES

                    csMyCryptoStream = DESCSP(fsOutput, Direction)

                Case CryptoTypes.encTypeRC2

                    csMyCryptoStream = RC2CSP(fsOutput, Direction)

                Case CryptoTypes.encTypeRijndael

                    csMyCryptoStream = RijndaelCSP(fsOutput, Direction)

                Case CryptoTypes.encTypeTripleDES

                    csMyCryptoStream = TripleDESCSP(fsOutput, Direction)

                Case Else

                    csMyCryptoStream = DESCSP(fsOutput, Direction)

            End Select




            '// 입력 파일에서 읽은 다음 암호화하거나 암호를 해독하고

            '// 출력 파일에 씁니다.


            While (nBytesProcessed < nFileLength)

                iBytesInCurrentBlock = fsInput.Read(byteBuffer, 0, 4096)

                csMyCryptoStream.Write(byteBuffer, 0, iBytesInCurrentBlock)

                nBytesProcessed = nBytesProcessed + CType(iBytesInCurrentBlock, Long)


            End While



            csMyCryptoStream.Close()

            fsInput.Close()

            fsOutput.Close()




        End Sub


        Private Function DESCSP(ByVal fsOutput As FileStream, ByVal Direction As Integer) As CryptoStream

            Dim Provider As DESCryptoServiceProvider = New DESCryptoServiceProvider()

            Dim csMyCryptoStream As CryptoStream = New CryptoStream(fsOutput, Provider.CreateDecryptor(), CryptoStreamMode.Read)



            '// 암호화나 암호 해독을 위한 설정

            Select Case (Direction)

                Case 1 '// 암호화

                    csMyCryptoStream = New CryptoStream(fsOutput, Provider.CreateEncryptor(mKey, mIV), CryptoStreamMode.Write)

                Case 2 '// 복호화

                    csMyCryptoStream = New CryptoStream(fsOutput, Provider.CreateDecryptor(mKey, mIV), CryptoStreamMode.Write)

            End Select

            Return csMyCryptoStream


        End Function



        Private Function RC2CSP(ByVal fsOutput As FileStream, ByVal Direction As Integer) As CryptoStream

            Dim Provider As RC2CryptoServiceProvider = New RC2CryptoServiceProvider()

            '//Dim csMyCryptoStream As CryptoStream

            Dim csMyCryptoStream As CryptoStream = New CryptoStream(fsOutput, Provider.CreateDecryptor(), CryptoStreamMode.Read)


            '// 암호화나 암호 해독을 위한 설정

            Select Case (Direction)

                Case 1 '// 암호화

                    csMyCryptoStream = New CryptoStream(fsOutput, Provider.CreateEncryptor(mKey, mIV), CryptoStreamMode.Write)


                Case 2 '// 복호화

                    csMyCryptoStream = New CryptoStream(fsOutput, Provider.CreateDecryptor(mKey, mIV), CryptoStreamMode.Write)

            End Select

            Return csMyCryptoStream


        End Function



        Private Function RijndaelCSP(ByVal fsOutput As FileStream, ByVal Direction As Integer) As CryptoStream

            Dim Provider As RijndaelManaged = New RijndaelManaged()

            '// Dim csMyCryptoStream As CryptoStream

            Dim csMyCryptoStream As CryptoStream = New CryptoStream(fsOutput, Provider.CreateDecryptor(), CryptoStreamMode.Read)


            '// 암호화나 암호 해독을 위한 설정


            Select Case (Direction)

                Case 1 '// 암호화

                    csMyCryptoStream = New CryptoStream(fsOutput, Provider.CreateEncryptor(mKey, mIV), CryptoStreamMode.Write)


                Case 2 '// 복호화

                    csMyCryptoStream = New CryptoStream(fsOutput, Provider.CreateDecryptor(mKey, mIV), CryptoStreamMode.Write)

            End Select

            Return csMyCryptoStream


        End Function



        Private Function TripleDESCSP(ByVal fsOutput As FileStream, ByVal Direction As Integer) As CryptoStream

            Dim Provider As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider()

            '// Dim csMyCryptoStream As CryptoStream

            Dim csMyCryptoStream As CryptoStream = New CryptoStream(fsOutput, Provider.CreateDecryptor(), CryptoStreamMode.Read)


            '// 암호화나 암호 해독을 위한 설정


            Select Case (Direction)

                Case 1 '// 암호화

                    csMyCryptoStream = New CryptoStream(fsOutput, Provider.CreateEncryptor(mKey, mIV), CryptoStreamMode.Write)


                Case 2 '// 복호화

                    csMyCryptoStream = New CryptoStream(fsOutput, Provider.CreateDecryptor(mKey, mIV), CryptoStreamMode.Write)

            End Select

            Return csMyCryptoStream


        End Function



        Private Function GetKeyByteArray(ByVal sPassword As String) As Byte()

            Dim byteTemp(7) As Byte

            sPassword = sPassword.PadRight(8)

            byteTemp = System.Text.Encoding.ASCII.GetBytes(sPassword.ToCharArray())

            Return byteTemp


        End Function


    End Class




    '//*********************************************************

    '// 해슁 클래스로 스태틱 멤버만 있다.

    '//*********************************************************

    Public Class Hashing


        '//*********************************************************

        '// 가능한 해슁 멤버

        '//*********************************************************

        Public Enum HashingTypes


            SHA

            SHA256

            SHA384

            SHA512

            MD5


        End Enum



        '//*********************************************************

        '// 입력 텍스트를 해슁 알고리즘으로 암호화한다(해슁 알고리즘 MD5)

        '// <param name="inputText">암호화할 텍스트</param>

        '// <returns>암호화된 텍스트</returns>

        '//*********************************************************


        Private Function Hash(ByVal inputText As String) As String

            Return ComputeHash(inputText, HashingTypes.MD5)

        End Function



        '//*********************************************************

        '// 입력 텍스트를 사용자가 지정한 해슁 알고리즘으로 암호화한다.

        '// <param name="inputText">암호화할 텍스트</param>

        '// <param name="hashingType">해슁 알고리즘</param>

        '// <returns>암호화된 텍스트</returns>

        '//*********************************************************

        Private Function Hash(ByVal inputText As String, ByVal hashingType As HashingTypes) As String

            Return ComputeHash(inputText, hashingType)

        End Function



        '//*********************************************************

        '// 입력 텍스트와 해쉬된 텍스트가 같은지 여부를 비교한다.

        '// <param name="inputText">해쉬되지 않은 입력 텍스트</param>

        '// <param name="hashText">해쉬된 텍스트</param>

        '// <returns>비교 결과</returns>

        '//*********************************************************


        Private Function isHashEqual(ByVal inputText As String, ByVal hashText As String) As Boolean

            Return (Hash(inputText) = hashText)

        End Function




        '//*********************************************************

        '// 사용자가 지정한 해쉬 알고리즘으로 입력 텍스트와 해쉬된 텍스트가 같은지 여부를 비교한다.

        '// <param name="inputText">해쉬되지 않은 입력 텍스트</param>

        '// <param name="hashText">해쉬된 텍스트</param>

        '// <param name="hashingType">사용자가 지정한 해슁 타입</param>

        '// <returns>비교 결과</returns>

        '//*********************************************************


        Private Function isHashEqual(ByVal inputText As String, ByVal hashText As String, ByVal hashingType As HashingTypes) As Boolean

            Return (Hash(inputText, hashingType) = hashText)

        End Function



        '//*********************************************************

        '// 해쉬 코드를 계산해서 스트링으로 변환함

        '// <param name="inputText">해쉬코드로 변환할 스트링</param>

        '// <param name="hashingType">사용할 해슁 타입</param>

        '// <returns>hashed string</returns>

        '//*********************************************************

        Private Function ComputeHash(ByVal inputText As String, ByVal hashingType As HashingTypes) As String

            Dim HA As HashAlgorithm = getHashAlgorithm(hashingType)

            '//declare a new encoder

            Dim UTF8Encoder As UTF8Encoding = New UTF8Encoding()


            '//get byte representation of input text

            Dim inputBytes() As Byte = UTF8Encoder.GetBytes(inputText)


            '//hash the input byte array

            Dim output() As Byte = HA.ComputeHash(inputBytes)


            '//convert output byte array to a string


            Return Convert.ToBase64String(output)

        End Function



        '//*********************************************************

        '// 특정한 해슁 알고리즘을 리턴함

        '// <param name="hashingType">사용할 해슁 알고리즘</param>

        '// <returns>HashAlgorithm</returns>

        '//*********************************************************


        Private Function getHashAlgorithm(ByVal hashingType As HashingTypes) As HashAlgorithm

            Select Case (hashingType)

                Case HashingTypes.MD5

                    Return New MD5CryptoServiceProvider()


                Case HashingTypes.SHA

                    Return New SHA1CryptoServiceProvider()


                Case HashingTypes.SHA256

                    Return New SHA256Managed()


                Case HashingTypes.SHA384

                    Return New SHA384Managed()


                Case HashingTypes.SHA512


                    Return New SHA512Managed()


                Case Else


                    Return New MD5CryptoServiceProvider()


            End Select


        End Function


    End Class

End Module



'VB.net' 카테고리의 다른 글

문자열 검색 기능  (0) 2018.05.23
공부 필요 Anti Process Kill  (0) 2018.05.16
파일 이어쓰기, 연달아 쓰기, 다음줄 쓰기  (0) 2018.05.11
PC 1시간뒤 자동 종료되게 하기  (0) 2018.05.11
폴더, 파일 존재여부 확인  (0) 2018.05.03