You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET中实现加密结果与原字符串等长的安全加密与解密?

.NET 实现等长加密解密机制

要实现加密结果与原始数据长度完全一致的加密解密机制,核心是采用一对一的字符/字节映射逻辑,避免使用需要填充的分组加密算法(如AES的CBC/ECB模式)。以下是两种可行的实现方案:

方案一:自定义字符映射加密

基于异或运算和自定义字符集,将每个明文字符映射为目标字符集中的唯一字符,确保长度严格一致。适合对可见字符进行加密的场景。

代码实现

using System;
using System.Text;

public class FixedCharCrypto
{
    // 自定义映射字符集(与示例一致)
    private readonly string _charSet = "abcdeABCDE12345";
    private readonly int _charSetLen;
    // 自定义密钥偏移量,用于增强加密强度
    private readonly int _keyOffset = 7;

    public FixedCharCrypto()
    {
        _charSetLen = _charSet.Length;
    }

    // 加密:明文字符→字符集映射字符
    public string Encrypt(string plainText)
    {
        var cipherBuilder = new StringBuilder();
        foreach (char c in plainText)
        {
            // 以字符ASCII值为基础计算映射索引,加入密钥偏移
            int mapIndex = (c % _charSetLen + _keyOffset) % _charSetLen;
            cipherBuilder.Append(_charSet[mapIndex]);
        }
        return cipherBuilder.ToString();
    }

    // 解密:映射字符→原明文字符
    public string Decrypt(string cipherText)
    {
        var plainBuilder = new StringBuilder();
        foreach (char c in cipherText)
        {
            int charIndex = _charSet.IndexOf(c);
            if (charIndex == -1)
                throw new ArgumentException("密文中包含无效字符");
            
            // 反向偏移计算原字符ASCII值
            int originAscii = (charIndex - _keyOffset + _charSetLen) % _charSetLen;
            plainBuilder.Append((char)originAscii);
        }
        return plainBuilder.ToString();
    }
}

// 使用示例
public class Demo
{
    public static void Main()
    {
        var crypto = new FixedCharCrypto();
        string plain = "Hello Word!";
        string cipher = crypto.Encrypt(plain);
        Console.WriteLine($"加密结果:{cipher}"); // 长度与原字符串一致
        string decrypted = crypto.Decrypt(cipher);
        Console.WriteLine($"解密结果:{decrypted}"); // 输出:Hello Word!
    }
}

方案二:流密码算法(RC4)

流密码会生成与明文长度一致的密钥流,通过逐字节异或完成加密,天然保证等长。安全性比自定义映射更高,适合对任意字节数据加密的场景。

代码实现

using System;
using System.Text;

public class RC4FixedLengthCrypto
{
    private readonly byte[] _key;
    private readonly string _charSet = "abcdeABCDE12345";
    private readonly int _charSetLen;

    public RC4FixedLengthCrypto(string secretKey)
    {
        _key = Encoding.UTF8.GetBytes(secretKey);
        _charSetLen = _charSet.Length;
    }

    // RC4核心逻辑:生成密钥流并完成异或运算(加密解密通用)
    private byte[] RC4Process(byte[] input)
    {
        byte[] sBox = new byte[256];
        byte[] keyBox = new byte[256];
        byte temp;

        // 初始化S盒与密钥盒
        for (int i = 0; i < 256; i++)
        {
            sBox[i] = (byte)i;
            keyBox[i] = _key[i % _key.Length];
        }

        // 置换S盒
        int j = 0;
        for (int i = 0; i < 256; i++)
        {
            j = (j + sBox[i] + keyBox[i]) % 256;
            temp = sBox[i];
            sBox[i] = sBox[j];
            sBox[j] = temp;
        }

        // 生成密钥流并异或加密
        int i1 = 0, j1 = 0;
        byte[] output = new byte[input.Length];
        for (int x = 0; x < input.Length; x++)
        {
            i1 = (i1 + 1) % 256;
            j1 = (j1 + sBox[i1]) % 256;
            temp = sBox[i1];
            sBox[i1] = sBox[j1];
            sBox[j1] = temp;
            int t = (sBox[i1] + sBox[j1]) % 256;
            output[x] = (byte)(input[x] ^ sBox[t]);
        }

        return output;
    }

    // 字符串加密:字节流→字符集映射
    public string EncryptString(string plainText)
    {
        byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
        byte[] encryptedBytes = RC4Process(plainBytes);
        
        var cipherBuilder = new StringBuilder();
        foreach (byte b in encryptedBytes)
        {
            cipherBuilder.Append(_charSet[b % _charSetLen]);
        }
        return cipherBuilder.ToString();
    }

    // 字符串解密:字符集映射→字节流
    public string DecryptString(string cipherText)
    {
        byte[] cipherBytes = new byte[cipherText.Length];
        for (int i = 0; i < cipherText.Length; i++)
        {
            int charIndex = _charSet.IndexOf(cipherText[i]);
            if (charIndex == -1)
                throw new ArgumentException("密文中包含无效字符");
            cipherBytes[i] = (byte)charIndex;
        }

        byte[] decryptedBytes = RC4Process(cipherBytes);
        return Encoding.UTF8.GetString(decryptedBytes);
    }
}

// 使用示例
public class Demo
{
    public static void Main()
    {
        var crypto = new RC4FixedLengthCrypto("MySecureKey123");
        string plain = "Hello Word!";
        string cipher = crypto.EncryptString(plain);
        Console.WriteLine($"加密结果:{cipher}"); // 长度与原字符串一致
        string decrypted = crypto.DecryptString(cipher);
        Console.WriteLine($"解密结果:{decrypted}"); // 输出:Hello Word!
    }
}

注意事项

  1. 自定义映射加密的安全性较低,仅适合对安全性要求不高的场景;流密码(RC4)安全性更强,但需妥善管理密钥。
  2. 若需支持全字符集加密,需确保映射字符集的覆盖范围足够(如包含256个可见字符),避免出现无法映射的情况。
  3. 示例中的密钥偏移量或密钥可根据实际需求自定义,提升加密强度。

内容的提问来源于stack exchange,提问作者Praveen Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:47:02