C#.NET AES CBC 加密

重点:

1. KEY 和 IV 转 byte[] 时的编码。

2.要加密的字符串转 byte[] 时的编码。

3.AES 的PADDING,MODE。

4.加密后的byte[] 转字符串时的编码。

加密过程

public static string AesEncrypt(string content, string aesKey, string aesIV)
        {

            byte[] byteKEY = Encoding.UTF8.GetBytes(aesKey);
            byte[] byteIV = Encoding.UTF8.GetBytes(aesIV);

            byte[] byteContnet = Encoding.UTF8.GetBytes(content);

            var _aes = new RijndaelManaged();
            _aes.Padding = PaddingMode.PKCS7;
            _aes.Mode = CipherMode.CBC;
             
            _aes.Key = byteKEY;
            _aes.IV = byteIV;

            var _crypto = _aes.CreateEncryptor(byteKEY, byteIV);
            byte[] decrypted = _crypto.TransformFinalBlock(
                byteContnet, 0, byteContnet.Length);

            _crypto.Dispose();

            return Convert.ToBase64String(decrypted);
        }

加密后的byte[] 转字符串时的编码,使用Base64。

--解密过程也大致相同。

1.先把密文字符串Base64 解码为 byte[] 。

2.解密后的byte[] ,再用UTF8编码还原为String.

解密过程

/// 解密
/// </summary>
/// <param name="decryptStr">要解密的串</param>
/// <param name="aesKey">密钥</param>
/// <param name="aesIV">IV</param>
/// <returns></returns>
public static string AesDecrypt(string decryptStr, string aesKey,string aesIV)
{

	byte[] byteKEY = Encoding.UTF8.GetBytes(aesKey);
	byte[] byteIV = Encoding.UTF8.GetBytes(aesIV);

	byte[] byteDecrypt = System.Convert.FromBase64String(decryptStr);

	var _aes = new RijndaelManaged();
	_aes.Padding = PaddingMode.PKCS7;
	_aes.Mode = CipherMode.CBC;
	 
	_aes.Key = byteKEY;
	_aes.IV = byteIV;

	var _crypto = _aes.CreateDecryptor(byteKEY, byteIV);
	byte[] decrypted = _crypto.TransformFinalBlock(
		byteDecrypt, 0, byteDecrypt.Length);

	_crypto.Dispose();

	return Encoding.UTF8.GetString(decrypted);
}

完整的AES UTIL , AES CBC ,PCKS7

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace Common.Utils
{
   public static class AesUtil
    {

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="decryptStr">要解密的串</param>
        /// <param name="aesKey">密钥</param>
        /// <param name="aesIV">IV</param>
        /// <returns></returns>
        public static string AesDecrypt(string decryptStr, string aesKey,string aesIV)
        {

            byte[] byteKEY = Encoding.UTF8.GetBytes(aesKey);
            byte[] byteIV = Encoding.UTF8.GetBytes(aesIV);

            byte[] byteDecrypt = System.Convert.FromBase64String(decryptStr);

            var _aes = new RijndaelManaged();
            _aes.Padding = PaddingMode.PKCS7;
            _aes.Mode = CipherMode.CBC;
             
            _aes.Key = byteKEY;
            _aes.IV = byteIV;

            var _crypto = _aes.CreateDecryptor(byteKEY, byteIV);
            byte[] decrypted = _crypto.TransformFinalBlock(
                byteDecrypt, 0, byteDecrypt.Length);

            _crypto.Dispose();

            return Encoding.UTF8.GetString(decrypted);
        }


        public static string AesEncrypt(string content, string aesKey, string aesIV)
        {

            byte[] byteKEY = Encoding.UTF8.GetBytes(aesKey);
            byte[] byteIV = Encoding.UTF8.GetBytes(aesIV);

            byte[] byteContnet = Encoding.UTF8.GetBytes(content);

            var _aes = new RijndaelManaged();
            _aes.Padding = PaddingMode.PKCS7;
            _aes.Mode = CipherMode.CBC;
             
            _aes.Key = byteKEY;
            _aes.IV = byteIV;

            var _crypto = _aes.CreateEncryptor(byteKEY, byteIV);
            byte[] decrypted = _crypto.TransformFinalBlock(
                byteContnet, 0, byteContnet.Length);

            _crypto.Dispose();

            return Convert.ToBase64String(decrypted);
        }

    }
}

调用DEMO,WINFORM写的。

using Common.Utils;
using System;
using System.Windows.Forms;

namespace AES加密
{

    public partial class Form1 : Form
    {

        string _aesKey = "1234567890123456";

