C#需要AES加密

问题描述 投票:0回答:1

我有一个加密字符串和解密它的函数。现在我需要编辑这个字符串并加密它。当我使用这个函数加密和解密时,结果字符串不一样。

原始加密字符串:

APpuC6G3f3cUKaAuOFXOGIo9rwz/+fQ0tBCi6Fk40THVnIT+au7JXkOQHdgPcpQ3VUrXw69rIL+QRsHea5+Q6TxOeuAnzkU8c3UClx6Toe+jOIVi3DlkLIGzE8DmyBArtZYpKTOt4rrOSDyLKifdgcM+MgwuJbDXyXVuQyp2C42zZ1ETPUOF2TSIZKhnMSR43FFy8WEbpKBAjkPmgVpqqhrjabu+JHbj7kPIxGGjDHGaCCyCtFwsk3264Lv4GTp049SCjNNYV0NVcN4wV0MaWMEO0iLuNGkseHuu5Snvp3YzZfXxDBWSLOUXc2zeXL2tA6So9WA5P3lZ/ga5i366EQ==

解密后的原始加密字符串:

{"status":"PASS","data":{"map_path":"VOtKu0.yGT","file_extension":"KAmXWV","username":"damianek","timestamp":9999999999},"message":"Logged in successfully. Your license will run out at 2021-12-03 18:41:39"}

原始解密函数:

public static string Decypher(string var1)
    {
        var1 = var1.Trim();
        byte[] array = Convert.FromBase64String(var1);
        byte[] array2 = new byte[16];
        byte[] array3 = new byte[32];
        byte[] array4 = new byte[array.Length - 48];
        for (int i = 0; i < 16; i++)
        {
            array2[i] = array[i];
        }
        for (int j = 16; j < 48; j++)
        {
            array3[j - 16] = array[j];
        }
        for (int k = 48; k < array.Length; k++)
        {
            array4[k - 48] = array[k];
        }
        ivv = array2;
        Aes aes = Aes.Create();
        aes.Mode = CipherMode.CBC;
        aes.Key = GetToken();
        aes.IV = array2;
        MemoryStream memoryStream = new MemoryStream();
        ICryptoTransform transform = aes.CreateDecryptor();
        CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write);
        string result = string.Empty;
        try
        {
            
            cryptoStream.Write(array4, 0, array4.Length);
            cryptoStream.FlushFinalBlock();
            byte[] array5 = memoryStream.ToArray();
            result = Encoding.ASCII.GetString(array5, 0, array5.Length);
            memoryStream.Close();
            cryptoStream.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.StackTrace);
        }
        return result;
    }

我的加密功能:

