65.9K
CodeProject 正在变化。 阅读更多。
Home

组合对称和非对称加密。

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (17投票s)

2004年10月25日

3分钟阅读

viewsIcon

96184

描述对称加密和非对称加密,然后展示如何结合它们。

对称加密

对称加密使用一个密钥值来加密和解密数据。发送者和接收者需要相同的密钥才能进行加密或解密。对称算法有两种类型,流算法和块算法。流算法一次处理一位或一个字节,而块算法处理更大的数据块(通常为 64 位)。这种类型的系统的缺点是,如果密钥被发现,所有消息都可以被解密。

在 .NET 框架中,System.Security.Cryptography 命名空间中有从 System.Security.SymmetricAlgorithm 类派生的类,使我们能够使用对称加密。每个类为此目的使用不同的算法。这些算法使用随机初始化向量 (IV),即使在使用相同源数据时,加密的数据也会有所不同。一般来说,密钥大小越大,算法就越安全。以下是可用的不同类

算法 默认密钥大小
DESCryptoServiceProvider DES 64
TripleDESCryptoServiceProvider TripleDES 192
RC2CryptServiceProvider RC2 128
RijndaelManaged Rijndael 256

使用 .NET,我们可以使用 CryptoStream 包装数据流。这为我们提供了一种非常简单的方法来使用对称加密类。如果您使用 CryptoStream 包装 FileStream,它会在写入时加密数据,并在读取时解密数据。这种类型的主要弱点是密钥的脆弱性。

示例

  • 声明该类的一个新实例
    Private Rijndael As New RijndaelManaged()
  • 写入密钥
    Dim keyFile As New FileStream("key.bin", FileMode.CreateNew) 
    keyFile.Write(Rijndael.Key, 0, Rijndael.Key.Length)
    keyFile.Close()
  • 加密数据
    Dim Transform As ICryptoTransform = Rijndael.CreateEncryptor() 
    Dim outFile As New FileStream("crypt.bin", FileMode.Create)
    outFile.Write(Rijndael.IV, 0, Rijndael.IV.Length) 
    Dim cryptStrm As New CryptoStream(outFile, Transform, CryptoStreamMode.Write) 
    Dim writer As New StreamWriter(cryptStrm) 
    writer.Write(txtSource.Text) 
    writer.Flush() 
    cryptStrm.FlushFinalBlock() 
    writer.Close()
  • 要解密数据,CryptoStream 将使用解密器,并且它将使用读取模式而不是写入模式。

非对称加密

非对称加密使用单独的密钥进行加密和解密。解密密钥很难从加密密钥中推导出来。加密密钥是公开的,因此任何人都可以加密消息。但是,解密密钥是私有的,因此只有接收者才能解密消息。通常在网络中设置“密钥对”,以便每个用户都有一个公钥和一个私钥。公钥对所有人可用,以便他们可以发送消息,但私钥仅对拥有它的人可用。

在 .NET 框架中,有一个 RSACryptoServiceProvider 类支持这种类型的加密。此类具有 1024 位的默认密钥大小。因为这种类型的加密不使用流,所以使用起来更加麻烦。您必须以小块加密数据,而不是能够包装 FileStream。这种类型的系统通常用于加密密钥,而不是整个消息。这是因为非对称加密速度慢,并且容易受到“选择明文”攻击。“选择明文”攻击是指当某人可以访问多个加密消息以及明文时,他们选择要加密的明文。关于这种类型系统的速度,对称算法通常快 1000 倍。非对称算法通常也会产生比源文件大得多的加密文件。

结合对称加密和非对称加密

如果我们想要两种类型的加密算法的优点,一般的想法是创建一个随机对称密钥来加密数据,然后使用非对称方式加密该密钥。非对称加密密钥后,我们将其添加到加密的消息中。接收者获取密钥,使用他们的私钥解密它,并使用它来解密消息。

示例

  • 声明该类的一个新实例
    Private RSA As New RSACryptoServiceProvider()
  • 创建密钥
    Dim keyFile As New FileStream("key.bin", FileMode.CreateNew)
    Dim writer As New StreamWriter(keyFile)
    writer.Write(RSA.ToXmlString(True))
    writer.Flush()
    keyFile.Close()
  • 加密
    Dim outFile As New FileStream("crypt.bin", FileMode.Create)
    Dim Rijndael As New RijndaelManaged()
    Dim EncryptedKey() As Byte = RSA.Encrypt(Rijndael.Key, False)
    Dim EncryptedIV() As Byte = RSA.Encrypt(Rijndael.IV, False)
    outFile.Write(EncryptedKey, 0, EncryptedKey.Length)
    outFile.Write(EncryptedIV, 0, EncryptedIV.Length)
    Dim Transform As ICryptoTransform = Rijndael.CreateEncryptor()
    Dim cryptStrm As New CryptoStream(outFile, Transform, CryptoStreamMode.Write)
    Dim writer As New StreamWriter(cryptStrm)
    writer.Write(txtSource.Text)
    writer.Flush()
    cryptStrm.FlushFinalBlock()
    writer.Close()

结论

密码学是一个非常强大的领域。本文试图指出将不同系统组合成一个系统的优势。在当前的密码学状态下,密钥是保持数据安全的最重要工具。保持私钥的安全性和足够大将使得破解加密系统非常困难。

资源

  • “应用密码学”,Bruce Schneier。
  • “Visual Basic .NET Programmers Cookbook”,Matthew MacDonald。
© . All rights reserved.