C# | AES加解密 - 快速上手

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院 (NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一 。AES作为计算机领域最常见的通用加密算法之一,称之为对称加密算法中的一哥也丝毫不为过,其重要程度不言而喻。本文将极尽详细的讲解C#实现AES加密和解密的全过程。

image.png

AES加解密 - 快速上手

@[toc]

简介

这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院 (NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一 。

AES作为计算机领域最常见的通用加密算法之一,称之为对称加密算法中的一哥也丝毫不为过,其重要程度不言而喻。
本文将极尽详细的讲解C#实现AES加密和解密的全过程。


演示

先看一下界面操作的演示:
在这里插入图片描述
这里我是用固定的ASE秘钥和向量进行加解密:

AES秘钥(32位):12345678901234567890123456789012
AES向量(16位):1234567890123456

用于测试的明文字符串及得到的加密结果如下:

明文(加密前):早上好
密文(加密后):56BA88D88B33EF9239C15CE521261588


源代码

所有引用

using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Windows.Forms;

AES参数

AES加密需要的6个参数如下所示:

        /// <summary>
        /// 指定要用于加密的块密码模式
        /// </summary>
        public CipherMode CipherMode {
   
    get; set; } = CipherMode.CBC;

        /// <summary>
        /// 指定在消息数据块短于加密操作所需的完整字节数时要应用的填充类型
        /// </summary>
        public PaddingMode PaddingMode {
   
    get; set; } = PaddingMode.PKCS7;

        /// <summary>
        /// 获取或设置加密操作的块大小(以位为单位)
        /// </summary>
        public int BlockSize {
   
    get; set; } = 128;

        /// <summary>
        /// 获取或设置用于对称算法的密钥大小(以位为单位)
        /// </summary>
        public int KeySize {
   
    get; set; } = 256;

        /// <summary>
        /// 用于对称算法的密钥(长度为[KeySize/8]字节)
        /// </summary>
        public byte[] RgbKey {
   
    get; } = "12345678901234567890123456789012".GetBytes();

        /// <summary>
        /// 用于对称算法的初始化向量(长度为16字节)
        /// </summary>
        public byte[] RgbIV {
   
    get; } = "1234567890123456".GetBytes();

生成加密器和解密器

创建AesManaged,将AES加密所需的参数填入,生成加密器和解密器:

            // 创建AES配置并生成加密器和解密器
            using (var managed = new AesManaged()
            {
   
   
                Mode = CipherMode,
                KeySize = KeySize,
                Padding = PaddingMode,
                BlockSize = BlockSize,
                Key = RgbKey,
                IV = RgbIV,
            })
            {
   
   
                encryptor = managed.CreateEncryptor();
                decryptor = managed.CreateDecryptor();
            }

加密按钮代码

加密按钮(btnEncrypt)单击事件触发时执行以下代码:

        private void btnEncrypt_Click(object sender, EventArgs e)
        {
   
   
            // 读取明文并转为字节数组(默认使用UTF-8编码格式)
            var bytes = tbClearText.Text.GetBytes();

            // 将待加密字节数组转为内存流
            var stream = new MemoryStream(bytes);

            // 创建加密流(使用加密器)
            var cryptoStream = new CryptoStream(stream, encryptor, CryptoStreamMode.Read);

            // 将加密流的内容拷贝到空的内存流中
            var encryptedStream = new MemoryStream();
            cryptoStream.CopyTo(encryptedStream);

            // 将新的内存流内容转为字节数组
            var encryptedBytes = encryptedStream.ToArray();

            // 以十六进制形式显示
            tbEncryptedText.Text = encryptedBytes.ToHexString();
        }

解密按钮代码

解密按钮(btnDecrypt)单击事件触发时执行以下代码:

        private void btnDecrypt_Click(object sender, EventArgs e)
        {
   
   
            // 读取十六进制密文并转为字节数组
            var bytes = tbEncryptedText.Text.HexStringToBytes();

            // 将加密字节数组转为内存流
            var stream = new MemoryStream(bytes);

            // 创建加密流(使用解密器)
            var cryptoStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Read);

            // 将加密流的内容拷贝到空的内存流中
            var clearStream = new MemoryStream();
            cryptoStream.CopyTo(clearStream);

            // 将新的内存流内容转为字节数组
            var encryptedBytes = clearStream.ToArray();

            // 将明文字节数组编码为字符串(默认使用UTF-8编码格式)
            tbClearText.Text = encryptedBytes.EncodeToString();
        }

界面设计

界面设计也非常简单,两个文本框(明文、密文)和两个按钮(加密、解密),布局如下:
在这里插入图片描述


源码使用问题

直接使用源码时,以下几处可能会遇到“未找到方法”的提示,这是因为这几个简化开发的方法需要安装扩展包“CodePlus”后才能使用,安装方法:C# 字节数组与16进制字符串互相转换
当然也可以自己实现这转换过程,都不难。
在这里插入图片描述


附录:完整代码

虽然上面已经有了,但是为了方便大家抄作业,还是整个贴上吧。

using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Windows.Forms;

namespace Test.Blog.Aes
{
   
   
    public partial class AesDemoForm : Form
    {
   
   
        private ICryptoTransform encryptor;
        private ICryptoTransform decryptor;

        /// <summary>
        /// 指定要用于加密的块密码模式
        /// </summary>
        public CipherMode CipherMode {
   
    get; set; } = CipherMode.CBC;

        /// <summary>
        /// 指定在消息数据块短于加密操作所需的完整字节数时要应用的填充类型
        /// </summary>
        public PaddingMode PaddingMode {
   
    get; set; } = PaddingMode.PKCS7;

        /// <summary>
        /// 获取或设置加密操作的块大小(以位为单位)
        /// </summary>
        public int BlockSize {
   
    get; set; } = 128;

        /// <summary>
        /// 获取或设置用于对称算法的密钥大小(以位为单位)
        /// </summary>
        public int KeySize {
   
    get; set; } = 256;

        /// <summary>
        /// 用于对称算法的密钥(长度为[KeySize/8]字节)
        /// </summary>
        public byte[] RgbKey {
   
    get; } = "12345678901234567890123456789012".GetBytes();

        /// <summary>
        /// 用于对称算法的初始化向量(长度为16字节)
        /// </summary>
        public byte[] RgbIV {
   
    get; } = "1234567890123456".GetBytes();


        public AesDemoForm()
        {
   
   
            InitializeComponent();

            // 创建AES配置并生成加密器和解密器
            using (var managed = new AesManaged()
            {
   
   
                Mode = CipherMode,
                KeySize = KeySize,
                Padding = PaddingMode,
                BlockSize = BlockSize,
                Key = RgbKey,
                IV = RgbIV,
            })
            {
   
   
                encryptor = managed.CreateEncryptor();
                decryptor = managed.CreateDecryptor();
            }
        }

        private void btnEncrypt_Click(object sender, EventArgs e)
        {
   
   
            // 读取明文并转为字节数组(默认使用UTF-8编码格式)
            var bytes = tbClearText.Text.GetBytes();

            // 将待加密字节数组转为内存流
            var stream = new MemoryStream(bytes);

            // 创建加密流(使用加密器)
            var cryptoStream = new CryptoStream(stream, encryptor, CryptoStreamMode.Read);

            // 将加密流的内容拷贝到空的内存流中
            var encryptedStream = new MemoryStream();
            cryptoStream.CopyTo(encryptedStream);

            // 将新的内存流内容转为字节数组
            var encryptedBytes = encryptedStream.ToArray();

            // 以十六进制形式显示
            tbEncryptedText.Text = encryptedBytes.ToHexString();
        }

        private void btnDecrypt_Click(object sender, EventArgs e)
        {
   
   
            // 读取十六进制密文并转为字节数组
            var bytes = tbEncryptedText.Text.HexStringToBytes();

            // 将加密字节数组转为内存流
            var stream = new MemoryStream(bytes);

            // 创建加密流(使用解密器)
            var cryptoStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Read);

            // 将加密流的内容拷贝到空的内存流中
            var clearStream = new MemoryStream();
            cryptoStream.CopyTo(clearStream);

            // 将新的内存流内容转为字节数组
            var encryptedBytes = clearStream.ToArray();

            // 将明文字节数组编码为字符串(默认使用UTF-8编码格式)
            tbClearText.Text = encryptedBytes.EncodeToString();
        }
    }
}
相关文章
|
7月前
|
算法 搜索推荐 安全
C# | 上位机开发新手指南(八)加密算法——AES
AES——这是在加密算法中相当重要的一种加密方式! 虽然这个世界上已经存在了非对称加密算法(比如RSA、ECC等),但是在对称加密算法中,AES的地位依然相当重要。与非对称加密算法不同,对称加密算法使用的是相同的密钥对数据进行加密和解密,因此其加密和解密速度更快,而且更加高效。而在对称加密算法中,AES是目前最安全、最可靠的加密算法之一,其加密强度和运行效率都非常高。因此,无论是在个人计算机、移动设备,还是在服务器和云计算等领域,AES都被广泛应用于数据的加密和解密过程中。
295 0
C# | 上位机开发新手指南(八)加密算法——AES
|
存储 安全 算法
C#加解密
C#加解密
162 0
|
C# 数据安全/隐私保护
|
安全 算法 C#
C# 中使用 RSA加解密算法
一、什么是RSA   RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。      在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。
2311 0
|
算法 C# 数据安全/隐私保护