本页说明在 .NET Framework 4.8 项目中做对称加解密与简单异或变换。目标框架以 LCode 默认的 .NET 4.8 为准;示例面向 C# 5.0 与 VB.NET(勿用字符串插值、nameof 等)。操作文案以 LCode 中文界面为准。仅需指纹/校验见 哈希与校验;密文落盘见 文件与流读写

选用哪种方式

方式 类型 说明
AES System.Security.Cryptography.Aes 推荐;密钥 16/24/32 字节;本页用 CBC + PKCS7
DES System.Security.Cryptography.DES 密钥 8 字节;已弱,仅兼容旧系统
TripleDES System.Security.Cryptography.TripleDES 密钥 16 或 24 字节;兼容旧系统时优于单 DES
异或(XOR) 自写字节循环 教学/简单混淆;不是安全加密

在 LCode 中使用

  1. 窗体应用入门 建好项目。
  2. 代码中 using System.Security.Cryptography; / Imports System.Security.Cryptography,一般不必再「添加引用」。
  3. 菜单 编译 → 编译解决方案F8)验证。
注意:示例密钥/IV 仅便于演示。生产环境须用安全随机密钥,妥善保管,勿写死在源码中。

AES(加解密)

C#
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

static byte[] AesEncrypt(byte[] plain, byte[] key, byte[] iv)
{
    using (Aes aes = Aes.Create())
    {
        aes.Key = key;
        aes.IV = iv;
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;
        using (ICryptoTransform enc = aes.CreateEncryptor())
        using (MemoryStream ms = new MemoryStream())
        using (CryptoStream cs = new CryptoStream(ms, enc, CryptoStreamMode.Write))
        {
            cs.Write(plain, 0, plain.Length);
            cs.FlushFinalBlock();
            return ms.ToArray();
        }
    }
}

static byte[] AesDecrypt(byte[] cipher, byte[] key, byte[] iv)
{
    using (Aes aes = Aes.Create())
    {
        aes.Key = key;
        aes.IV = iv;
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;
        using (ICryptoTransform dec = aes.CreateDecryptor())
        using (MemoryStream ms = new MemoryStream(cipher))
        using (CryptoStream cs = new CryptoStream(ms, dec, CryptoStreamMode.Read))
        using (MemoryStream outMs = new MemoryStream())
        {
            cs.CopyTo(outMs);
            return outMs.ToArray();
        }
    }
}

byte[] key = Encoding.UTF8.GetBytes("1234567890123456"); // 16 字节
byte[] iv = Encoding.UTF8.GetBytes("abcdefghijklmnop");  // 16 字节
byte[] plain = Encoding.UTF8.GetBytes("LCode demo");
byte[] cipher = AesEncrypt(plain, key, iv);
string text = Encoding.UTF8.GetString(AesDecrypt(cipher, key, iv));
VB.NET
Imports System
Imports System.IO
Imports System.Security.Cryptography
Imports System.Text

Private Shared Function AesEncrypt(plain As Byte(), key As Byte(), iv As Byte()) As Byte()
    Using aes As Aes = Aes.Create()
        aes.Key = key
        aes.IV = iv
        aes.Mode = CipherMode.CBC
        aes.Padding = PaddingMode.PKCS7
        Using enc As ICryptoTransform = aes.CreateEncryptor()
            Using ms As New MemoryStream()
                Using cs As New CryptoStream(ms, enc, CryptoStreamMode.Write)
                    cs.Write(plain, 0, plain.Length)
                    cs.FlushFinalBlock()
                    Return ms.ToArray()
                End Using
            End Using
        End Using
    End Using
End Function

Private Shared Function AesDecrypt(cipher As Byte(), key As Byte(), iv As Byte()) As Byte()
    Using aes As Aes = Aes.Create()
        aes.Key = key
        aes.IV = iv
        aes.Mode = CipherMode.CBC
        aes.Padding = PaddingMode.PKCS7
        Using dec As ICryptoTransform = aes.CreateDecryptor()
            Using ms As New MemoryStream(cipher)
                Using cs As New CryptoStream(ms, dec, CryptoStreamMode.Read)
                    Using outMs As New MemoryStream()
                        cs.CopyTo(outMs)
                        Return outMs.ToArray()
                    End Using
                End Using
            End Using
        End Using
    End Using
End Function

Dim key As Byte() = Encoding.UTF8.GetBytes("1234567890123456")
Dim iv As Byte() = Encoding.UTF8.GetBytes("abcdefghijklmnop")
Dim plain As Byte() = Encoding.UTF8.GetBytes("LCode demo")
Dim cipher As Byte() = AesEncrypt(plain, key, iv)
Dim text As String = Encoding.UTF8.GetString(AesDecrypt(cipher, key, iv))

DES(加解密)

密钥与 IV 均为 8 字节。写法与 AES 相同,把 Aes 换成 DES

C#
byte[] key = Encoding.UTF8.GetBytes("12345678");
byte[] iv = Encoding.UTF8.GetBytes("87654321");
byte[] plain = Encoding.UTF8.GetBytes("hello");
byte[] cipher;
byte[] back;

