前言

对于数据加密和解密每次我都是从网上拷贝一份,无需有太多了解,由于在.net core中对加密和解密目前全部是统一了接口,只是做具体的实现,由于遇到过问题,所以将打算基本了解下其原理,知其然足矣,知其所以然那就达不到了,利用AES加密更加安全,上一篇园友又提出,所以借着这个机会刚好用到加密和解密,同时我也已将项目中DES加密已替换为AES,在这里介绍一下。

AES加密介绍

高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。它要求区块大小必须为128位,而密钥长度则可以为128、196、256位。基于此我们来实现.NET Framework版本和.NET Core版本。

在.NET Framework中实现AES加密和解密

AES加密

  1. public static string EncryptText(string input, string key)
  2. {
  3.  
  4. byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(input);
  5. byte[] passwordBytes = Encoding.UTF8.GetBytes(key);
  6.  
  7. passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
  8.  
  9. byte[] bytesEncrypted = AESEncryptBytes(bytesToBeEncrypted, passwordBytes);
  10.  
  11. string result = Convert.ToBase64String(bytesEncrypted);
  12.  
  13. return result;
  14. }
  1. public static byte[] AESEncryptBytes(byte[] bytesToBeEncrypted, byte[] passwordBytes)
  2. {
  3. byte[] encryptedBytes = null;
  4.  
  5. var saltBytes = new byte[] { , , , , , , , ,};
  6.  
  7. using (var ms = new MemoryStream())
  8. {
  9. using (var AES = new RijndaelManaged())
  10. {
  11. AES.KeySize = ;
  12. AES.BlockSize = ;
  13.  
  14. var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, );
  15. AES.Key = key.GetBytes();
  16. AES.IV = key.GetBytes();
  17.  
  18. AES.Mode = CipherMode.CBC;
  19.  
  20. using (var cs = new CryptoStream(ms, AES.CreateEncryptor(),
  21. CryptoStreamMode.Write))
  22. {
  23. cs.Write(bytesToBeEncrypted, , bytesToBeEncrypted.Length);
  24. cs.Close();
  25. }
  26.  
  27. encryptedBytes = ms.ToArray();
  28. }
  29. }
  30.  
  31. return encryptedBytes;
  32. }

上述盐字节必须为至少8个字节,否则报错如下:

AES解密

  1. public static string DecryptText(string input, string key)
  2. {
  3. byte[] bytesToBeDecrypted = Convert.FromBase64String(input);
  4.  
  5. byte[] passwordBytes = Encoding.UTF8.GetBytes(key);
  6.  
  7. passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
  8.  
  9. byte[] bytesDecrypted = AESDecryptBytes(bytesToBeDecrypted, passwordBytes);
  10.  
  11. string result = Encoding.UTF8.GetString(bytesDecrypted);
  12.  
  13. return result;
  14. }
  1. public static byte[] AESDecryptBytes(byte[] bytesToBeDecrypted, byte[] passwordBytes)
  2. {
  3. byte[] decryptedBytes = null;
  4.  
  5. var saltBytes = new byte[] { , , , , , , , ,};
  6.  
  7. using (var ms = new MemoryStream())
  8. {
  9. using (var AES = new RijndaelManaged())
  10. {
  11. AES.KeySize = ;
  12. AES.BlockSize = ;
  13.  
  14. var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, );
  15. AES.Key = key.GetBytes();
  16. AES.IV = key.GetBytes();
  17.  
  18. AES.Mode = CipherMode.CBC;
  19.  
  20. using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
  21. {
  22. cs.Write(bytesToBeDecrypted, , bytesToBeDecrypted.Length);
  23. cs.Close();
  24. }
  25.  
  26. decryptedBytes = ms.ToArray();
  27. }
  28. }
  29.  
  30. return decryptedBytes;
  31. }

测试如下:

  1. var encrptText = "Jeffcky";
  2. var key = Guid.NewGuid().ToString("N");
  3. Console.WriteLine("加密前内容:" + encrptText);
  4. var input = EncryptText(encrptText,key);
  5. Console.WriteLine("加密后字符串为:" + input);
  6. var text = DecryptText(input, key);
  7. Console.WriteLine("解密后内容:" + text);

上述利用 RijndaelManaged 来实例化AES,最终该类继承自 SymmetricAlgorithm 对称算法类。通过我们实例化一个 Rfc2898DeriveBytes 来对密钥密钥和盐循环迭代1000次从而实现加密,同理解密反向操作。

在.NET Core中实现AES加密和解密

