研究SSO的副產(chǎn)品,在尋找好的加密算法
在ASP.NET中常用的有:不可逆的HASH算法,如MD5,SHA1,對(duì)稱可逆的DES,不對(duì)稱可逆的RSA等.我最終選擇的是對(duì)稱可擬的AES算法的衍生算法:Rijndael,因?yàn)樗用芎蟮拈L度比較小,適合在URL中攜帶,而原本考慮的RSA算法生成128位長度的字串,顯得未免太長了,呼呼
以下代碼綜合了網(wǎng)上各類文章并做了部分整合修改.需要的人可以使用.至于MD5,SHA1,BASE64之類的在.NET里一條語句就搞定.呼呼
------------------
Rijndael算法:
密鑰KEY和起始量IV都通過專門的函數(shù)生成.如果是要做成可調(diào)用的函數(shù),,可修改EncryptString128Bit,DecryptString128Bit
Imports System.Security.Cryptography
Imports System.IO
Imports System.Text
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
Private Function CreateKey(ByVal strPassword As String) As Byte()
Dim chrData() As Char = strPassword.ToCharArray
Dim intLength As Integer = chrData.GetUpperBound(0)
Dim bytDataToHash(intLength) As Byte
For i As Integer = 0 To chrData.GetUpperBound(0)
bytDataToHash(i) = CByte(Asc(chrData(i)))
Next
Dim SHA512 As New System.Security.Cryptography.SHA512Managed
Dim bytResult As Byte() = SHA512.ComputeHash(bytDataToHash)
Dim bytKey(31) As Byte
For i As Integer = 0 To 31
bytKey(i) = bytResult(i)
Next
Return bytKey
End Function
Private Function CreateIV(ByVal strPassword As String) As Byte()
Dim chrData() As Char = strPassword.ToCharArray
Dim intLength As Integer = chrData.GetUpperBound(0)
Dim bytDataToHash(intLength) As Byte
For i As Integer = 0 To chrData.GetUpperBound(0)
bytDataToHash(i) = CByte(Asc(chrData(i)))
Next
Dim SHA512 As New System.Security.Cryptography.SHA512Managed
Dim bytResult As Byte() = SHA512.ComputeHash(bytDataToHash)
Dim bytIV(15) As Byte
For i As Integer = 32 To 47
bytIV(i - 32) = bytResult(i)
Next
Return bytIV
End Function
Public Function EncryptString128Bit(ByVal vstrTextToBeEncrypted As String, ByVal vstrEncryptionKey As Byte(), ByVal vstrEncryptionVI As Byte()) As String
Dim bytValue() As Byte
Dim bytEncoded() As Byte
Dim objMemoryStream As New MemoryStream()
Dim objCryptoStream As CryptoStream
Dim objRijndaelManaged As RijndaelManaged
vstrTextToBeEncrypted = StripNullCharacters(vstrTextToBeEncrypted)
bytValue = Encoding.ASCII.GetBytes(vstrTextToBeEncrypted.ToCharArray)
objRijndaelManaged = New RijndaelManaged()
Try
objCryptoStream = New CryptoStream(objMemoryStream, _
objRijndaelManaged.CreateEncryptor(vstrEncryptionKey, vstrEncryptionVI), CryptoStreamMode.Write)
objCryptoStream.Write(bytValue, 0, bytValue.Length)
objCryptoStream.FlushFinalBlock()
bytEncoded = objMemoryStream.ToArray
objMemoryStream.Close()
objCryptoStream.Close()
Catch
End Try
Return Convert.ToBase64String(bytEncoded)
End Function
Public Function DecryptString128Bit(ByVal vstrStringToBeDecrypted As String, _
ByVal vstrDecryptionKey As Byte(), ByVal vstrDecryptionVI As Byte()) As String
Dim bytDataToBeDecrypted() As Byte
Dim bytTemp() As Byte
Dim objRijndaelManaged As New RijndaelManaged()
Dim objMemoryStream As MemoryStream
Dim objCryptoStream As CryptoStream
Dim strReturnString As String = String.Empty
bytDataToBeDecrypted = Convert.FromBase64String(vstrStringToBeDecrypted)
ReDim bytTemp(bytDataToBeDecrypted.Length)
objMemoryStream = New MemoryStream(bytDataToBeDecrypted)
Try
objCryptoStream = New CryptoStream(objMemoryStream, _
objRijndaelManaged.CreateDecryptor(vstrDecryptionKey, vstrDecryptionVI), CryptoStreamMode.Read)
objCryptoStream.Read(bytTemp, 0, bytTemp.Length)
objCryptoStream.FlushFinalBlock()
objMemoryStream.Close()
objCryptoStream.Close()
Catch
End Try
Return StripNullCharacters(Encoding.ASCII.GetString(bytTemp))
End Function
Public Function StripNullCharacters(ByVal vstrStringWithNulls As String) As String
Dim intPosition As Integer
Dim strStringWithOutNulls As String
intPosition = 1
strStringWithOutNulls = vstrStringWithNulls
Do While intPosition > 0
intPosition = InStr(intPosition, vstrStringWithNulls, vbNullChar)
If intPosition > 0 Then
strStringWithOutNulls = Microsoft.VisualBasic.Left$(strStringWithOutNulls, intPosition - 1) & _
Microsoft.VisualBasic.Right$(strStringWithOutNulls, Len(strStringWithOutNulls) - intPosition)
End If
If intPosition > strStringWithOutNulls.Length Then
Exit Do
End If
Loop
Return strStringWithOutNulls
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
RESULTTB.Text = EncryptString128Bit(ORGTB.Text, CreateKey(keyTB.Text), CreateIV(VITB.Text))
DesTB.Text = DecryptString128Bit(RESULTTB.Text, CreateKey(keyTB.Text), CreateIV(VITB.Text))
End Sub
End Class
----------------
RSA算法:
Imports System.Text
Imports System.Security.Cryptography
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim rsa1 As RSACryptoServiceProvider = New RSACryptoServiceProvider
Dim rsa2 As RSACryptoServiceProvider = New RSACryptoServiceProvider
Dim publickey, privatekey As String
publickey = rsa1.ToXmlString(False)
privatekey = rsa1.ToXmlString(True)
TextBox1.Text = publickey
TextBox2.Text = privatekey
Dim plaintext As String
plaintext = "天幻網(wǎng)" & vbCrLf & "12345678" & vbCrLf & "211.95.72.224"
TextBox3.Text &= "原始數(shù)據(jù)是:" & Microsoft.VisualBasic.Chr(10) & plaintext
rsa2.FromXmlString(privatekey)
Dim cipherbytes As Byte()
cipherbytes = rsa2.Encrypt(Encoding.UTF8.GetBytes(plaintext), False)
TextBox3.Text &= "加密后的數(shù)據(jù)是(" & cipherbytes.Length.ToString & "):"
Dim i As Integer = 0
While i < cipherbytes.Length
TextBox3.Text &= String.Format("{0:X2} ", cipherbytes(i))
System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1)
End While
Dim plaintbytes As Byte()
plaintbytes = rsa1.Decrypt(cipherbytes, False)
TextBox3.Text &= "解密后的數(shù)據(jù)是:"
TextBox3.Text &= Encoding.UTF8.GetString(plaintbytes)
End Sub
End Class
-----------------------
DES算法:
Imports System.Data.SqlClient
Imports System.Security
Imports System.Security.Cryptography
Imports System.Text
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim key, Str As String
key = TextBox1.Text
Str = TextBox3.Text
TextBox2.Text = Encrypt(Str, key)
End Sub
'DES加密方法
Public Shared Function Encrypt(ByVal pToEncrypt As String, ByVal sKey As String) As String
Dim des As New DESCryptoServiceProvider()
Dim inputByteArray() As Byte
inputByteArray = Encoding.Default.GetBytes(pToEncrypt)
'建立加密對(duì)象的密鑰和偏移量
'原文使用ASCIIEncoding.ASCII方法的GetBytes方法
'使得輸入密碼必須輸入英文文本
des.Key = ASCIIEncoding.ASCII.GetBytes(sKey)
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey)
'寫二進(jìn)制數(shù)組到加密流
'(把內(nèi)存流中的內(nèi)容全部寫入)
Dim ms As New System.IO.MemoryStream()
Dim cs As New CryptoStream(ms, des.CreateEncryptor, CryptoStreamMode.Write)
'寫二進(jìn)制數(shù)組到加密流
'(把內(nèi)存流中的內(nèi)容全部寫入)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
'建立輸出字符串
Dim ret As New StringBuilder()
Dim b As Byte
For Each b In ms.ToArray()
ret.AppendFormat("{0:X2}", b)
Next
Return ret.ToString()
End Function
'DES解密方法
Public Shared Function Decrypt(ByVal pToDecrypt As String, ByVal sKey As String) As String
Dim des As New DESCryptoServiceProvider()
'把字符串放入byte數(shù)組
Dim len As Integer
len = pToDecrypt.Length / 2 - 1
Dim inputByteArray(len) As Byte
Dim x, i As Integer
For x = 0 To len
i = Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16)
inputByteArray(x) = CType(i, Byte)
Next
'建立加密對(duì)象的密鑰和偏移量,,此值重要,不能修改
des.Key = ASCIIEncoding.ASCII.GetBytes(sKey)
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey)
Dim ms As New System.IO.MemoryStream()
Dim cs As New CryptoStream(ms, des.CreateDecryptor, CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Return Encoding.Default.GetString(ms.ToArray)
End Function
End Class