        string _aesIV = "abcdefghABCDEFGH";


        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }


        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btmJiaMi_Click(object sender, EventArgs e)
        {
            try
            {
                if (string.IsNullOrEmpty(txtDaiJiaMi.Text))
                {
                    MessageBox.Show("待加密字符串 为空!");
                    return;
                }

                string content = txtDaiJiaMi.Text;


                txtJiaMiHou.Text = AesUtil.AesEncrypt(content, _aesKey, _aesIV);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnJieMi_Click(object sender, EventArgs e)
        {
            try
            {
                if (string.IsNullOrEmpty(txtJiaMiHou.Text))
                {
                    MessageBox.Show("加密后字符串 为空!");
                    return;
                }

                string content = txtJiaMiHou.Text;


                txtJieMiHou.Text = AesUtil.AesDecrypt(content, _aesKey, _aesIV);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}

 只要 KEY ,IV , MODE,PADDING ,密文编码,明文编码这几项统一,和其它编程语言加解密就无障碍了。

PHP进行AES-256-CBC加解密

当我们在 PHP 中使用 AES-256-CBC 加密解密时,可以使用 OpenSSL 扩展来实现。以下是一个示例代码:

<?php

function encrypt($data, $key, $iv) {
    $cipher = "AES-256-CBC";
    $options = OPENSSL_RAW_DATA;
    $encryptedData = openssl_encrypt($data, $cipher, $key, $options, $iv);
    return base64_encode($encryptedData);
}

function decrypt($encryptedData, $key, $iv) {
    $cipher = "AES-256-CBC";
    $options = OPENSSL_RAW_DATA;
    $decryptedData = openssl_decrypt(base64_decode($encryptedData), $cipher, $key, $options, $iv);
    return $decryptedData;
}

$data = "要加密的数据";
$key = "32位的密钥";
$iv = "16位的初始向量";

$encrypted = encrypt($data, $key, $iv);
echo "加密后的数据: " . $encrypted . "\n";

$decrypted = decrypt($encrypted, $key, $iv);
echo "解密后的数据: " . $decrypted . "\n";

?>

可以使用以下示例代码生成随机的密钥和初始向量:

$key = bin2hex(random_bytes(16)); // 生成 32 位随机密钥
$iv = bin2hex(random_bytes(8)); // 生成 16 位随机初始向量

echo "随机生成的密钥: " . $key . "\n";
echo "随机生成的初始向量: " . $iv . "\n";

请注意,对于 AES-256-CBC 加密,密钥应该是 32 字节(256 位),初始向量应该是 16 字节(128 位)。您可以根据需要调整密钥和初始向量的长度。

C#进行AES-256-CBC加解密

以下是使用 C# 实现 AES-256-CBC 加密和解密的示例代码:

using System;
using System.Security.Cryptography;
using System.Text;

class Program
{
    static void Main()
    {
        string data = "要加密的数据";
        string key = "32位的密钥";
        string iv = "16位的初始向量";

        string encryptedData = Encrypt(data, key, iv);
        Console.WriteLine("加密后的数据: " + encryptedData);

        string decryptedData = Decrypt(encryptedData, key, iv);
        Console.WriteLine("解密后的数据: " + decryptedData);
    }

    public static string Encrypt(string data, string key, string iv)
    {
        byte[] encryptedBytes;
        using (Aes aesAlg = Aes.Create())
        {
            aesAlg.Key = Encoding.UTF8.GetBytes(key);
            aesAlg.IV = Encoding.UTF8.GetBytes(iv);
            ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

            byte[] dataBytes = Encoding.UTF8.GetBytes(data);
            encryptedBytes = encryptor.TransformFinalBlock(dataBytes, 0, dataBytes.Length);
        }
        return Convert.ToBase64String(encryptedBytes);
    }

    public static string Decrypt(string encryptedData, string key, string iv)
    {
        byte[] decryptedBytes;
        using (Aes aesAlg = Aes.Create())
        {
            aesAlg.Key = Encoding.UTF8.GetBytes(key);
            aesAlg.IV = Encoding.UTF8.GetBytes(iv);
            ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

            byte[] encryptedBytes = Convert.FromBase64String(encryptedData);
            decryptedBytes = decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
        }
        return Encoding.UTF8.GetString(decryptedBytes);
    }
}

请注意,在实际使用中,密钥和初始向量需要严格保密。此示例中的密钥和初始向量仅用于演示目的,请确保在真正使用时使用随机生成的安全密钥和初始向量。同时,也请确保在程序中引入正确的命名空间 using System.Security.Cryptography;using System.Text;

确保 PHP 服务器和客户端之间使用相同的安全密钥和初始向量是确保加密和解密正确性的关键。以下是一些方法来保证密钥和初始向量的安全性:

  1. 使用 HTTPS 进行通信:使用 SSL/TLS 加密的 HTTPS 连接来保护服务器和客户端之间的通信,确保数据在传输过程中的安全。

  2. 密钥交换协议:使用安全的密钥交换协议(如 Diffie-Hellman)来协商并交换密钥,确保只有服务器和客户端知道密钥。

  3. 预共享密钥:在部署应用程序之前,将密钥和初始向量预先共享给服务器和客户端,并确保只有授权的人员可以访问这些密钥。

  4. 密钥管理系统:使用专门的密钥管理系统(KMS)来生成、存储和分发密钥。这样可以确保密钥在存储和分发过程中的安全。

  5. 安全存储:将密钥和初始向量保存在安全的位置,例如使用加密存储或硬件安全模块(HSM)。确保只有授权的人员能够访问这些存储。

  6. 密钥轮换:定期更换密钥和初始向量,以减少被猜测或破解的风险。确保平滑地进行密钥轮换,以避免服务中断。

  7. 访问控制:实施严格的访问控制策略,限制密钥和初始向量的访问权限,并记录密钥的使用情况,以便检测任何潜在的滥用。

  8. 安全审计和监测:实时监测和审计密钥和初始向量的使用情况,并记录任何异常活动或潜在威胁。

综合以上建议,需根据具体的安全需求和要求来选择和实现合适的方法来保护密钥和初始向量的安全性。请注意,确保服务器和客户端之间的通信是安全且可靠的,同时采取必要的防护措施来保护密钥和初始向量的机密性和完整性。

posted @   多见多闻  阅读(475)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示