| 密码的故事 2002 年 3 月 14 日 本文是由一个问题引出的。我需要一种将密码保存在加密文件中的方法,因为我需要记住许多密码,但记忆力却已大不如前。我知道有许多商用工具能够做到这一点,但我感到学习 .net 中的一项新技术真的很有好处。 理解流
流是 .net 中处理字节的基本概念。下面简单介绍一下其工作原理。 后端流
后端流从某个可以保存字节的位置获取字节或将字节存储到该位置。文件流就是一种后端流。文件流使用文件作为字节的后端存储,并读取或写入该文件。 过程流
过程流用于接收并处理字节,然后将字节写入其他流(通常是后端流)。例如,我们可以从名为 stream 的 .net 基类中继承,然后创建一个将大写字母更改为小写字母的过程流。再将这个流附加到任何后端流。现在,上图的关系可以表示为图 2。 .net 中的加密在 .net 中,加密和解密是使用过程流来实现的。例如,加密的典型步骤为:
加密流被封装到一个名为 cryptostream 的类(本文后面将详细介绍该类)。假设我们正在读取和写入磁盘文件,那么如果使用这一术语,则此过程的关系如图 3 所示。 加密类型
加密信息的方法已经有几百年的历史。小说家艾伦·坡就曾经涉足密码学,而设计和破解密码也曾经是第二次世界大战中的一项重要活动。然而,计算机的出现使密码学有了飞速发展。计算机强大的分析加密消息的能力迫使人们不断研究越来越难以破解的加密技术。
加密算法的一般类型有对称和非对称两种。对称算法使用相同的密钥来加密和解密数据。非对称算法使用一个公钥进行加密,而使用另一个密钥来解密。在本文最后,我们将继续介绍这一点。
有许多 web 站点讨论了以上因素。对于初学者,以下两个网站比较适合:http://www.microsoft.com/china/security/ 和 snake oil faq http://www.interhack.net/people/cmcurtin/snake-oil-faq.html(英文)。 使用 .net 加密类本表列出的 .net 类都在 system.security.cryptography 命名空间中,因此使用它们时必须引用 system.security.dll。此外,使用一对 imports 语句来引用命名空间会使代码更加简洁: imports system.securityimports system.security.cryptography
上表中的类都和一个名为 cryptostream 的一般密码流类一起工作。这样便可以仅使用一个能实现多种加密的类来处理流操作。您甚至可以创建自己的加密类并将其插入 cryptostream 中(尽管其安全性不太可能与上表列出的类相比)。 创建密钥
如果使用随机密钥,则对称加密算法最安全。所以,生成密钥的最好方法是使用随机过程来获得所需的 8 个字节。但是,8 个随机字节并不容易记住。在下面的示例中,我们使用“密码”来生成密钥。简单地说,密码是一个 8 字符的字符串,使用字符的 ascii 值来初始化构成密钥的字节数组。 加密/解密程序
我们已经介绍了相关概念,现在可以开始创建加密和解密文件的程序了。我们将其设计为一个 windows 窗体应用程序。
将各个文本框的 text 属性设置为空。将状态栏命名为 sbencryptionstatus。 dim bytekey() as bytebytekey = getkeybytearray(txtkeypassword.text)dim byteinitializationvector() as bytebyteinitializationvector = getkeybytearray(txtivpassword.text)encryptordecryptfile(txtunencryptedfile.text, _ txtencryptedfile.text, _ bytekey, byteinitializationvector, _ cryptoaction.actionencrypt) 为 btndecrypt 按钮添加以下代码: dim bytekey() as bytebytekey = getkeybytearray(txtkeypassword.text)dim byteinitializationvector() as bytebyteinitializationvector = getkeybytearray(txtivpassword.text)encryptordecryptfile(txtencryptedfile.text, _ txtunencryptedfile.text, _ bytekey, byteinitializationvector, _ cryptoaction.actiondecrypt)
您会注意到这两个按钮相关的代码很类似。它们使用相同的函数获取密钥和初始化向量的数组,并使用相同的函数(名为 encryptordecryptfile)加密或解密文件。使用 encryptordecryptfile 时的唯一区别是文本框中输入和输出文件的文件名正好相反,并且动作(加密或解密)不同。 private enum cryptoaction actionencrypt = 1 actiondecrypt = 2end enum 还需要在模块顶部添加语句,以便轻松地引用密码类和流类。以下是所需的代码行: imports system.security.cryptographyimports system.securityimports system.io 到目前为止,代码都比较简单。现在我们看看怎样生成密钥。下面是一个将密码变成字节数组的函数,应当将它添加到窗体代码中: private function getkeybytearray(byval spassword as string) as byte() dim bytetemp(7) as byte spassword = spassword.padright(8) 确保是 8 个字符 dim icharindex as integer for icharindex = 0 to 7 bytetemp(icharindex) = asc(mid$(spassword, icharindex + 1, 1)) next return bytetempend function
这也是一段很直观的代码。visual basic 6.0 开发人员应当注意对字符串的 padright 方法(取代 visual basic 6.0 中的等效字符串处理代码)的使用,以确保长度正确。 private sub encryptordecryptfile(byval sinputfile as string, _ byval soutputfile as string, _ byval bytedeskey() as byte, _ byval bytedesiv() as byte, _ byval direction as cryptoaction) 创建处理输入和输出文件的文件流。 dim fsinput as new filestream(sinputfile, _ filemode.open, fileaccess.read) dim fsoutput as new filestream(soutputfile, _ filemode.openorcreate, fileaccess.write) fsoutput.setlength(0) 加密/解密过程中需要的变量 dim bytebuffer(4096) as byte 保存字节块以进行处理 dim nbytesprocessed as long = 0 运行对加密字节的计数 dim nfilelength as long = fsinput.length dim ibytesincurrentblock as integer dim desprovider as new descryptoserviceprovider() dim csmycryptostream as cryptostream dim sdirection as string 设置为加密或解密 select case direction case cryptoaction.actionencrypt csmycryptostream = new cryptostream(fsoutput, _ desprovider.createencryptor(bytedeskey, bytedesiv), _ cryptostreammode.write) sdirection = "加密" case cryptoaction.actiondecrypt csmycryptostream = new cryptostream(fsoutput, _ desprovider.createdecryptor(bytedeskey, bytedesiv), _ cryptostreammode.write) sdirection = "解密" end select sbencryptionstatus.text = sdirection + "正在启动..." 从输入文件读取,然后加密或解密 并写入输出文件。 while nbytesprocessed < nfilelength ibytesincurrentblock = fsinput.read(bytebuffer, 0, 4096) csmycryptostream.write(bytebuffer, 0, ibytesincurrentblock) nbytesprocessed = nbytesprocessed + clng(ibytesincurrentblock) sbencryptionstatus.text = sdirection + _ "正在处理 - 已处理字节数 - " + _ nbytesprocessed.tostring end while sbencryptionstatus.text = "完成" + sdirection + _ "。处理的字节总数 - " + nbytesprocessed.tostring csmycryptostream.close() fsinput.close() fsoutput.close()end sub
现在我们具体说明以上代码。
接下来的一段是 select case,根据我们执行该函数所要完成的操作来设置为加密或解密。descryptoserviceprovider 可以分别使用 createencryptor 或 createdecryptor 方法创建加密器或解密器。这用于实例化我们要使用的 cryptostream 对象,并命名为 csmycryptostream。csmycryptostream 对象还需要知道使用哪个流进行输出。为此,在实例化 csmycryptostream 过程中,加密和解密都指定 fsoutput 流。 总结
如上所述,des 算法只是一种选择。而最灵活的选择之一是使用公钥加密系统,也称为非对称加密。在这种技术中,加密和解密使用不同的密钥。加密密钥是公开的,而解密密钥则是保密的,只有需要执行解密的人才知道。人人都可以使用加密密钥进行加密,但只能使用解密密钥进行解密。 |
密码的故事 (st:ms,author:billy hollis )-.net教程,算法/线
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 密码的故事 (st:ms,author:billy hollis )-.net教程,算法/线
相关推荐
- 暂无文章




