【CSharp】加密数据

机密数据应得到保护,从而使未授权的用户不能读取它们。这对于在网络中发送的数据或存储的数据都有效。可以用对称或不对称密钥来加密这些数据。

通过对称密钥,可以使用同一个密钥进行加密和解密。与不对称的加密相比,加密和解密使用不同的密钥:公钥/私钥。如果使用一个公钥进行加密,就应使用对应的私钥进行解密,而不是使用公钥解密。同样,如果使用一个私钥加密,就应使用对应的公钥解密,而不是使用私钥解密。不可能从私钥中计算出公钥,也不可能从公钥中计算出私钥

公钥/私钥总是成对创建。公钥可以由任何人使用,它甚至可以放在Web站点上,但私钥必须安全地加锁。为了说明加密过程,下面看看使用公钥和私钥的例子。

如果Alice给Bob发了一封电子邮件,并且Alice希望能保证除了Bob外,其他人都不能阅读该邮件,所以她就使用Bob的公钥。邮件是使用Bob的公钥加密的。Bob打开该邮件,并使用他秘密存储的私钥解密。这种方式可以保证除了Bob外,其他人都不能阅读Alice的邮件。

但这还有一个问题:Bob不能确保邮件是Alice发送来的。Eve也可以使用Bob的公钥加密发送给Bob的邮件并假装是Alice。我们使用公钥/私钥把这条规则扩展一下。下面再次从Alice给Bob发送电子邮件开始。在Alice使用Bob的公钥加密邮件之前,她添加了自己的签名,再使用自己的私钥加密该签名。然后使用Bob的公钥加密邮件。这样就保证了除Bob外,其他人都不能阅读该邮件。在Bob解密邮件时,他检测到一个加密的签名该签名是Alice使用她的私钥加密的。这个签名可以使用Alice的公钥来解密。而Bob可以访问Alice的公钥,因为这个密钥是公钥。在解密了签名后,Bob就可以确定是Alice发送了电子邮件。

使用对称密钥的加密和解密算法比使用非对称密钥的算法快得多。对称密钥的问题是密钥必须以安全的方式互换。在网络通信中,一种方式是先使用非对称的密钥进行密钥互换,再使用对称密钥加密通过网络发送的数据。

在.NET Framework中,可以使用System.Security.Cryptography名称空间中的类来加密。它实现了几个对称算法和非对称算法。有几个不同的算法类用于不同的目的。一些类以Cng作为前缀或后缀。CNG是Cryptography Next Generation的简称,是本机Crypto API的更新版本,这个API可以使用基于提供程序的模型,编写独立于算法的程序。

下表列出了System.Security.Cryptography名称空间中的加密类及其功能。

  • 没有Cng、ManagedCryptoServiceProvider后缀的类是抽象基类,如MD5
  • Managed 后缀表示这个算法用托管代码实现,其他类可能封装了本地Windows API调用
  • CryptoServiceProvider 后缀用于实现了抽象基类的类
  • Cng后缀用于利用新Cryptography CNG API的类
类别说 明
散列MD5
MD5Cng

SHA1
SHA1Managed
SHA1Cng

SHA256
SHA256Managed
SHA256Cng

SHA384
SHA384Managed
SHA384Cng

ShA512
SHA512Managed
SHA512Cng

RIPEMD160
RIPEMD160Managed
散列算法的目标是从任意长度的二进制字符串中创建一个长度固定的散列值。

这些算法和数字签名一起用于保证数据的完整性。

如果再次散列相同的二进制字符串,会返回相同的散列结果。

MD5(Message Digest Algorithm 5, 消息摘要算法5)由RSA实验室开发,比SHA1快。SHA1在抵御暴力攻击方面比较强大。SHA算法由美国国家安全局(NSA)设计。

MD5使用128位的散列长度,
SHA1使用160位。
其他SHA算法在其名称中包含了散列长度。

SHA512是这些算法中最强大的,其散列长度为512位,它也是最慢的。

RIPEMD160使用160位的散列长度,替代了128位的MD4和MD5.
对称DES
DESCryptoServiceProvider

TripleDES
TripleDESCryptoServiceProvider

