您正在查看"其他语言"下的文章

校内网相册批量下载工具

说明:

1.由于超时等影响,本工具不保证整个相册的照片都能下载完全。

2.输入登录邮箱,登录密码,相册地址,选择好路径(最好是一个空的文件夹哦,否则可能会一堆图片和你的原来文件混在一起),点击“开始下载”按钮即开始尝试下载,刚开始可能分析失败,请重新点击“开始下载”重试,如果显示已经开始下载,那么你就可以干别的事去了,程序可能出现假死,不要关闭,过一会就把整个相册下载到你指定的文件夹下了。 阅读全文 »

线程间操作无效: 从不是创建控件的线程访问它

最近用VB.NET写一个校内网相册批量下载工具,已经基本完成,能够比较完整的下载完整个相册。但是有一个问题,就是下载的时候程序会出现假死,无法移动等操作。以前写的小工具也出现这样的问题,都是因为for循环里面执行太多的操作。今天终于决定改一改,找到可以用线程来解决假死的问题。于是立马动手开始修改了,改完后却发现出现”线程间操作无效: 从不是创建控件的线程访问它”的异常,第一次见,到网上查资料,找到几种解决方案,都是说的C#的,不过两语言基本共通,修改一下就应该可以了,不过以我这资质,估计还的研究研究了,先摘录以备用。 阅读全文 »

VB.NET如何读取网页文件

源码下载:下载文件 点击下载此文件
在.net中,system.net命名空间下的webclient类提供想URI标识的资源发送数据和从URI标识的资源接受数据的公共方法。使用该类的OpenRead()方法可以直接从URI标识的资源接受数据流,即下载数据。
本实例程序将使用该方法下载目标网页的数据流,并通过systerm.io.streamreader对象将下载的数据流读取出来,达到读取网页内容的目的。
webclient类常用的公共方法说明如下:
(1)DownLoadData()方法,用于从具有指定URI的资源下载数据。
(2)DownLoadFile()方法,用于从具有指定URI的资源将数据下载到本地文件。
(3)OpenRead()方法,从具有指定URI的资源下载的数据打开一个可读的流。
(4)OpenWrite()方法,用于打开一个流以将数据写入具有指定URI的资源。
(5)UploadData()方法,用于将数据缓冲区上载到具有指定URI的资源。
(6)UploadFile()方法,用于将本地文件上载到具有指定URI的资源。
(7)UploadValues()方法,用于将名称/值集合上载到具有指定URI的资源。
下面是使用WebClient类的OpenRead()方法读取网页内容的具体步骤:
1.创建一个Windows应用程序。

2.如上图所示拖入相应控件,然后为两个button添加单击事件:

程序代码 程序代码
‘下载按钮
     Private Sub btnDown_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDown.Click
         Dim MyURL As String = Me.txtURL.Text.Trim
         If MyURL.IndexOf("http://") = -1 Then
             MyURL = "http://" + MyURL
         End If
         Try
             ‘声明webclient对象,读取HTML
             Dim MyClient As New System.Net.WebClient
             ‘声明stream 对象,存放传回的HTML数据
             Dim MyStream As System.IO.Stream = MyClient.OpenRead(MyURL)
             ‘声明streamreader对象,用来读取stream对象中的数据
             Dim MyReader As New System.IO.StreamReader(MyStream, System.Text.Encoding.Default)
             ‘传回stream数据
             Me.rtxtContent.Text = MyReader.ReadToEnd()
             ‘关闭stream对象
             MyStream.Close()
         Catch ex As Exception
             MsgBox("读取网页出错:" + ex.Message, MsgBoxStyle.OkOnly, "信息提示")
         End Try
     End Sub
‘保存按钮
     Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
         With SaveFileDialog1
             .Title = "保存"
             .Filter = "文本文件(*.txt)|*.txt|网页文件(*.html/*.htm)|*.htm,*.html"
         End With

         If Me.rtxtContent.Text = "" Then
             Exit Sub
         End If
         If Me.SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
             Dim MyFileName As String = Me.SaveFileDialog1.FileName
             Me.rtxtContent.SaveFile(MyFileName, RichTextBoxStreamType.PlainText)
         End If
     End Sub

最后编译执行程序即可。

VB.NET如何读写文本文件

源码下载:下载文件 点击下载此文件
在.net中,对文件进行读写操作通常使用system.io命名空间下的streamreader类和streamwrite类。在不借助其他控件而需要对文件进行直接读写的情况下,使用streamreader类和streamwrite类进行读写操作是一种较好的选择。下面是使用streamreader类和streamwrite类实现读写文本文件的具体操作步骤:
1.新建一个windows 应用程序

2.拖放如上图所示控件,在“浏览文件”和“保存文件”两个按钮上添加事件:

程序代码 程序代码
‘浏览文件
     Private Sub btnOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpen.Click
         Dim Result As DialogResult
         Dim MyFileName As String
         With Me.OpenFileDialog1
             .Title = "打开文件"
             .CheckFileExists = True
             .CheckPathExists = True
             .Filter = "所有文本文件(*.txt)|*.txt"
             .ShowDialog()
             MyFileName = .FileName
         End With
         If Result = Windows.Forms.DialogResult.Cancel Then
             Exit Sub
         End If
         Me.RichTextBox1.Text = ""
         Try
             Dim myreader As New System.IO.StreamReader(MyFileName)
             Dim MyReceiver As String = myreader.ReadLine()
             While Not MyReceiver Is Nothing
                 Me.RichTextBox1.AppendText(MyReceiver & Environment.NewLine)
                 MyReceiver = myreader.ReadLine()
             End While
         Catch ex As Exception
             MsgBox("读取文件时发生错误!", MsgBoxStyle.OkOnly, "信息提示")
         End Try
     End Sub