using (DES des = DES.Create())
{
    des.Key = key;
    des.IV = iv;
    des.Mode = CipherMode.CBC;
    des.Padding = PaddingMode.PKCS7;
    using (ICryptoTransform enc = des.CreateEncryptor())
        cipher = enc.TransformFinalBlock(plain, 0, plain.Length);
    using (ICryptoTransform dec = des.CreateDecryptor())
        back = dec.TransformFinalBlock(cipher, 0, cipher.Length);
}
string text = Encoding.UTF8.GetString(back);
VB.NET
Dim key As Byte() = Encoding.UTF8.GetBytes("12345678")
Dim iv As Byte() = Encoding.UTF8.GetBytes("87654321")
Dim plain As Byte() = Encoding.UTF8.GetBytes("hello")
Dim cipher As Byte()
Dim back As Byte()

Using des As DES = DES.Create()
    des.Key = key
    des.IV = iv
    des.Mode = CipherMode.CBC
    des.Padding = PaddingMode.PKCS7
    Using enc As ICryptoTransform = des.CreateEncryptor()
        cipher = enc.TransformFinalBlock(plain, 0, plain.Length)
    End Using
    Using dec As ICryptoTransform = des.CreateDecryptor()
        back = dec.TransformFinalBlock(cipher, 0, cipher.Length)
    End Using
End Using
Dim text As String = Encoding.UTF8.GetString(back)

TripleDES(加解密)

密钥常用 24 字节(也可用 16)。API 与 DES 相同。

C#
byte[] key = Encoding.UTF8.GetBytes("123456789012345678901234"); // 24
byte[] iv = Encoding.UTF8.GetBytes("abcdefgh");                 // 8
byte[] plain = Encoding.UTF8.GetBytes("hello");
byte[] cipher;
byte[] back;

using (TripleDES tdes = TripleDES.Create())
{
    tdes.Key = key;
    tdes.IV = iv;
    tdes.Mode = CipherMode.CBC;
    tdes.Padding = PaddingMode.PKCS7;
    using (ICryptoTransform enc = tdes.CreateEncryptor())
        cipher = enc.TransformFinalBlock(plain, 0, plain.Length);
    using (ICryptoTransform dec = tdes.CreateDecryptor())
        back = dec.TransformFinalBlock(cipher, 0, cipher.Length);
}
string text = Encoding.UTF8.GetString(back);
VB.NET
Dim key As Byte() = Encoding.UTF8.GetBytes("123456789012345678901234")
Dim iv As Byte() = Encoding.UTF8.GetBytes("abcdefgh")
Dim plain As Byte() = Encoding.UTF8.GetBytes("hello")
Dim cipher As Byte()
Dim back As Byte()

Using tdes As TripleDES = TripleDES.Create()
    tdes.Key = key
    tdes.IV = iv
    tdes.Mode = CipherMode.CBC
    tdes.Padding = PaddingMode.PKCS7
    Using enc As ICryptoTransform = tdes.CreateEncryptor()
        cipher = enc.TransformFinalBlock(plain, 0, plain.Length)
    End Using
    Using dec As ICryptoTransform = tdes.CreateDecryptor()
        back = dec.TransformFinalBlock(cipher, 0, cipher.Length)
    End Using
End Using
Dim text As String = Encoding.UTF8.GetString(back)

异或(XOR)

用同一密钥再异或一次即可还原。仅适合演示或极轻量混淆,勿当安全加密。

C#
static byte[] XorBytes(byte[] data, byte[] key)
{
    byte[] result = new byte[data.Length];
    for (int i = 0; i < data.Length; i++)
        result[i] = (byte)(data[i] ^ key[i % key.Length]);
    return result;
}

byte[] key = Encoding.UTF8.GetBytes("LCodeKey");
byte[] plain = Encoding.UTF8.GetBytes("hello");
byte[] cipher = XorBytes(plain, key);
byte[] back = XorBytes(cipher, key);
string text = Encoding.UTF8.GetString(back);
VB.NET
Private Shared Function XorBytes(data As Byte(), key As Byte()) As Byte()
    Dim result(data.Length - 1) As Byte
    For i As Integer = 0 To data.Length - 1
        result(i) = CByte(data(i) Xor key(i Mod key.Length))
    Next
    Return result
End Function

Dim key As Byte() = Encoding.UTF8.GetBytes("LCodeKey")
Dim plain As Byte() = Encoding.UTF8.GetBytes("hello")
Dim cipher As Byte() = XorBytes(plain, key)
Dim back As Byte() = XorBytes(cipher, key)
Dim text As String = Encoding.UTF8.GetString(back)

易错点

说明
密钥长度 AES 16/24/32;DES 8;TripleDES 16/24;长度不符会抛异常。
IV CBC 模式加解密双方 IV 必须一致;IV 长度随算法块大小(AES 16,DES/3DES 8)。
编码 明文字符串转字节、密文常以 Base64 传输:Convert.ToBase64String / FromBase64String
弱算法 DES / 裸异或勿用于新系统敏感数据;优先 AES。
C# 语言版本 LCode / .NET 4.8 按 C# 5.0:勿用 $"…"nameof 等。

相关阅读