Aes
AesCryptoServiceProvider
AesManaged

RC2
RC2CtyptoServiceProvider

Rijandel
RijandelManaged
对称密钥算法使用相同的密钥进行数据的加密和解密。

现在认为DES(Data Encryption Standard, 数据加密标准)是不安全的,因为它只使用56位的密钥长度,可以在不超过24小时的时间内破解。

Triple-DES是DES的继承者,其密钥长度是168位,但它提供的有效安全性只有112位。

AES(Advanced Encryption Standard,高级加密标准)的密钥长度128、192或256位。

Rijandel非常类似于AES,它只是在密钥长度方面的选项角度。AES是美国政府采用的加密标准
非对称DSA
DSACryptoServiceProvider

ECDsa
ECDsaCng

ECDiffieHellman
ECDiffieHellmanCng

RSA
RSACryptoServiceProvider
RSACng
非对称算法使用不同的密钥进行加密和解密

RSA(Rivest, Shamir, Adleman)是第一个用于签名和加密的算法。这个算法广泛用于电子商务协议。

RSACng是.NET4.6和.NET 5 Core的一个新类,基于Cryptography Next Generation(CNG)实现方式。DSA(Digital Signature Algorithm,数字签名算法)是用与数据签名的一个美国联邦政府标准。

ECDSA(Elliptic Curve DAS,椭圆曲线数字签名算法)和EC Diffie-Hellman使用基于椭圆权限组的算法。这些算法比较安全,且使用较短的密钥长度。

例如,DSA的密钥长度位1024位,其安全性类似于ECDSA的160位。因此,ECDSA比较快。EC Diffie-Hellman算法用于以安全的方式在公共信道中交换私钥

加密基元

加密用于实现以下目标:

  • 保密性:有助于防止用户的身份或数据被读取
  • 数据完整性:有助于防止数据被更改
  • 身份验证:确保数据来自于特定方
  • 不可否认性:防止特定方否认其发送过信息

若要实现这些目标,可以使用称为加密基元惯例的组合来创建加密方案。下表列出了加密基元以及其用途。

加密基元用途
私钥加密(对称加密)在数据上执行转换,以防止其被第三方读取。此类型的加密使用单个共享的密钥来加密和解密数据
公钥加密(非对称加密)在数据上执行转换,以防止其被第三方读取。此类型的加密使用公钥/私钥来对数据进行加密和解密数据
加密签名通过创建特定于参与方的数字签名,帮助验证数据是否来自此特定方。此流程也使用哈希函数
加密哈希任意长度的数据映射到固定长度的字节序列。哈希值在统计上是唯一的;不同的双字节序列不会由哈希处理为同一个值

私钥加密

私钥加密算法使用单个密钥来加密和解密数据。必须确保密钥不被未经授权的代理访问,因为具有此密钥的任意方均可使用此密钥解密你的数据或者加密自己的数据,而声称此数据来自于你。

私钥加密也称为对称加密,因为加密和解密所用的密码相同。私钥加密i算法非常迅速,也非常适合在大型数据流上执行加密转换。非对称加密从数学上来说在可加密的数据量方面存在限制。对称加密算法通常没有这些问题。

一种名为分组加密的私钥算法用于一次加密一个数据块。分组加密(例如数据加密标准(DES)、TripleDES和高级加密标准(AES))可将n个字节的输入块通过加密转换为由加密字节构成的输出块。如果想要加密或解密字节序列,则必须逐块执行。由于n很小(DES和TripleDES为8字节;AES为16字节[默认值]、24字节或32字节),所以对于大于n的数据值,必须一次加密一个数据块。小于n的数据值则必须扩展为n才能进行处理。

分组加密的一种简单形式被称为电子密码本(ECB)模式。ECB模式被视为不安全,因为它不使用初始化向量来初始化第一个纯文本块。对于给定的私钥k,不使用初始化向量的简单分组加密会见相同的纯文本输入块加密为相同的已加密文本的输出块。因此,如果输入的纯文本流中存在重复的块,则输出密码文本流中也会有重复的块。 这些重复的输出块会警告未经授权的用户使用了可能被采用的算法访问不可靠的加密以及可能的攻击模式。 因此,ECB 密码模式非常易于分析,最终导致密钥易于被发现。