public void EncryptStringToBytes()
    {
        string plainText = textBox2.Text;
        byte[] array = Encoding.UTF8.GetBytes(plainText);
        byte[] encrypted;
        using (Aes aesAlg = Aes.Create())
        {
            aesAlg.Key = GetToken();
            aesAlg.IV = new byte[16];
            aesAlg.Mode = CipherMode.CBC;
            var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
            using (var msEncrypt = new MemoryStream())
            {
                using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (var swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }
        textBox3.Text = Convert.ToBase64String(encrypted);
    }

我用原始函数加密和解密后的字符串:

?%j>]???r?????":"KAmXWV","username":"damianek","timestamp":1637955589},"message":"Logged in successfully. Your license will run out at 2021-12-03 18:41:39"}

编辑: 现在加密函数看:

public void EncryptStringToBytes()
    {
        string plainText = textBox2.Text.Trim();
        byte[] array = Encoding.ASCII.GetBytes(plainText);
        byte[] encrypted;
        using (Aes aesAlg = Aes.Create())
        {
            aesAlg.Key = GetToken();
            aesAlg.IV = GetIV();
            aesAlg.Mode = CipherMode.CBC;
            var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
            using (var msEncrypt = new MemoryStream())
            {
                msEncrypt.Write(aesAlg.Key, 0, aesAlg.Key.Length);
                msEncrypt.Flush();
                using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    csEncrypt.Write(aesAlg.Key, 0, aesAlg.Key.Length);
                    using (var swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }
        textBox3.Text = Convert.ToBase64String(encrypted);
    }

但是加密解密后的字符串看起来:

;???En  Dp??g???{"status":"PASS","data":{"map_path":"VOtKu0.yGT","file_extension":"KAmXWV","username":"damianek","timestamp":1637955589},"message":"Logged in successfully. Your license will run out at 2021-12-03 18:41:39"}
c# encryption aes
1个回答
1
投票

我的 C# AES 实现

来自我的回答AES Crypto C# compatible Java

  • IV在每个加密过程中都是随机的,以获得具有相同文本的不同输出,并避免入侵者/攻击者轻松获得原始文本。

  • 默认模式为CBC。

  • 使用的编码是UTF-8。 UTF-8 是网络上使用最广泛的编码。

您可以在 https://replit.com/@JomaCorpFX/AesCbcEncrypt#main.cs 上测试/运行此代码

参考文献

IV
使用AES和CBC时,IV有必要保密吗?

生成用于加密和解密的密钥 - Microsoft

创建和管理密钥是加密过程的重要组成部分。对称算法需要创建密钥和初始化向量 (IV)。您必须对不应解密您的数据的任何人保密此密钥。 IV 不必保密,但每次会话都应更改

代码

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

public enum HashAlgorithm
{
    MD5,
    SHA1,
    SHA256,
    SHA384,
    SHA512
}

public class HashManager
{
    public static byte[] ToRawHash(byte[] data, HashAlgorithm algorithm)
    {
        byte[] hash;
        switch (algorithm)
        {
            case HashAlgorithm.MD5:
                MD5 md5 = MD5.Create();
                hash = md5.ComputeHash(data, 0, data.Length);
                return hash;
            case HashAlgorithm.SHA1:
                SHA1Managed sha1 = new SHA1Managed();
                hash = sha1.ComputeHash(data);
                return hash;
            case HashAlgorithm.SHA256:
                SHA256Managed sha256 = new SHA256Managed();
                hash = sha256.ComputeHash(data);
                return hash;
            case HashAlgorithm.SHA384:
                SHA384Managed sha384 = new SHA384Managed();
                hash = sha384.ComputeHash(data);
                return hash;
            case HashAlgorithm.SHA512:
                SHA512Managed sha512 = new SHA512Managed();
                hash = sha512.ComputeHash(data, 0, data.Length);
                return hash;
            default:
                throw new ArgumentException("Invalid Algorithm");
        }
    }
}

public class AesManager
{
    private const int MAX_IV_LENGTH = 16;
    private const int MAX_KEY_LENGTH = 32;

    private static byte[] GenerateValidKey(byte[] keyBytes)
    {
        byte[] ret = new byte[MAX_KEY_LENGTH];
        byte[] hash = HashManager.ToRawHash(keyBytes, HashAlgorithm.SHA256);
        Array.Copy(hash, ret, MAX_KEY_LENGTH);
        return ret;
    }


    public static byte[] EncryptRaw(byte[] PlainBytes, byte[] Key)
    {
        AesManaged AesAlgorithm = new AesManaged()
        {
            Key = GenerateValidKey(Key)
        };
        AesAlgorithm.GenerateIV();
        var Encrypted = AesAlgorithm.CreateEncryptor().TransformFinalBlock(PlainBytes, 0, PlainBytes.Length);
        byte[] ret = new byte[Encrypted.Length + MAX_IV_LENGTH];
        Array.Copy(Encrypted, ret, Encrypted.Length);
        Array.Copy(AesAlgorithm.IV, 0, ret, ret.Length - MAX_IV_LENGTH, MAX_IV_LENGTH);
        return ret;
    }

    public static byte[] DecryptRaw(byte[] CipherBytes, byte[] Key)
    {
        AesManaged AesAlgorithm = new AesManaged()
        {
            Key = GenerateValidKey(Key)
        };
        byte[] IV = new byte[MAX_IV_LENGTH];
        Array.Copy(CipherBytes, CipherBytes.Length - MAX_IV_LENGTH, IV, 0, MAX_IV_LENGTH);
        AesAlgorithm.IV = IV;
        byte[] RealBytes = new byte[CipherBytes.Length - MAX_IV_LENGTH];
        Array.Copy(CipherBytes, RealBytes, CipherBytes.Length - MAX_IV_LENGTH);
        return AesAlgorithm.CreateDecryptor().TransformFinalBlock(RealBytes, 0, RealBytes.Length); ;
    }


    public static String EncryptToBase64(String Plaintext, String Key)
    {
        byte[] PlainBytes = Encoding.UTF8.GetBytes(Plaintext);
        return Base64Manager.ToBase64(EncryptRaw(PlainBytes, Encoding.UTF8.GetBytes(Key)), false);
    }



    public static String DecryptFromBase64(String CipherText, String Key)
    {
        byte[] CiPherBytes = Base64Manager.Base64ToByteArray(CipherText);
        byte[] Encrypted = DecryptRaw(CiPherBytes, Encoding.UTF8.GetBytes(Key));
        return Encoding.UTF8.GetString(Encrypted, 0, Encrypted.Length);
    }

}

public class Base64Manager
{
    public static byte[] Base64ToByteArray(String base64)
    {
        return Convert.FromBase64String(base64);
    }

    public static String ToBase64(byte[] data, Boolean insertLineBreaks = default(Boolean))
    {
        return insertLineBreaks ? Convert.ToBase64String(data, Base64FormattingOptions.InsertLineBreaks) : Convert.ToBase64String(data);
    }
}



public class Program
{
    public static void Main()
    {
        Console.Write("Plain text: ");
        string plainText = Console.ReadLine();
        Console.Write("Password: ");
        string password = Console.ReadLine();
        string encrypted = AesManager.EncryptToBase64(plainText, password);
        Console.WriteLine();

        Console.WriteLine($"Password: {password}" );
        Console.WriteLine();

        Console.WriteLine($"Encrypted: {encrypted}");
        Console.WriteLine();
        
        Console.WriteLine($"Decrypted: {AesManager.DecryptFromBase64(encrypted, password)}");
        Console.ReadLine();
    }
}

输出

© www.soinside.com 2019 - 2024. All rights reserved.