对称加密(4) NET对称加密实践

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介:

对称加密(4) NET对称加密实践

 

在使用.NET框架提供的加密算法实现类来执行加密任务时,需要准备加密密钥和初始化向量(Initialization VectorIV)。基于对称加密的特点,在加密数据之后一定要保存好密钥和初始化向量,因为解密要用到它们。但是对于不同的数据加密,要使用不同的密钥和初始化向量,理论上每次新的加密过程都应该使用全新的密钥和初始化向量。

通常需要将加密密钥和初始化向量传递给另一个人,这时候需要使用非对称加密算法来加密密钥和初始化向量,然后在网络上传输。本节主要演示如何使用加密实践类,更多的应用内容会在本书的第四部分介绍。

那么如何创建加密密钥和初始化向量呢?有两种基本方法,一种是使用加密算法实现类的构造函数,另一种是使用GenerateIV()GenerateKey()方法生成密钥和初始化向量。

使用构造函数创建密钥和初始化向量

先测试构造函数的方法,如代码清单6-5

代码清单6-5  使用构造函数创建密钥和初始化向量

using System;

using System.Text;

using System.Security.Cryptography;

namespace Encription

{

    classProgram

    {

        staticvoid Main(string[] args)

        {

            AesCryptoServiceProvider acsp = new AesCryptoServiceProvider();

            WriteKeyAndIV(acsp);

            AesManaged am = newAesManaged();

            WriteKeyAndIV(am);

            DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();

            WriteKeyAndIV(dsp);

            TripleDESCryptoServiceProvider tdsp = newTripleDESCryptoServiceProvider();

            WriteKeyAndIV(tdsp);

            RijndaelManaged rm = new RijndaelManaged();

            WriteKeyAndIV(rm);

            Console.Read();

        }

        staticvoid WriteKeyAndIV(SymmetricAlgorithm sa)

        {

            Console.WriteLine(GetStringFromByte(sa.Key));

            Console.WriteLine("*******");

            Console.WriteLine(GetStringFromByte(sa.IV));

            Console.WriteLine("--------------------------");

        }

        staticstring GetStringFromByte(byte[] bytes)

        {

            string s="";

            for (int i = 0; i < bytes.Length; i++)

            {

                s += bytes[i].ToString()+" ";

            }

            return s;

        }

    }

}

以上代码中一共有三个方法,Main方法用来初始化.NET提供的5种对称加密实例;WriteKeyAndIV方法用来输出每个实例的密钥和初始化向量;GetStringFromByte方法用来输出byte数组的原始值。现在看输出结果,是不是如预料的,已经初始化了加密密钥和初始化向量呢?如图6-11所示。

 

6-11  代码清单6-5输出结果

如图6-11所示,在控制台输出了每个加密实例的密钥和初始化向量。

使用GenerateIV()GenerateKey()方法

当需要多个密钥或者多个初始化向量的时候,就要采用GenerateIV()GenerateKey()方法。下面对代码清单6-5做简要的修改,如代码清单6-6所示。

代码清单6-6  使用GenerateIV()GenerateKey()方法

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Security.Cryptography;

namespace Encription

{

    classProgram

    {

        staticvoid Main(string[] args)

        {

            AesCryptoServiceProvider acsp = new AesCryptoServiceProvider();

            WriteKeyAndIV(acsp);

            acsp.GenerateIV();

            acsp.GenerateKey();

            WriteKeyAndIV(acsp);

            Console.Read();

        }

        staticvoid WriteKeyAndIV(SymmetricAlgorithm sa)

        {

          

            Console.WriteLine(GetStringFromByte(sa.Key));

            Console.WriteLine("*******");

            Console.WriteLine(GetStringFromByte(sa.IV));

            Console.WriteLine("--------------------------");

        }

        staticstring GetStringFromByte(byte[] bytes)

        {

            string s="";

            for (int i = 0; i < bytes.Length; i++)

            {

                s += bytes[i].ToString()+" ";

            }

            return s;

        }

    }

}

   修改很简单,Main方法中只保留了AesCryptoServiceProvider实例,再初始化该实例后,又调用它的GenerateIVGenerateKey方法,看是否产生了新的加密密钥和初始化向量。结果如图6-12所示。

