加密解密概述及.NET中对加密解密的支持(二)

.NET中加密解密的支持

相信通过前面几页的叙述,大家已经明白了加密解密、数字签名的基本原理,下面我们看一下在.NET中是如何来支持加密解密的。正如上面我们所进行的分类,.NET中也提供了两组类用于加密解密,一组为对称加密,一组为非对称加密。这些类按照名称还可以分为两组,一组后缀为“CryptoServiceProvider”的,是对于底层Windows API的包装类,一组后缀为“Managed”,是在.NET中全新编写的类。

.NET对称加密解密支持

.NET Framework提供了一些常见的对称算法的实现,包括DES、RC2等。下面列出了与对称算法有关的类的结构:

System.Security.Cryptography.SymmetricAlgorithm

System.Security.Cryptography.Aes
System.Security.Cryptography.AesCryptoServiceProvider
System.Security.Cryptography.AesManaged
System.Security.Cryptography.DES

System.Security.Cryptography.DESCryptoServiceProvider
System.Security.Cryptography.RC2

System.Security.Cryptography.RC2CryptoServiceProvider
System.Security.Cryptography.Rijndael

System.Security.Cryptography.RijndaelManaged
System.Security.Cryptography.TripleDES

System.Security.Cryptography.TripleDESCryptoServiceProvider

这些类中黑体表示的类为实现算法的具体类,其它的都是抽象类;也可以根据需要实现自己的对称算法。

.NET非对称加密解密支持

RSA是当今最常用的非对称算法,其被应用于很多领域。RSA算法的理论依据来自于一个大素数所具有的特性:对于给定的两个大素数A与B,很容易计算出它们的乘积;但是,仅知道AB的成绩却很难计算原来的A与B各自的值。

.NET Frameork提供了两个类供我们使用RSA算法:用于加密数据的RSACryptoServiceProvider类以及用于对数据做数字签名的DSACryptoServiceProvider类(DSA: Digital Signature Algorithm,数字签名算法),其类的层次结构如下

System.Security.Cryptography.AsymmetricAlgorithm
System.Security.Cryptography.DSA

System.Security.Cryptography.DSACryptoServiceProvider
System.Security.Cryptography.RSA

System.Security.Cryptography.RSACryptoServiceProvider

System.Security.Cryptography.ECDiffieHellman(椭圆曲线Diffie-Hellman (ECDH) 算法实现)

System.Security.Cryptography.ECDiffieHellmanCng(椭圆曲线Diffie-Hellman (ECDH) 算法的下一代加密技术 (CNG) 实现)
System.Security.Cryptography.ECDsa

System.Security.Cryptography.ECDsaCng(椭圆曲线数字签名算法 (ECDSA) 的下一代加密技术 (CNG) 实现)

.NET散列算法支持

散列算法是把长长的一列数据变成较短的代码,这是最流行的64位散列密钥。两个最流行的散列算法是SHA(Secured Hash Algorithm)和MD5(MessageDigest version5)。这些散列密钥用于标记数字文档。

散列值是根据一个数据集合计算出来的数字。如果数据集合不同,那么计算出来的数字基本上也是不同的。.NET Framework在其System.Security.Cryptography命名空间下提供了一些主要的散列算法,包括:SHAx、RIPEMD160、与MD5。

System.Security.Cryptography.HashAlgorithm

System.Security.Cryptography.KeyedHashAlgorithm(键控哈希算法的实现基类)

System.Security.Cryptography.HMAC (基于哈希的消息验证代码 (HMAC)的抽象类)

System.Security.Cryptography.HMACMD5

System.Security.Cryptography.HMACRIPEMD160

System.Security.Cryptography.HMACSHA1

System.Security.Cryptography.HMACSHA256

System.Security.Cryptography.HMACSHA384

System.Security.Cryptography.HMACSHA512

System.Security.Cryptography.MACTripleDES
System.Security.Cryptography.MD5