‘保存文件
     Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
         Dim Result As DialogResult
         Dim MyFileName As String
         With Me.SaveFileDialog1
             .Title = "保存文件"
             .CheckFileExists = False
             .CheckPathExists = False
             .CreatePrompt = True
             .Filter = "所有文本文件(*.txt)|*.txt"
             .ShowDialog()
             MyFileName = .FileName
         End With
         If Result = Windows.Forms.DialogResult.Cancel Then
             Exit Sub
         End If
         Try
             Dim MyWriter As New System.IO.StreamWriter(MyFileName)
             MyWriter.Write(Me.RichTextBox1.Text)
             MyWriter.Close()
         Catch ex As Exception
             MsgBox("保存文本文件发生错误!", MsgBoxStyle.OkOnly, "信息提示")
         End Try
     End Sub

最后编译执行程序即可。

DES加密与解密

东拼西凑弄出来的,还行吧.
下载源码:下载文件 点击下载此文件
本文的程序在Visual Studio 2005的开发环境下实现,封装了.NET基础类库,因此程序运行需要.NET Framework 2.0或更高版本的支持。Microsoft .NET Framework 2.0版可从如下地址获得:
http://www.microsoft.com/downloads/details.aspx?FamilyID=0856eacb-4362-4b0d-8edd-aab15c5e04f5&displaylang=zh-cn

程序代码 程序代码
Imports System
Imports System.Security.Cryptography
Imports System.Text
Imports System.IO