在.NET Core中对于对称加密统一接口不再利用不同类而实现,对于非对称加密当然和对称加密接口就不同了,创建起来格外方便,不再是实例化对应的类,如下

  1. //对称加密
  2. var aes = Aes.Create();
  3. var tripleDES = TripleDES.Create();
  4.  
  5. //非对称加密
  6. var rsa = RSA.Create();

由下可以看出直接定义了一个静态方法来创建加密

  1. public abstract class Aes : SymmetricAlgorithm
  2. {
  3. protected Aes();
  4.  
  5. public override KeySizes[] LegalBlockSizes { get; }
  6. public override KeySizes[] LegalKeySizes { get; }
  7.  
  8. public static Aes Create();
  9. }
  1. public abstract class RSA : AsymmetricAlgorithm
  2. {
  3. protected RSA();
  4.  
  5. public static RSA Create();
  6. ...
  7. }

当然命名空间依然是 System.Security.Cryptography 。我们直接看实现。

AES加密

  1. public static string AESEncrypt(string input, string key)
  2. {
  3. var encryptKey = Encoding.UTF8.GetBytes(key);
  4.  
  5. using (var aesAlg = Aes.Create())
  6. {
  7. using (var encryptor = aesAlg.CreateEncryptor(encryptKey, aesAlg.IV))
  8. {
  9. using (var msEncrypt = new MemoryStream())
  10. {
  11. using (var csEncrypt = new CryptoStream(msEncrypt, encryptor,
  12. CryptoStreamMode.Write))
  13.  
  14. using (var swEncrypt = new StreamWriter(csEncrypt))
  15. {
  16. swEncrypt.Write(input);
  17. }
  18.  
  19. var iv = aesAlg.IV;
  20.  
  21. var decryptedContent = msEncrypt.ToArray();
  22.  
  23. var result = new byte[iv.Length + decryptedContent.Length];
  24.  
  25. Buffer.BlockCopy(iv, , result, , iv.Length);
  26. Buffer.BlockCopy(decryptedContent, , result,
  27. iv.Length, decryptedContent.Length);
  28.  
  29. return Convert.ToBase64String(result);
  30. }
  31. }
  32. }
  33. }

AES解密(修改:2019-11-13)

  1. public static string AESDecrypt(string input, string key)
  2. {
  3. var fullCipher = Convert.FromBase64String(input);
  4.  
  5. var iv = new byte[];
  6. var cipher = new byte[fullCipher.Length-iv.Length];
  7.  
  8. Buffer.BlockCopy(fullCipher, , iv, , iv.Length);
  9. Buffer.BlockCopy(fullCipher, iv.Length, cipher, , fullCipher.Length- iv.Length);
  10. var decryptKey = Encoding.UTF8.GetBytes(key);
  11.  
  12. using (var aesAlg = Aes.Create())
  13. {
  14. using (var decryptor = aesAlg.CreateDecryptor(decryptKey, iv))
  15. {
  16. string result;
  17. using (var msDecrypt = new MemoryStream(cipher))
  18. {
  19. using (var csDecrypt = new CryptoStream(msDecrypt,
  20. decryptor, CryptoStreamMode.Read))
  21. {
  22. using (var srDecrypt = new StreamReader(csDecrypt))
  23. {
  24. result = srDecrypt.ReadToEnd();
  25. }
  26. }
  27. }
  28.  
  29. return result;
  30. }
  31. }
  32. }

测试如下:

  1. var key = Guid.NewGuid().ToString("N");
  2. var name = "Jeffcky";
  3. Console.WriteLine($"加密字符串为{name}");
  4. var encryptStr = AESEncrypt(name, key);
  5. Console.WriteLine($"加密后结果为:{encryptStr}");
  6. var decryptStr = AESDecrypt(encryptStr, key);
  7. Console.WriteLine($"解密后字符串为{decryptStr}");

总结

在.NET Core中实现对称加密和非对称加密无论是实现还是创建都更加简洁,之前也并未去具体了解加密和解密相关内容,借此机会稍微了解下对应的加密所以花了一点时间。对于AES加密还没怎么具体去了解内部原理,只是参照了一点资料,以此作为备忘录,目前.NET Core仅支持AES、TripleDES、RSA。希望对在.NET Core项目中需要实现加密的童鞋提供一点帮助。接下来有时间我们继续巩固下线程基础知识,敬请期待,待我学习完毕再来更新博客和大家一起分享。

