引用
'『對稱式』加密,
'''此方法可將加密過的密碼做逆向的解密工作,
'''套用範圍較廣,但目前架構僅限於伺服器端的內容加密儲存方式,
'''此目的是為了不讓具有資料庫管理權限的管理者直接看到一些
'''屬於公司內部的機密資料或是重要資料,而造成資料外洩的情況發生。
'
'-----------------------------------------------------------------------------------------------------------------
'
'此架構必須設計三個儲存『對稱演算法的秘密金鑰SecretKey』、『對稱演算法的起始向量SecretIV』及
'『加密後Base64內容字串EncryptedString』欄位
'以機密內容加密為例:
'加密時:由外部輸入欲加密字串內容後,程式會自動產生『對稱演算法的秘密金鑰』、『對稱演算法的起始向量』,
' 上述兩個資料是為瞭解密之用,因此你在前端程式必須將之儲存於資料庫欄位中,以利解密時取出之用。
' 隨後產生加密後的內容字串,此字串我們再使用Base64來做一次處理,加強加密內容的複雜度,
' 當然加密的欄位也必須儲存起來。
'
'解密時:我們可以從資料庫取出先前加密時產生的『對稱演算法的秘密金鑰』、『對稱演算法的起始向量』,
' 另外取出加密後的字串來做解密工作。
'
'-----------------------------------------------------------------------------------------------------------------
Imports System
Imports System.Text
Imports System.IO
Imports System.Security.Cryptography
Namespace Util.Encrypt
Public Class Symmetric
#Region "變數宣告"
Private mEncryptSrcStr As String
Private mDecryptSrcStr() As Byte
Private mEncrypt As String
Private mDecrypt As String
Private mSakey As String
Private mSaIV As String
Private mDSaKey() As Byte
Private mDSaIV() As Byte
#End Region
#Region "屬性宣告"
Public WriteOnly Property EncryptSrcStr() As String ''來源欲加密字串
Set(ByVal Value As String)
mEncryptSrcStr = Value
End Set
End Property
Public WriteOnly Property DecryptSrcStr() As String ''來源欲解密字串
Set(ByVal Value As String)
mDecryptSrcStr = Convert.FromBase64String(Value)
End Set
End Property
Public ReadOnly Property EncryptedString() As String ''加密後字串
Get
Return mEncrypt
End Get
End Property
Public ReadOnly Property DecryptedString() As String ''解密後字串
Get
Return mDecrypt
End Get
End Property
Public ReadOnly Property SecretKey() As String ''密鑰字串KEY秘密金鑰
Get
Return mSakey
End Get
End Property
Public ReadOnly Property SecretIV() As String ''密鑰字串IV起始向量
Get
Return mSaIV
End Get
End Property
Public WriteOnly Property DeSecretKey() As String ''密鑰字串KEY秘密金鑰
Set(ByVal Value As String)
mDSaKey = Convert.FromBase64String(Value)
End Set
End Property
Public WriteOnly Property DeSecretIV() As String ''密鑰字串IV起始向量
Set(ByVal Value As String)
mDSaIV = Convert.FromBase64String(Value)
End Set
End Property
#End Region
Public Sub New()
End Sub
Public Function EcryptSymmetric() As Boolean ''對稱式加密
'''==產生密鑰
Dim sa As SymmetricAlgorithm
Dim tmpSa As ICryptoTransform
sa = Rijndael.Create() 'AES (Rijndael) is a symmetric-key block cipher
sa.GenerateKey() '產生隨機的 (32*8) 位的密鑰
sa.Mode = CipherMode.ECB '區串流優先等級處理模式
sa.Padding = PaddingMode.Zeros '末尾資料區串流優先等級的填充模式
mSakey = Convert.ToBase64String(sa.Key) '取得SymmetricAlgorithm的對稱演算法的秘密金鑰
mSaIV = Convert.ToBase64String(sa.IV) '取得SymmetricAlgorithm的對稱演算法的起始向量
tmpSa = sa.CreateEncryptor(Convert.FromBase64String(mSakey), Convert.FromBase64String(mSaIV))
'''==============================================================================================
Dim ms As MemoryStream
Dim cs As CryptoStream
Dim Bufffer As Byte() = New Byte() {}
ms = New MemoryStream
cs = New CryptoStream(ms, tmpSa, CryptoStreamMode.Write)
If mEncryptSrcStr <> String.Empty Then
Bufffer = Encoding.UTF8.GetBytes(mEncryptSrcStr)
cs.Write(Bufffer, 0, Bufffer.Length)
cs.FlushFinalBlock()
cs.Close()
cs = Nothing
mEncrypt = String.Empty
mEncrypt = Convert.ToBase64String(ms.ToArray()) '加密後BASE64內容字串
If mEncrypt <> String.Empty Then
Return True
Else
Return False
End If
ms.Close()
Else
Throw New System.Exception("Error,加密原始字串內容是空值!")
End If
End Function
Public Function DecryptSymmetric() As Boolean ''對稱式解密
Dim ms As MemoryStream
Dim sa As SymmetricAlgorithm
Dim tmpSa As ICryptoTransform
Dim cs As CryptoStream
ms = New MemoryStream
sa = Rijndael.Create() 'AES (Rijndael) is a symmetric-key block cipher
sa.Mode = CipherMode.ECB '區串流優先等級處理模式
sa.Padding = PaddingMode.Zeros '末尾資料區串流優先等級的填充模式
sa.Key = mDSaKey
sa.IV = mDSaIV
tmpSa = sa.CreateDecryptor
cs = New CryptoStream(ms, tmpSa, CryptoStreamMode.Write)
cs.Write(mDecryptSrcStr, 0, mDecryptSrcStr.Length)
cs = Nothing
mDecrypt = Encoding.UTF8.GetString(ms.ToArray()) '解密後內容字串
If mDecrypt <> String.Empty Then
Return True
Else
Return False
End If
End Function
End Class
End Namespace
'------------------------------------------------------------------
'『非對稱式』加密,
'''此方法無法將加密過的密碼做逆向的解密工作,
'''通常適用於會員機制的伺服器端的密碼欄位儲存方式,
'''此目的是為了不讓具有資料庫管理權限的管理者直接看到使用者密碼,
'''而造成使用者密碼不當曝光的情況發生。
'
'------------------------------------------------------------------
'
'此架構必須設計兩個儲存『加密後密碼』及『加密的亂數』欄位
'以會員機制為例:
'註冊時:新的使用者註冊時會輸入密碼,儲存時我們便可使用
' CreateSalt()加密的亂數及CreateHash()加密亂數
' 儲存於資料庫中。
'登入時:使用者會輸入帳戶及密碼,此時前端輸入的密碼為未加密過的密碼
' ,此時將此密碼經過先前產生出來的『加密的亂數』再做一次
' CreateHash()產生的加密密碼後,與原來資料庫內儲存的密碼做
' 比對即可,上述方法可呼叫CheckAuthentication()即可。
'
'------------------------------------------------------------------Imports System
Imports System.Text
Imports System.IO
Imports System.Security.Cryptography
Imports System.Web.Security.FormsAuthentication
Namespace Util.Encrypt
Public Class Asymmetric
''CreateSalt 產生經過 RNGCryptoServiceProvider 所加密的亂數
''這是被用來傳遞給CreateHash()做串連使用者前端畫面所輸入的密碼之方法
Public Function CreateSalt() As String
Dim rng As RNGCryptoServiceProvider = New RNGCryptoServiceProvider '實作密碼編譯亂數產生器 (RNG)。
Dim size As Integer
size = CInt(Int((20 * Rnd()) + 1))
Dim buff() As Byte = New Byte(size) {}
rng.GetBytes(buff)
Return Convert.ToBase64String(buff)
End Function
''CreateHash 產生雜湊運算後的字串
''salt 為CreateSalt() 所產生的加密字串
''pwd 為前端使用者在畫面所輸入的密碼
Public Function CreateHash(ByVal pwd As String, ByVal salt As String) As String
Dim saltPwd As String = String.Concat(pwd, salt)
Dim data() As Byte = Encoding.UTF8.GetBytes(saltPwd)
Dim result() As Byte
Dim shaM As New SHA1Managed
result = shaM.ComputeHash(data)
Dim hashPwd As String = Convert.ToBase64String(result)
Return hashPwd
End Function
''pwd 未加密過的密碼,也就是前端使用者所輸入的密碼
''hashedPwd 已儲存在資料庫中且加密過的密碼
''salt 已儲存在資料庫中且經過 RNGCryptoServiceProvider 所產生的加密亂數
Public Function CheckAuthentication(ByVal pwd As String, ByVal salt As String, ByVal hashedPwd As String) As Boolean
Dim hashPwdcmp As String = CreateHash(pwd, salt)
Dim cp As Boolean
If hashedPwd.Equals(hashPwdcmp) Then
cp = True
Else
cp = False
End If
Return cp
End Function
End Class
End Namespace