Public Class Form1
     ”’ <summary>
     ”’ 加密方法
     ”’ </summary>
     ”’ <param name="pToEncrypt"></param>
     ”’ <param name="sKey"></param>
     ”’ <returns></returns>
     ”’ <remarks></remarks>
     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)
         ‘建立加密对象的密钥和偏移量
         ‘原文使用ASCIIEncoding.ASCII方法的GetBytes方法
         ‘使得输入密码必须输入英文文本
         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.CreateEncryptor, CryptoStreamMode.Write)
         ‘写二进制数组到加密流
         ‘(把内存流中的内容全部写入)
         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

     ”’ <summary>
     ”’ 解密方法
     ”’ </summary>
     ”’ <param name="pToDecrypt"></param>
     ”’ <param name="sKey"></param>
     ”’ <returns></returns>
     ”’ <remarks></remarks>
     Public Shared Function Decrypt(ByVal pToDecrypt As String, ByVal sKey As String) As String
         Dim des As New DESCryptoServiceProvider()
         ‘把字符串放入byte数组
         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
         ‘建立加密对象的密钥和偏移量,此值重要,不能修改
         Try
             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.UTF8.GetString(ms.ToArray)

         Catch ex As Exception
             MsgBox("请输入正确的解密密码", MsgBoxStyle.OkOnly, "信息提示")
             Return ""
         End Try

     End Function

     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
         Me.OpenFileDialog1.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*"
         Me.OpenFileDialog1.CheckFileExists = True
         Me.OpenFileDialog1.CheckPathExists = True
         Me.OpenFileDialog1.InitialDirectory = System.Environment.GetFolderPath(Environment.SpecialFolder.Personal)
     End Sub

     Private Sub btnGetMingwen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetMingwen.Click
         If Me.OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
             Dim fileMingwenName As String = Me.OpenFileDialog1.FileName
             txtURLtoGetMingwen.Text = fileMingwenName
         End If

     End Sub

     Private Sub btnStoreMiwen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStoreMiwen.Click
         If Me.OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
             Dim fileMingwenName As String = Me.OpenFileDialog1.FileName
             txtURLtoStoreMiwen.Text = fileMingwenName
         End If
     End Sub

     Private Sub btnGetMiwen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetMiwen.Click
         If Me.OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
             Dim fileMingwenName As String = Me.OpenFileDialog1.FileName
             txtURLtoGetMiwen.Text = fileMingwenName
         End If
     End Sub

     Private Sub btnStoreMingwen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStoreMingwen.Click
         If Me.OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
             Dim fileMingwenName As String = Me.OpenFileDialog1.FileName
             txtURLtoStoreMingwen.Text = fileMingwenName
         End If
     End Sub

     Private Sub btnJiami_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnJiami.Click
         Dim strDatatoEncrypt As String = ""
         Try
             If txtURLtoGetMingwen.Text = "" Then
                 MsgBox("请选择需要加密的文件")
                 Exit Sub
             End If
             ‘ Create an instance of StreamReader to read from a file.
             Using sr As StreamReader = New StreamReader(txtURLtoGetMingwen.Text, Encoding.Default)
                 Dim line As String
                 ‘ Read and display the lines from the file until the end
                 ‘ of the file is reached.
                 Do
                     line = sr.ReadLine()
                     strDatatoEncrypt = strDatatoEncrypt + line + Environment.NewLine
                 Loop Until line Is Nothing
                 sr.Close()
                 ‘MsgBox(strDatatoEncrypt)
             End Using
         Catch ex As Exception
             ‘ Let the user know what went wrong.
             Console.WriteLine(ex.Message)
         End Try

         If txtJiami1.Text = "" or txtJiami2.Text = "" Then
             MsgBox("请输入加密密钥", MsgBoxStyle.OkOnly, "信息提示")
             txtJiami1.Focus()
             txtJiami1.SelectAll()
             Exit Sub
         ElseIf txtJiami1.Text <> txtJiami2.Text Then
             MsgBox("两次输入的密钥不同,请重新输入", MsgBoxStyle.OkOnly, "信息提示")
             txtJiami1.Focus()
             txtJiami1.SelectAll()
             Exit Sub
         ElseIf txtJiami1.Text.Length <> 8 Then
             MsgBox("请输入8位英文大小写字母或数字", MsgBoxStyle.OkOnly, "信息提示")
             txtJiami1.Focus()
             txtJiami1.SelectAll()
             Exit Sub
         End If

         Dim EncryptedData As String = Encrypt(strDatatoEncrypt, txtJiami1.Text)

         ‘ Create an instance of StreamWriter to write text to a file.
         If txtURLtoStoreMiwen.Text = "" Then
             MsgBox("请选择密文存放路径", MsgBoxStyle.OkOnly, "信息提示")
             Exit Sub
         End If
         Using sw As StreamWriter = New StreamWriter(txtURLtoStoreMiwen.Text)
             ‘ Add some text to the file.
             sw.Write(EncryptedData)
             sw.Close()
         End Using
         If MsgBox("恭喜您加密成功,是否退出?", MsgBoxStyle.OkCancel, "信息提示") = MsgBoxResult.Ok Then
             Me.Close()
         End If
     End Sub

     Private Sub btnJiemi_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnJiemi.Click
         Dim strDatatoDecrypt As String = ""
         Try
             If txtURLtoGetMiwen.Text = "" Then
                 MsgBox("请选择需要解密的文件")
                 Exit Sub
             End If
             ‘ Create an instance of StreamReader to read from a file.
             Using sr As StreamReader = New StreamReader(txtURLtoGetMiwen.Text, Encoding.Default)
                 Dim line As String
                 ‘ Read and display the lines from the file until the end
                 ‘ of the file is reached.
                 Do
                     line = sr.ReadLine()
                     strDatatoDecrypt = strDatatoDecrypt + line
                 Loop Until line Is Nothing
                 sr.Close()
                 ‘MsgBox(strDatatoEncrypt)
             End Using
         Catch ex As Exception
             ‘ Let the user know what went wrong.
             Console.WriteLine(ex.Message)
         End Try

         If txtJiemi1.Text = "" or txtJiemi2.Text = "" Then
             MsgBox("请输入解密密钥", MsgBoxStyle.OkOnly, "信息提示")
             txtJiemi1.Focus()
             txtJiemi1.SelectAll()
             Exit Sub
         ElseIf txtJiemi1.Text <> txtJiemi2.Text Then
             MsgBox("两次输入的密钥不同,请重新输入", MsgBoxStyle.OkOnly, "信息提示")
             txtJiemi1.Focus()
             txtJiemi1.SelectAll()
             Exit Sub
         ElseIf txtJiemi1.Text.Length <> 8 Then
             MsgBox("请输入8位英文大小写字母或数字", MsgBoxStyle.OkOnly, "信息提示")
             txtJiemi1.Focus()
             txtJiemi1.SelectAll()
             Exit Sub
         End If

         Dim DecryptedData As String = Decrypt(strDatatoDecrypt, txtJiemi1.Text)
         If DecryptedData = "" Then
             Exit Sub
         End If
         ‘ Create an instance of StreamWriter to write text to a file.
         If txtURLtoStoreMingwen.Text = "" Then
             MsgBox("请选择解密后的明文存放路径", MsgBoxStyle.OkOnly, "信息提示")
             Exit Sub
         End If
         Using sw As StreamWriter = New StreamWriter(txtURLtoStoreMingwen.Text)
             ‘ Add some text to the file.
             sw.Write(DecryptedData)
             sw.Close()
         End Using

         If MsgBox("恭喜您解密成功,是否退出?", MsgBoxStyle.OkCancel, "信息提示") = MsgBoxResult.Ok Then
             Me.Close()
         End If
     End Sub

     Private Sub btnAbout_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAbout.Click
         MsgBox ("作者:颖之猫" + Environment.NewLine + "学号:200532660039" + Environment.NewLine + "时间:2008/04/22" + Environment.NewLine + "作业:加密解密程 序", MsgBoxStyle.OkOnly, "关于程序")
     End Sub

     Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExit.Click
         Me.Close()
     End Sub
End Class

.NET框架下实现高性能的文件加密系统(3)

四、系统性能分析    我们从横向和纵向两个方面对程序做对比测试,测试环境如表1所示。横向对比中,我们分别就对称密码、公钥密码、数字签名和消息摘要四组来对文本处理的结果进行性能分析;纵向测试中,我们将本程序与VC平台下实现的其他文件加密软件作了性能对比。限于篇幅,程序执行时间的统计实现请见源代码。

.NET框架下实现高性能的文件加密系统(2)

三、程序运行
    本文的程序在Visual Studio 2005的开发环境下实现,封装了.NET基础类库,因此程序运行需要.NET Framework 2.0或更高版本的支持。Microsoft .NET Framework 2.0版可从如下地址获得:
http://www.microsoft.com/downloads/details.aspx?FamilyID=0856eacb-4362-4b0d-8edd-aab15c5e04f5&displaylang=zh-cn
    在确保机器上已正确安装了.NET Framework 2.0以后即可运行程序。
    通过选择不同的标签页可以执行相应的加解密、签名或消息摘要算法。在程序中我们还增加了时间测试功能,这样每一项操作执行完毕后均会给出提示并显示精确的用时,详细代码请见源程序。程序的DES和MD5运行界面如图4、5所示。

图4 DES操作界面

图5 MD5操作界面

.NET框架下实现高性能的文件加密系统

马 亮     陈 波

摘 要 介绍了.NET基础类库在system.security.cryptography命名空间下实现的诸多加密服务提供类。在此基础上,封装了基础类库中的相关安全类,实现了一个多功能文件加密系统。分析了相关安全类的实现,并与其他平台下实现的加解密程序进行了性能比较实验,结果表明。
关键词 .NET安全类库,对称加密,公钥加密,数字签名,消息摘要,性能

     在信息安全的实际应用中,需要对计算机中大容量文件或数据进行加解密、数字签名以及完整性验证等工作。在VC等平台下实现的相关软件有很多,但是它们在处理大容量文件或数据时的执行效率成为应用的瓶颈。如何提高加解密程序执行的效率是本文研究和解决的重点。利用.NET基础类库在 system.security.cryptography命名空间下实现的诸多加密服务提供类很好的达到了此目的。
一、.NET安全类库
    常见的加解密、完整性验证以及数字签名算法都已经在.NET Framework中得到了实现,为编码提供了极大的便利性,实现这些算法的命名空间是system.security.cryptography。此命名空间按如下方式组织:
    1.对称加密。
   与公钥算法相比,对称加密算法非常快,特别适用于对较大的数据流执行加密。.NET Framework提供以下实现对称加密算法的类: ①DESCryptoServiceProvider;②RC2CryptoServiceProvider;③RijndaelManaged; ④TripleDESCryptoServiceProvider。
    2.公钥加密和数字签名。
    公钥加密算法也称为非对称算法,使用一个必须对未经授权的用户保密的私钥和一个可以对任何人公开的公钥。用公钥加密的数据只能用私钥解密,而用私钥签名的数据只能用公钥验证。公钥可以被任何人使用,该密钥用于加密要发送到私钥持有者的数据。两个密钥对于通信会话都是唯一的。.NET Framework提供以下实现公钥加密算法的类:①DSACryptoServiceProvider; ②RSACryptoServiceProvider。
    3.消息摘要。
    消息摘要也称Hash算法,能将任意长度的二进制值映射为固定长度的短二进制值(Hash值)。如果对一段明文哪怕只更改其中的一个字母,随后的Hash 值都将产生巨大的变化。要找到Hash值相同的两个不同的输入,在计算上是不可能的,所以数据的Hash值可以检验数据的完整性。.NET Framework提供以下实现数据完整性算法的类:①HMACSHA1;②MACTripleDES; ③MD5CryptoServiceProvider;④SHA1Managed、SHA256Managed、SHA384Managed、 SHA512Managed。
二、封装.NET安全类库
    由于.NET安全类库并没有直接提供加密文件的方法,而本文的重点是实现文件的加密,且考虑到编码的封装性原则,因此在.NET已有安全类库的基础上做进一步的封装,实现了一个多功能、高性能的文件加密系统,其中涉及了密码体系四个方面的技术:对称密码实现了DES和Rijndael算法,公钥密码实现了 RSA算法,数字签名实现了DSA签名方案,消息摘要实现了MD5和SHA-1算法。下面对封装的方法和各部分功能的实现逐一分析。
    1.对称密码
    (1)DES(Data Encryption Standard)
    .NET中DESCryptoServiceProvider类定义了访问DES算法的加密服务提供程序版本的包装对象, DESCryptoServiceProvider类的公共属性中有两个最重要的属性IV和Key。IV属性用于获取或设置对称算法的初始化向量,如果初始值为空,则调用GenerateIV方法创建新的随机值。Key属性用于获取或设置DES算法的密钥。如果此属性在使用时为空,则调用 GenerateKey方法创建新的随机值。
    DESCryptoServiceProvider类还有两个重要的公共方法:CreateEncryptor和CreateDecryptor。 CreateEncryptor方法用指定的Key和IV创建DES加密器对象,而CreateDecryptor方法则用指定的Key和IV创建DES 解密器对象。
    基于以上,封装成一个新类MyDES。类声明如下:
class MyDES
{
private string _sourceFile;     //需要加/解密文件的路径
private string _saveFile;     //加/解密后的文件保存路径
private byte[] _DESKey;     //DES的密钥,64位
private byte[] _DESIV;            //DES的初始化向量,64位,已指定
public MyDES(string sourcepath, string savepath, string key);   //类的构造函数
public void EncryptData();    //加密数据
public void DecryptData();    //解密数据
}
    自定义的MyDES类与.NET中DESCryptoServiceProvider类之间的主要关系如图1所示:

图1 MyDES类与DESCryptoServiceProvider类之间的主要关系
    为了简化加解密过程,用MyDES类中已给定值的成员_DESIV来取代原类库中DESCryptoServiceProvider类的IV属性;同时用 MyDES类中的_DESKey来取代DESCryptoServiceProvider类的key属性,以便于从用户界面获得密钥。
