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

在这里插入图片描述

AES加解密 - 快速上手

简介

这个标准用来替代原先的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();
        }
    }
}

  • 8
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

猿长大人

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

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

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

打赏作者

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

抵扣说明:

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

余额充值