基类库中提供的分组加密类使用称为加密块链接 (CBC)的默认链接模式,但可随意更改此默认设置。

通过使用初始化向量 (IV)加密第一个纯文本块,CBC 密码克服了与 ECB 密码关联的问题。 每个后续纯文本块在加密之前,都将与之前的密码文本块进行位异或 (XOR) 运算。 因此,每个密码文本块均依赖于之前所有的块。 使用此系统时,可能已为未经授权的用户所知的常见消息头不可用来对密钥进行反向工程处理。

一种泄露以 CBC 密码加密的数据的方式是对每个可能的密钥执行详尽搜索。 具体取决于用来执行加密的密钥大小,这种搜索即使是使用最快的计算机也非常耗时,因此不可行。 密钥大小更大,解密更难。 虽然从理论上来说,加密并未使攻击者检索加密数据变得不可能,但它确实增加了执行此操作的成本。 如果花费三个月的时间执行详尽搜索来检索仅在几天之内有意义的数据,则详尽搜索方法不切实际。

密钥加密的缺点是它假定双方已商定密钥IV,并互相传达了密钥和 IV 的值。 IV 不被视为机密,并可以以纯文本的形式通过消息传输。 但是,密钥必须对未经授权的用户保密。 由于存在这些问题,密钥加密通常与公钥加密一起使用,以秘密地传达密钥和 IV 的值。

假定 Alice 和 Bob 是想通过非安全通道进行通信的双方,则他们可能按如下所示使用密钥加密:Alice 和 Bob 同意使用某种具有特定密钥和 IV 的特定算法(例如 AES)。 Alice 撰写一条消息,并创建要在其上发送消息的网络流。 接下来,她使用密钥和 IV 对文本进行加密,然后通过 intranet 向 Bob 发送加密的消息和 IV。 Bob 收到加密文本并使用 IV 和之前商定的密钥对其进行解密。 如果传输被截获,侦听器无法恢复原始消息,因为它们不知道密钥。 在此方案中,只有密钥必须保持机密。 在实际方案中,Alice 和 Bob 都可以生成密钥并使用公钥(非对称)加密将密钥(对称)传递给另一方。

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

  • AesManaged
  • DESCryptoServiceProvider
  • HMACSHA1
  • RC2CryptoServiceProvider.
  • RijndaelManaged.
  • TripleDESCryptoServiceProvider.

公钥加密

公钥加密使用必须对从未经授权的用户保密的私钥和可以公开给任何人的公钥。 从数学上来讲,公钥和私钥是相互链接的;使用公钥加密的数据只能用私钥解密,而使用私钥签名的数据只能使用公钥进行验证。 公钥可供任何人使用;它用加密要发到送私钥所有者的数据。 公钥加密算法也称为非对称算法,因为加密数据需要一个密钥,而解密数据需要另一个密钥。 基本加密规则禁止密钥重复使用,并且每个通信会话的两个密钥应该是独有的。 但是,在实践中,非对称密钥的生存期通常很长。

双方(Alice 和 Bob)可能按如下所示使用公钥加密:首先,Alice 生成公钥/私钥对(解密一方创建公钥/私钥对,并发送给发送数据者)。 如果 Bob 想要向 Alice 发送一条已加密的消息,他会向她索要公钥。 Alice 通过非安全网络向 Bob 发送她的公钥,然后 Bob 使用此密钥对消息进行加密。 Bob 将加密的消息发送给 Alice,然后她将使用自己的私钥对其进行解密。

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

  • DSACryptoServiceProvider
  • RSACryptoServiceProvider
  • ECDiffieHellman (基类)
  • ECDiffieHellmanCng
  • ECDiffieHellmanCngPublicKey (基类)
  • ECDiffieHellmanKeyDerivationFunction (基类)
  • ECDsaCng

RSA 允许加密和签名,但 DSA 仅可用于签名,而 Diffie-Hellman 仅可用于生成密钥。 一般情况下,公钥算法的使用比私钥算法的更受限制。

数字签名