构造函数MyDES()负责根据用户界面上获取的信息,初始化需要加/解密文件的路径_sourceFile、加/解密后的文件保存路径_saveFile以及DES的密钥_DESKey。
    成员函数EncryptData()负责对指定的文件进行加密,主要步骤如下:
    根据从用户界面获取的_sourceFile和_saveFile,创建输入输出流
FileStream fin = new FileStream(_sourceFile, FileMode.Open, FileAccess.Read);
FileStream fout = new FileStream(_saveFile, FileMode.OpenOrCreate, FileAccess.Write);
创建DESCryptoServiceProvider类的对象
DES des = new DESCryptoServiceProvider();
    调用CreateEncryptor方法创建加密器对象,并将输入流套接成为加密流
CryptoStream encryptStream = new CryptoStream(fout, des.CreateEncryptor(_DESKey, _DESIV), CryptoStreamMode.Write);
按每200字节块进行加密
   byte[] readBuffer = new byte[200];
   len = fin.Read(readBuffer, 0, readBuffer.Length);
   encryptStream.Write(readBuffer, 0, len);
    清除所有敏感数据
    des.Clear();
    创建DESCryptoServiceProvider类的对象后,应该显式调用其clear方法。因为从安全的角度考虑,仅在使用完对象后强制垃圾回收是不够的。必须显式调用Clear方法,以便在释放对象之前将对象中所包含的所有敏感数据清零。以下封装类都会用到此方法。
    成员函数DecryptData()负责对指定的文件进行解密,其步骤与EncryptData类似。首先仍然是创建 DESCryptoServiceProvider类的对象,调用其CreateDecryptor方法创建DES解密器对象,再将输入流套接成为加密流,利用此加密流进行解密工作。
   (2)Rijndael(AES)
    .NET中RijndaelManaged类定义了访问Rijndael算法的托管版本,同DESCryptoServiceProvider类一样, RijndaelManaged类的公共属性中也有两个最重要的属性IV和Key,以及两个重要的方法:CreateEncryptor和 CreateDecryptor,它们的含义和DESCryptoServiceProvider类中的相同,不再赘述。基于以上,我们再封装一个类 MyRijndael。类声明如下:
class MyRijndael
{
private string _sourceFile=null;    //需要加/解密文件的路径
private string _saveFile=null;    //加/解密后的文件保存路径
private byte[] _RijndaelKey=null; //Rijndael的密钥,256位
      private byte[] _RijndaelIV= new byte[] { 166, 160, 56, 13, 136, 27, 144, 219, 162, 21, 60, 142, 182, 248, 1, 35 };//Rijndael的初始化向量,128位,已指定
public MyRijndael(string sourcepath, string savepath, string key); //类的构造函数
public void EncryptData(); //加密数据
public void DecryptData(); //解密数据
}
    同样是为了简化加解密过程,在程序中显式指定了Rijndael的初始化向量。
    DES和Rijndael都属于对称密码体制,只是基于的数学算法不相同。.NET基础类库中实现这两种算法的类结构也是极其相似的,因此我们自己封装的 MyDES和MyRijndael也具有相同的接口。有关MyRijndael类的成员方法EncrptData和DecrptData的实现流程和说明可以参考MyDES类,不再重复。
    2.公钥密码RSA算法
    .NET中RSACryptoServiceProvider类定义了访问RSA 算法以执行不对称加解密的服务提供程序版本的包装对象。对于加密应用而言,RSACryptoServiceProvider类有四个常用且比较重要的公共方法Encrypt、Decrypt和FromXmlString、ToXmlString。
Encrypt方法、Decrypt方法分别使用RSA算法对数据进行加、解密。
FromXmlString方法通过XML字符串中的密钥信息初始化RSA对象,此方法可用于使用指定的密钥文件初始化RSA对象。
ToXmlString方法创建并返回包含当前RSA对象的密钥的XML字符串,此方法可用于程序中生成随机RSA密钥对并保存到文件。
    基于以上,我们封装一个采用RSA公钥体制加密的类MyRSA。类声明如下:
public class MyRSA
{
    private string _sourceFile;     //需要加/解密文件的路径
    private string _saveFile;      //加/解密后的文件保存路径
    private RSACryptoServiceProvider _rsa; //RSA加密服务提供程序的实现
    public MyRSA();       //类的无参构造函数
    public MyRSA(string sourceFile, string saveFile, string keyfile) : this(); //类的构造函数
    public string Key{ get; }      //密钥对(公钥&私钥),提供只读访问器
    public string PublicKey{ get; }    //公钥,提供只读访问器
    private void SaveToFile(string filename, string s);   //将传入的字符串写入指定文件
    private string ReadFile(string filename);    //读取文件
    public void LoadKeyFromFile(string filename);   //载入密钥文件
    public void SaveKeyToFile();       //保存密钥到文件
//清理资源,对外提供使内部对象中所包含的所有敏感数据清零的方法
    public void Clear();
    public void EncryptData();       //使用公钥进行加密
    public void DecryptData();       //使用私钥进行解密
}
    自定义的MyRSA类与.NET中RSACryptoServiceProvider类之间的主要关系如图2所示:

图2 MyRSA类与RSACryptoServiceProvider类之间的主要关系
    无参构造函数的作用很简单,生成一个RSACryptoServiceProvider类的对象。