6-12  代码清单6-6运行结果

如图6-12所示,可以看到使用GenerateIVGenerateKey方法后,生成了新的密钥和初始化向量。

   准备工作完成了,下面要开始真正的加密之旅了。对称加密需要和CryptoStream类的实例配合,使用加密流来实现数据加密(.NET中的内存流、文件流、网络流都可以使用)。为了示例更明了,以AesCryptoServiceProvider类为例,使用内存流来演示如何使用对称加密类加密、解密数据。先看代码清单6-7

代码清单6-7  加密解密数据示例

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Security.Cryptography;

using System.IO;

namespace Sample

{

    classProgram

    {

        staticAesCryptoServiceProvider acsp = newAesCryptoServiceProvider();

        staticvoid Main(string[] args)

        {

            byte[] key = acsp.Key;

            byte[] iv = acsp.IV;

            string s = @"xuanhun加密测试";

            byte[] sbyt = Encoding.Default.GetBytes(s);

            byte []Enb = Encript(sbyt, key, iv);

            byte []Deb = Decript(Enb, key, iv);

            Console.WriteLine(Encoding.Default.GetString(Enb));

            Console.WriteLine(Encoding.Default.GetString(Deb));

            Console.Read();

        }

 

        publicstaticbyte[] Encript(byte[] s1, byte[] key, byte[] iv)

        {

         

   using (MemoryStream msEncrypt = new MemoryStream())             

{                 using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, acsp.CreateEncryptor(key, iv), CryptoStreamMode.Write))                 {                    

 using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))                    

 {                         //Write all data to the stream.                        

 var s = Convert.ToBase64String(s1);                       

  swEncrypt.Write(s);                     

}                     

  byte[] outb1  = msEncrypt.ToArray();                      

 return outb1;              

   }            

 }

        }

 

        publicstaticbyte[] Decript(byte[] s2, byte[] key, byte[] iv)

        {

           

    using (MemoryStream msDecrypt = new MemoryStream(s2))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, acsp.CreateDecryptor(key, iv), CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            var s= Convert.FromBase64String(srDecrypt.ReadToEnd());
 
                            return s;
                        }
                    }
                }

        }

 

        publicstaticbyte[] GetByteFromstring(string s)

        {

            returnEncoding.Default.GetBytes(s);

        }

    }

}

以上代码首先创建了AesCryptoServiceProvider实例,然后在Main方法中使用了局部变量keyiv来保存该实例的加密密钥和初始化向量,字符串s是要加密的原始字符串。局部变量sbyte保存了将字符串s转化为byte数组后的结果。加密解密过程都是围绕该byte数组进行的。

  Main方法中调用两个静态方法EncriptDecript方法,分别用来实现加密和解密。在Encript方法中,首先初始化内存流MemoryStream的实例mstream,然后以mstream为参数创建CryptoStream实例。CryptoStream构造函数需要3个参数:第一个是流实例,第二个是加密或者解密器,在加密函数中使用CreateEncryptor方法做参数,在解密方法中使用CreateDecryptor做参数;CreateEncryptorCreateDecryptor方法需要传入准备好的加密密钥和初始化向量。第三个参数是CryptoStreamMode枚举,该枚举有两个值WriteRead,用来指示流的操作。比如在网络流中,加密并输出数据时要设置Write属性,接收并解密的一方要设置Read属性。本例中把加密和解密的数据都写入内存流,所以都设置了Write属性。在初始化CryptoStream实例之后,调用该实例的Write方法,将加密后的数据写入内存流。然后再调用内存流的ToArray方法读出加密数据,返回到Main方法中,通过Encoding.Default.GetString方法,获得加密后的字符串。解密过程与此类似,不再赘述。

现在看改程序的运行结果,如图6-13所示。

6-13  代码清单6-7运行结果

如图6-7所示,已经成功实现了简单的对称加密解密过程。.NET中的其他对称加密实现类的使用方法与此类似。

 

----------------------注:本文部分内容改编自《.NET安全揭秘》


本文转自悬魂博客园博客,原文链接:http://www.cnblogs.com/xuanhun/archive/2012/06/23/2559537.html,如需转载请自行联系原作者