公钥算法还可用于构成数字签名。 数字签名会验证发件人的身份,并有助于保护数据的完整性。 使用 Alice 生成的公钥,Alice 的数据的收件人可通过将数字签名与 Alice 的数据及其公钥进行比较来验证数据是否由 Alice 发送。

若要使用公钥加密以数字方式签署一条消息,Alice 首先要将哈希算法应用于此消息,以创建消息摘要。 然后,Alice 使用她的私钥加密此消息摘要,以创建她的个人签名。 在收到消息和签名后,Bob 将使用 Alice 的公钥解密签名,以恢复此消息摘要,并且将使用 Alice 所使用的同一个哈希算法对消息进行哈希运算。 如果 Bob 计算的消息摘要与从 Alice 处收到的消息摘要完全匹配,Bob 就可以确定此消息来自私钥的持有人且数据不曾被修改。
Alice 签名流程

原始消息 >>哈希运算>> 消息摘要 >>私钥加密>> 数字签名

Bob 验证流程

数字签名 >>公钥解密>> 消息摘要 >>哈希运算>>

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

  • DSACryptoServiceProvider
  • RSACryptoServiceProvider
  • ECDsa (基类)
  • ECDsaCng

第一个例子说明了如何使用ECDSA(DSA 仅用于签名)算法进行签名。Alice创建了一个签名,它用Alice的私钥加密,可以使用Alice的公钥访问。因此保证该签名来自于Alice。

// 使用指定的ECDsaP521创建公钥和私钥
var aliceKeys = CngKey.Create(CngAlgorithm.ECDsaP521);

// 公钥
var alicePubKey = aliceKeys.Export(CngKeyBlobFormat.GenericPublicBlob);

// 获取原始字节流
var aliceData = Encoding.UTF8.GetBytes("Alice");

// 用私钥签名
byte[] aliceSignature;
// 使用Alice的私钥构建签名算法
using (var signingAlg = new ECDsaCng(aliceKeys))
{
	// 用指定的哈希算法计算消息的摘要,并根据签名算法创建一个消息签名
	aliceSignature = signingAlg.SignData(aliceData, HashAlgorithmName.SHA512);
	WriteLine($"Alice created signature: {Convert.ToBase64String(aliceSignature)}");
}

// 用公钥验证
using (CngKey key = CngKey.Import(alicePubKey, CngKeyBlobFormat.GenericPublicBlob))
{
	using (var signingAlg = new ECDsaCng(key))
	{
		// 哪里来的原始数据?
		var retValue = signingAlg.VerifyData(aliceData, aliceSignature, HashAlgorithmName.SHA512);
		WriteLine("Verify Result : {0}", retValue);
	}
}

注意
千万不要使用Encoding类把加密的数据转换位字符串。Encoding类验证和转换Unicode不允许使用无效值,因此把字符串转换回字节数组会得到另外一个值

哈希值

哈希算法将任意长度的二进制值映射到较小的固定长度的二进制值,称为哈希值。 哈希值是一段数据的数值表示形式。 如果对一段纯文本进行哈希处理,甚至只更改段落的一个字母,随后的哈希运算都将产生不同的值。

双方(Alice 和 Bob)可以使用哈希函数来确保消息的完整性。 他们会选择要对其消息进行签名的哈希算法。 Alice 编写一条消息,然后将消息原文和哈希签名通过不同的方式发送给Bob;Bob在接收到消息原文和哈希签名后,利用约定好的哈希算法对消息原文进行哈希运算计算出一个哈希值,并与接收到的哈希值进行比较。

.NET Framework 提供了以下实现哈希算法的类:

  • HMACSHA1
  • MACTripleDES
  • MD5CryptoServiceProvider
  • RIPEMD160
  • SHA1Managed.
  • SHA256Managed
  • SHA384Managed
  • SHA512Managed
  • 所有安全哈希算法 (SHA)、消息摘要 5 (MD5) 和 ripemd-160 算法的 HMAC 变体。
  • 所有 SHA 算法的 CryptoServiceProvider 实现(托管的代码包装)。
  • 所有 MD5 和 SHA 算法的下一代加密技术 (CNG) 实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhy29563

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值