构造函数的另一个重载版本负责根据从界面上获取的信息初始化需要加/解密文件的路径、加/解密后的文件保存路径以及需要载入的密钥文件路径。
公开Key和PublicKey属性是为了便于生成随机密钥对,因此仅提供只读访问器。
LoadKeyFromFile封装了上文提到的FromXmlString方法,作用是从指定文件载入密钥。
SaveKeyToFile封装了上文提到的FromXmlString方法,作用是将生成的随机密钥对保存到文件。
Clear只是简单的封装了RSACryptoServiceProvider类的Clear方法,目的是为了在用MyRSA类的对象生成随机密钥后能有一个及时清除所有敏感数据的方法。
    EncryptData负责对指定的文件进行加密,主要步骤如下:
    根据从用户界面获取的_sourceFile和_saveFile,创建输入输出流
FileStream fin = new FileStream(_sourceFile, FileMode.Open, FileAccess.Read);
FileStream fout = new FileStream(_saveFile, FileMode.OpenOrCreate, FileAccess.Write);
按128字节分块读取文件,利用RSACryptoServiceProvider类的Encrypt()方法加密
byte[] readBuffer = new byte[128];
fin.Read(readBuffer, 0, readBuffer.Length);
byte[] encryptedBuffer = _rsa.Encrypt(readBuffer, true);
    其中_rsa为构造函数中生成的RSACryptoServiceProvider类的对象。
    清除所有敏感数据
_rsa.Clear();
    DecryptData负责解密数据,同EncryptData类似,首先仍然是从文件路径创建输入输出流,分块读取输入流,调用 RSACryptoServiceProvider的Decrypt方法解密,再将解密后的数据块写进输出流,最后调用Clear方法清楚内存中的敏感数据。
    3.数字签名DSA(Digital Signature Algorithm)算法
    .NET中DSACryptoServiceProvider类定义了访问DSA 算法以执行数字签名的服务提供程序版本的包装对象。DSACryptoServiceProvider类有四个常用的公共方法 FromXmlString、ToXmlString和SignData和SignData、VerifySignature。前两个方法同RSA中的同名方法,另两个方法说明如下:
SignData方法有三个重载,在本程序中需要输入参数是流的重载,这个重载计算指定输入流的Hash值并对其签名,生成Hash的算法采用的是DSA中默认的SHA-1。
    VerifySignature方法验证指定数据的DSA签名,接受文件的Hash值和需要验证的签名数据作为输入参数。
    基于以上,封装一个采用DSA签名方案的类MyDSA。类声明如下:
class MyDSA
{
    private string _path1; //需要签名的文件或者接受到的文件路径
    private string _path2; //签名文件的路径
    private DSACryptoServiceProvider _dsa;   //DSA服务提供程序的实现
    public MyDSA();        //类的构造函数
    public MyDSA(string path1, string path2, string keyfile): this();   //类的构造函数
public string Key{ get; }    //密钥对(公钥&私钥),提供只读访问器
    public string PublicKey{ get; } //公钥,提供只读访问器
    private void SaveToFile(string filename, string s);   //将传入的字符串写入指定文件
    private string ReadFile(string filename);    //读取文件
    public void LoadKeyFromFile(string filename);    //载入密钥文件
    public void SaveKeyToFile();       //保存密钥到文件
    //清理资源,对外提供使内部对象中所包含的所有敏感数据清零的方法
    public void Clear();
    public void SignData();        //签名文件
    public bool VerifySignature();      //验证签名
}
    自定义的MyDSA类与.NET中的DSACryptoServiceProvider类之间的主要关系如图3所示:

图3 MyDSA类与DSACryptoServiceProvider类之间的主要关系
    MyDSA类中的两个重载构造函数、LoadKeyFromFile方法、SaveKeyToFile方法和Clear方法的作用均与MyRSA中的类似,在此不再赘述。
    SignData方法负责对文件签名,具体步骤如下:
    根据从用户界面获得的_path1和_path2,创建输入输出流
FileStream originalFile = new FileStream(_path1, FileMode.Open, FileAccess.Read);
FileStream fout = new FileStream(_path2, FileMode.OpenOrCreate, FileAccess.Write);
利用DSACryptoServiceProvider类的SignData方法签名文件
     byte[] signedHashValue = _dsa.SignData(originalFile);
    其中_dsa为构造函数中生成的DSACryptoServiceProvider类的对象。
    清除所有敏感数据
_dsa.Clear();
    DSACryptoServiceProvider类的SignData方法存在一个接受流的重载,采用默认的SHA-1算法生成流的Hash值再将Hash值用私钥签名。最后,将签名结果写入输出流并调用clear方法清除内存中的敏感数据。