探讨.NET Core中实现AES加密和解密以及.NET Core为我们提供了什么方便!的更多相关文章

  1. 探讨数据进行AES加密和解密以及.NET Core对加密和解密为我们提供了什么?

    前言 对于数据加密和解密每次我都是从网上拷贝一份,无需有太多了解,由于在.net core中对加密和解密目前全部是统一了接口,只是做具体的实现,由于遇到过问题,所以将打算基本了解下其原理,知其然足矣, ...

  2. OPENSSL安装 以及使用openssl中的AES加密和解密

    OPENSSL安装:(VS) 1:第一步和所有的软件安装一样. 2:将OPENSSL中INLUCDE 和 LIB 分别拷贝到VS中VC的INLUCDE 和LIB目录下(我的机器上的目录是:C:\Pro ...

  3. 探讨.NET Core数据进行3DES加密和解密问题

    前言 一直困扰着我关于数据加密这一块,24号晚上用了接近3个小时去完成一项任务,本以为立马能解决,但是为了保证数据的安全性,我们开始去对数据进行加密,然后接下来3个小时专门去研究加密这一块,然而用着用 ...

  4. 探讨NET Core数据进行3DES加密或解密弱密钥问题

    前言 之前写过一篇<探讨.NET Core数据进行3DES加密和解密问题>,最近看到有人提出弱密钥问题,换个强密钥不就完了吗,猜测可能是与第三方对接导致很无奈不能更换密钥,所以产生本文解决 ...

  5. 使用as3crypto在Flex中实现AES加密

    要在Flex中实现AES加密,可以通过as3crypto实现.但是as3crypto本身的用法比较复杂,一般是封装一下再调用. 下面是9RIA上的一篇文章给出的一个实现,使用中稍感不方便(见注释): ...

  6. Php AES加密、解密与Java互操作的问题

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html 内部邀请码:C8E245J (不写邀请码,没有现金送) 国 ...

  7. java独立小程序实现AES加密和解密

    一.需求: web项目中配置文件配置的密码是明文的, 现在需要修改成密文, 加密方式采用AES, 于是写了个工具类用于加密和解密. 又因为这个密码是由客户来最终确定, 所以为了部署时方便起见, 写了个 ...

  8. java与C#、.NET AES加密、解密 解决方案

      1.情景展示 Java提供的密钥,C#无法解密. 2.原因分析 在Java中,AES的实际密钥需要用到KeyGenerator 和 SecureRandom,但是C#和.NET 里面没有这2个类, ...

  9. AES加密、解密工具类

    AES加密.解密工具类代码如下: package com.util; import java.io.IOException; import java.io.UnsupportedEncodingExc ...

随机推荐

  1. leetcode-66.加一

    leetcode-66.加一 题意 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一. 最高位数字存放在数组的首位, 数组中每个元素只存储一个数字. 你可以假设除了整数 0 之外,这个 ...

  2. Hibernate:查询

    本文内容 OID查询 对象导航查询 HQL查询 QBC查询 SQL查询 首发日期:2018-07-31 hibernate的查询方式: hibernate有很多查询方式 OID查询 对象导航查询: H ...

  3. Android 线程交互

    在Android开发过程中,耗时操作是不允许写在主线程(UI线程)中的,以免由于等待时间过长而发生ANR.所以耗时操作需要创建子线程来完成,然而往往这些操作都需要与主线程进行通讯交互(例如更新主线程的 ...

  4. jdk各版本特性

    JDK Version 1.0 开发代号为Oak(橡树),于1996-01-23发行. JDK Version 1.1 于1997-02-19发行. 引入的新特性包括: 引入JDBC(Java Dat ...

  5. xtrabackup部署以及使用

    简介 备份mysql数据库一直是一个比较恶心的工作,主要就是备份的数据库比较大实在是慢.最近开始使用xtrabackup来备份数据库,速度上快了很多,尤其还原速度要快的多.下面我将从安装开始简要介绍一 ...

  6. Linux下2号进程的kthreadd--Linux进程的管理与调度(七)

    2号进程 内核初始化rest_init函数中,由进程 0 (swapper 进程)创建了两个process init 进程 (pid = 1, ppid = 0) kthreadd (pid = 2, ...

  7. Windows10家庭版连接远程桌面出现credssp加密oracle修正问题

    我发现我的win10不能连接别人的远程桌面,问题如下: 1.windows10家庭版需要修改注册表,家庭版没有组织策略: 2.win+R打开快速启动命令行输入"regedit": ...

  8. python——函数之生成器

    1 生成器函数的含义    生成器是一个返回可以迭代对象的函数,它是一个特殊的迭代器,但迭代器的抽象层级更高且比较复杂需要实现很多方法.相较迭代器而言,生成器简单使用. 2 生成器的创建方式 2.1 ...

  9. js原生动态创建表格

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. Alpha阶段 - 博客链接合集

    Alpha阶段 - 博客链接合集 项目Github地址 安卓端(Stardust):https://github.com/StardustProject/Stardust 服务器端(Gravel):h ...