System.Security.Cryptography.MD5Cng(128 位哈希算法的 CNG(下一代加密技术)实现

System.Security.Cryptography.MD5CryptoServiceProvider

System.Security.Cryptography.RIPEMD160

System.Security.Cryptography.RIPEMD160Managed

System.Security.Cryptography.SHA1

System.Security.Cryptography.SHA1CryptoServiceProvider
System.Security.Cryptography.SHA1Managed

System.Security.Cryptography.SHA256

System.Security.Cryptography.SHA256Managed

System.Security.Cryptography.SHA384

System.Security.Cryptography.SHA384Managed

System.Security.Cryptography.SHA512

System.Security.Cryptography.SHA512Managed

KeyedHash

键控哈希算法是依赖于密钥的单向哈希函数,用作消息验证代码。只有知道密钥的人才能验证哈希值。加密哈希算法提供没有机密的真实性。

SHA

SHA(安全散列算法)是一个块密码,在64位的数据块上执行,这个算法的改进版本采用了更大的密钥值,当然,密钥值越大所需的计算时间越长。而且,对于相对较小的文件,散列值越小就越安全,就是说,散列算法的块大小应小于或等于数据块本身的大小。 SHA1算法的散列范围是160位。

.NET Framework也提供了更大的密钥值算法,分别为SHA256、SHA384和SHA512。名称最后的数字表示其块大小。

ASP.NET安全性中的成员资格提供程序使用SHA1加密用户密码。

MD5

MD5表示MessageDigest版本5。它是一个加密的单向散列算法。MD5有抗伪造,计算成本低且执行简单等特点。现在MD5已成为散列算法的事实标准。

.NET Framework提供了MD5CryptoServiceProvider这个类实现MD5算法。该类与SHA1共享同一个基类,前面的示例也只需要做简单的改动即可成为使用MD5进行处理的例子。

RIPEMD-160

基于MD5的RIPEMD-160最早出现于欧洲,是一个使用160位的散列算法。.NET也引入了对这种算法的支持。

对称加密解密示例

现在假设我们以TripleDES作为算法,那么加密的流程如下:

1. 先创建一个TripleDESCryptoServiceProvider的实例,实例名比如叫provider。

2.在provider上指定密钥和IV,也就是它的Key属性和IV属性。这里简单解释一下IV(initialization vector),如果一个字符串(或者数据)加密之前很多部分是重复的比如ABCABCABC,那么加密之后尽管字符串是乱码,但相关部分也是重复的。为了解决这个问题,就引入了IV,当使用它以后,加密之后即使是重复的也被打乱了。对于特定算法,密钥和IV的值可以随意指定,但长度是固定,通常密钥为128位或196位,IV为64位。密钥和IV都是byte[]类型,因此,如果使用Encoding类来将字符串转换为byte[],那么编码方式就很重要,因为UTF8是变长编码,所以对于中文和英文,需要特别注意byte[]的长度问题。

3.如果是加密,在provider上调用CreateEncryptor()方法,创建一个ICryptoTransform类型的加密器对象;如果是解密,在provider上调用CreateDecryptor()方法,同样是创建一个ICryptoTransform类型的解密器对象。ICryptoTransform定义了加密转换的运算,.NET将在底层调用这个接口。

4.因为流和byte[]是数据类型无关的一种数据结构,可以保存和传输任何形式的数据,区别只是byte[]是一个静态的概念而流是一个动态的概念。因此,.NET采用了流的方式进行加密和解密,我们可以想到有两个流,一个是明文流,含有加密前的数据;一个是密文流,含有加密后的数据。那么就必然有一个中介者,将明文流转换为密文流;或者将密文流转换为明文流。.NET中执行这个操作的中介者也是一个流类型,叫做CryptoStream。它的构造函数如下,共有三个参数:

publicCryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode)

5. 当加密时,stream为密文流(注意此时密文流还没有包含数据,仅仅是一个空流);ICryptoTransform是第3步创建的加密器,包含着加密的算法;CryptoStreamMode枚举为Write,意思是将流经CryptoStream的明文流写入到密文流中。最后,从密文流中获得加密后的数据。

6. 当解密时,stream为密文流(此时密文流含有数据);ICryptoTransform是第3步创建的解密器,包含着解密的算法;CryptoStreamMode枚举为Read,意思是将密文流中的数据读出到byte[]数组中,进而再由byte[]转换为明文流、明文字符串。

可见,CryptoStream总是接受密文流,并且根据CryptoStreamMode枚举的值来决定是将明文流写入到密文流(加密),还是将密文流读入到明文流中(解密)。下面是我编写的一个加密解密的Helper类:


非对称加密解密示例

如果对文件的安全性要求不是很严格,只是控制文件在传输中的完整性,可以用散列算法算出一个文件的散列,然后用非对称算法加密并把加密后的信息附加于文件中,接收方使用收到的文件中的散列验证文件的完整性,同时也能确认文件的发送者,即实现了简单的文件签名的功能。

下面示例演示了如何使用RSACryptoServiceProvider类加密一个字符串。其中,ExpertParameter(bool)方法根据参数的真假允许获得公钥/私钥对(true)或只有公钥(false)。


哈希计算示例

以下以MD5算法计算哈希值为例,给出简单示例。


你可能感兴趣的:(.net)