VerifySignature 方法负责验证签名,首先利用SHA1CryptoServiceProvider类的ComputeHash计算文件的哈希,接着调用 DSACryptoServiceProvider类的VerifySignature方法验证此数值与用公钥解密签名文件内容后的数值是否相等。
DSA 在计算Hash值时默认采用SHA-1算法。如果想自定义生成Hash的算法,可以采用System.Security.Cryptography命名空间下的DSASignatureFormatter类,此类中的SetHashAlgorithm方法可以指定DSA的Hash算法,然后再调用其 CreateSignature方法生成签名,下面给出代码片段:
//创建一个 DSACryptoServiceProvider类的对象
DSACryptoServiceProvider DSA = new DSACryptoServiceProvider();
//待签名的哈希值
byte[] Hash = {59,4,248,102,77,97,142,201,210,12,224,93,25};
//创建一个DSASignatureFormatter类的对象,接受一个 DSACryptoServiceProvider类的
//对象作为参数以传递密钥信息
DSASignatureFormatter DSAFormatter = new DSASignatureFormatter(DSA);
//设置哈希算法为SHA1
DSAFormatter.SetHashAlgorithm("SHA1");
//生成哈希值的签名并返回
byte[] SignedHash = DSAFormatter.CreateSignature(Hash);
    4.消息摘要
    .NET中的MD5CryptoServiceProvider和SHA1CryptoServiceProvider类分别定义了用MD5算法和SHA -1算法以计算数据的Hash值的包装对象。在这两个类中有一个共同的从HashAlgorithm类继承的方法ComputeHash,此方法有三个重载,用于在派生类中用特定的算法计算数据的Hash值,在这里我们使用传入参数是流的重载。
基于以上,封装一个集成MD5和SHA-1算法的类MessageDigest,此类为一个静态类。类声明如下:
static class MessageDigest
{
    //将输入的字节数组转换为16进制表示的字符串。
    private static string ArrayToHexString(byte[] array, bool uppercase);
    //计算文件的MD5值
    public static string ComputeFileMD5(string filePath);
    //计算文件的SHA-1值
    public static string ComputeFileSHA1(string filePath);
}
    ComputeFileMD5方法用于文件MD5值的计算,其主要步骤如下:
    根据接受的文件路径参数创建文件流
    FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
    创建MD5CryptoServiceProvider类的对象并调用ComputeHash方法计算哈希值
MD5 md5 = new MD5CryptoServiceProvider();
byte[] byteTemp = md5.ComputeHash(fs);
    清除所有敏感数据
md5.Clear();
ComputeFileSHA1方法用于文件SHA1值的计算,其步骤同ComputeFileMD5类似,不同之处在于创建的是SHA1CryptoServiceProvider类的对象。

.NET与安全性――数据加密算法

目前企业面临的计算环境和过去有很大的变化,许多数据资源能够依靠网络来远程存取,而且越来越多的通讯依赖于公共网络公共网络(如 Internet),而这些环境并不保证实体间的安全通信,数据在传输过程可能被其它人读取或篡改。

加密将防止数据被查看或修改,并在原本不安全的信道上提供安全的通信信道,它达到以下目的:

  • 保密性:防止用户的标识或数据被读取。
  • 数据完整性:防止数据被更改。
  • 身份验证:确保数据发自特定的一方。

一、数据加密/编码算法列表

常见用于保证安全的加密或编码算法如下:

1、常用密钥算法

密钥算法用来对敏感数据、摘要、签名等信息进行加密,常用的密钥算法包括:

  • DES(Data Encryption Standard):数据加密标准,速度较快,适用于加密大量数据的场合;
  • 3DES(Triple DES):是基于DES,对一块数据用三个不同的密钥进行三次加密,强度更高;
  • RC2和 RC4:用变长密钥对大量数据进行加密,比 DES 快;
  • IDEA(International Data Encryption Algorithm)国际数据加密算法,使用 128 位密钥提供非常强的安全性;
  • RSA:由 RSA 公司发明,是一个支持变长密钥的公共密钥算法,需要加密的文件快的长度也是可变的;
  • DSA(Digital Signature Algorithm):数字签名算法,是一种标准的 DSS(数字签名标准);
  • AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前 AES 标准的一个实现是 Rijndael 算法;
  • BLOWFISH,它使用变长的密钥,长度可达448位,运行速度很快;
  • 其它算法,如ElGamal、Deffie-Hellman、新型椭圆曲线算法ECC等。

2、单向散列算法

单向散列函数一般用于产生消息摘要,密钥加密等,常见的有:

  • MD5(Message Digest Algorithm 5):是RSA数据安全公司开发的一种单向散列算法,MD5被广泛使用,可以用来把不同长度的数据块进行暗码运算成一个128位的数值;
  • SHA(Secure Hash Algorithm)这是一种较新的散列算法,可以对任意长度的数据运算生成一个160位的数值;
  • MAC(Message Authentication Code):消息认证代码,是一种使用密钥的单向函数,可以用它们在系统上或用户之间认证文件或消息。HMAC(用于消息认证的密钥散列法)就是这种函数的一个例子。
  • CRC(Cyclic Redundancy Check):循环冗余校验码,CRC校验由于实现简单,检错能力强,被广泛使用在各种数据校验应用中。占用系统资源少,用软硬件均能实现,是进行数据传 输差错检测地一种很好的手段(CRC 并不是严格意义上的散列算法,但它的作用与散列算法大致相同,所以归于此类)。

3、其它数据算法

其它数据算法包括一些常用编码算法及其与明文(ASCII、Unicode 等)转换等,如 Base 64Quoted PrintableEBCDIC 等。

二、算法的 .NET 实现

常见的加密和编码算法都已经在 .NET Framework中得到了实现,为编码人员提供了极大的便利性,实现这些算法的名称空间是:System.Security.Cryptography。

System.Security.Cryptography 命名空间提供加密服务,包括安全的数据编码和解码,以及许多其他操作,例如散列法、随机数字生成和消息身份验证。