相关文章
|
3月前
|
存储 数据安全/隐私保护
.NET Core 究竟隐藏着怎样的神秘力量,能实现强身份验证与数据加密?
【8月更文挑战第28天】在数字化时代,数据安全与身份验证至关重要。.NET Core 提供了强大的工具,如 Identity 框架,帮助我们构建高效且可靠的身份验证系统,并支持高度定制化的用户模型和认证逻辑。此外,通过 `System.Security.Cryptography` 命名空间,.NET Core 还提供了丰富的加密算法和工具,确保数据传输和存储过程中的安全性。以下是一个简单的示例,展示如何使用 .NET Core 的 Identity 框架实现用户注册和登录功能。
38 3
|
1月前
|
安全 网络安全 数据安全/隐私保护
网络安全的守护者:漏洞管理与加密技术的实践之路
【9月更文挑战第33天】在数字时代的浪潮中,网络安全成为了维护信息资产安全的关键防线。本文将深入探讨网络安全中的两个核心要素——漏洞管理和加密技术,揭示它们如何协同工作以保护我们的在线世界。我们将通过实际案例,展示这些技术如何在现实世界中发挥作用,并强调安全意识的重要性。无论你是IT专业人士还是普通网民,这篇文章都将为你提供宝贵的知识和启示。
|
17天前
|
开发框架 缓存 算法
开源且实用的C#/.NET编程技巧练习宝库(学习,工作,实践干货)
开源且实用的C#/.NET编程技巧练习宝库(学习,工作,实践干货)
|
24天前
|
Cloud Native API C#
.NET云原生应用实践(一):从搭建项目框架结构开始
.NET云原生应用实践(一):从搭建项目框架结构开始
|
24天前
|
安全 网络协议 网络安全
【HTTPS】对称加密和非对称加密
【HTTPS】对称加密和非对称加密
28 0
|
2月前
|
算法 安全 网络安全
概念区分:对称加密、非对称加密、公钥、私钥、签名、证书
概念区分:对称加密、非对称加密、公钥、私钥、签名、证书
60 0
|
3月前
|
jenkins 测试技术 持续交付
解锁.NET项目高效秘籍:从理论迷雾到实践巅峰,持续集成与自动化测试如何悄然改变游戏规则?
【8月更文挑战第28天】在软件开发领域,持续集成(CI)与自动化测试已成为提升效率和质量的关键工具。尤其在.NET项目中,二者的结合能显著提高开发速度并保证软件稳定性。本文将从理论到实践,详细介绍CI与自动化测试的重要性,并以ASP.NET Core Web API项目为例,演示如何使用Jenkins和NUnit实现自动化构建与测试。每次代码提交后,Jenkins自动触发构建流程,通过编译和运行NUnit测试确保代码质量。这种方式不仅节省了时间,还能快速发现并解决问题,推动.NET项目开发迈向更高水平。
45 8
|
3月前
|
Kubernetes 监控 Devops
【独家揭秘】.NET项目中的DevOps实践:从代码提交到生产部署,你不知道的那些事!
【8月更文挑战第28天】.NET 项目中的 DevOps 实践贯穿代码提交到生产部署全流程,涵盖健壮的源代码管理、GitFlow 工作流、持续集成与部署、容器化及监控日志记录。通过 Git、CI/CD 工具、Kubernetes 及日志框架的最佳实践应用,显著提升软件开发效率与质量。本文通过具体示例,助力开发者构建高效可靠的 DevOps 流程,确保项目成功交付。
66 0
|
3月前
|
存储 算法 安全
|
3月前
|
Java Spring UED
Spring框架的异常处理秘籍:打造不败之身的应用!
【8月更文挑战第31天】在软件开发中,异常处理对应用的稳定性和健壮性至关重要。Spring框架提供了一套完善的异常处理机制,包括使用`@ExceptionHandler`注解和配置`@ControllerAdvice`。本文将详细介绍这两种方式,并通过示例代码展示其具体应用。`@ExceptionHandler`可用于控制器类中的方法,处理特定异常;而`@ControllerAdvice`则允许定义全局异常处理器,捕获多个控制器中的异常。
46 0