System.Security.Cryptography 是按如下方式组织的:

1、私钥加密

私钥加密又称为对称加密,因为同一密钥既用于加密又用于解密。私钥加密算法非常快(与公钥算法相比),特别适用于对较大的数据流执行加密转换。

.NET Framework 提供以下实现私钥加密算法的类:

  • DES:DESCryptoServiceProvider
  • RC2:RC2CryptoServiceProvider
  • Rijndael(AES):RijndaelManaged
  • 3DES:TripleDESCryptoServiceProvider

2、公钥加密和数字签名

公钥加密使用一个必须对未经授权的用户保密的私钥和一个可以对任何人公开的公钥。用公钥加密的数据只能用私钥解密,而用私钥签名的数据只能用公钥验证。公钥可以被任何人使用;该密钥用于加密要发送到私钥持有者的数据。两个密钥对于通信会话都是唯一的。公钥加密算法也称为不对称算法,原因是需要用一个密钥加密数据而需要用另一个密钥来解密数据。

.NET Framework 提供以下实现公钥加密算法的类:

  • DSADSACryptoServiceProvider
  • RSA:RSACryptoServiceProvider

3、哈希(Hash)值

哈希算法将任意长度的二进制值映射为固定长度的较小二进制值,这个小的二进制值称为哈希值。哈希值是一 段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的 输入,在计算上是不可能的,所以数据的哈希值可以检验数据的完整性。

.NET Framework 提供以下实现数字签名算法的类:

  • HMAC:HMACSHA1 (HMAC 为一种使用密钥的 Hash 算法)
  • MAC:MACTripleDES
  • MD5:MD5CryptoServiceProvider
  • SHA1:SHA1Managed、SHA256Managed、SHA384Managed、SHA512Managed

4、随机数生成

加密密钥需要尽可能地随机,以便使生成的密钥很难再现,所以随机数生成是许多加密操作不可分割的组成部分。

在 .NET Framework 中,RNGCryptoServiceProvider 是随机数生成器算法的实现,对于数据算法,.NET Framework 则在其它命名空间中实现,如 Convert 类实现 Base 64 编码,System.Text 来实现编码方式的转换等。

从以上来看,.NET Framework 对于数据加密/编码还是支持比较好,大大地方便了开发人员,但美中不足的是,.NET Framework 中的数据加密算法仍然不够完全,如 IDEA、BLOWFISH、其它算法,如ElGamal、Deffie-Hellman、ECC 等,对于一些其它的数据校验算法支持也不够,如 CRC、SFV 等,开发人员只能去从早期代码做移植或者寻找第三方厂商的实现。

VB.NET编程实例-如何创建多文档窗体

额,话说学了语言总是不知道怎么去实现具体的东东,昨天在图书馆看到一本实例书,感觉还行.
下面就是按照书上的步骤做的,有些东西看起来挺难得,真做起来其实也挺简单的.
如何创建多文档窗体(VS2005)
1.创建一个VB.NET Windows应用程序框架.form1.vb
2.添加一个Windows窗体.form2.vb
3.在form2.vb设计窗体上拖放一个RichTextBox控件(RichTextBox1),dock属性为fill.
4.在form1.vb的设计视图中设置IsMidContainer属性为True.(这个属性表示Form1是一个多文档窗体子窗体的容器,这样就可以以此为基础创建一个多文档窗体程序了,这也是次实力程序的关键.)
5.在form1.vb的设计窗体上拖放一个OpenFileDialog空间(OpenFileDialog1),将Filter属性设置为"所有文本文件(*.txt)|*.txt".
6.在form1.vb的设计窗体上拖放一个MenuStrip控件(MenuStrip1).按下图添加主菜单和子菜单项:

7.为控件的子菜单项"打开(O)","活动窗口(A)","退出(E)"…等鼠标单击事件添加如下代码:
    ‘打开文件
    Private Sub menuOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuOpen.Click
        If Me.OpenFileDialog1.ShowDialog = DialogResult.OK Then
            Dim MyFileName As String = Me.OpenFileDialog1.FileName
            Dim MyForm As New Form2
            MyForm.MdiParent = Me
            MyForm.RichTextBox1.LoadFile(MyFileName, RichTextBoxStreamType.PlainText)
            MyForm.Text = MyFileName
            MyForm.Show()
        End If
    End Sub
    ‘活动窗口
    Private Sub menuActive_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuActive.Click
        Try
            MsgBox("当前活动窗口是:" + Me.ActiveMdiChild.Text, MsgBoxStyle.DefaultButton1, "信息提示")
        Catch ex As Exception
            MsgBox("当前没有活动窗口", MsgBoxStyle.DefaultButton1, "信息提示")
        End Try
    End Sub
    ‘关闭程序
    Private Sub menuExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuExit.Click
        Me.Close()
    End Sub
    ‘层叠窗口
    Private Sub menuC_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuC.Click
        Me.LayoutMdi(MdiLayout.Cascade)
    End Sub
    ‘水平平铺窗口
    Private Sub muneH_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles muneH.Click
        Me.LayoutMdi(MdiLayout.TileHorizontal)
    End Sub
    ‘垂直平铺窗口
    Private Sub menuV_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuV.Click
        Me.LayoutMdi(MdiLayout.TileVertical)
    End Sub
最后编译程序即可.
运行截图:

源码下载地址(运行测试环境:VS2005):下载文件 点击下载此文件