gpt4 book ai didi

c# - 如何从 AES 256 加密文件中获取文件类型

转载 作者:太空宇宙 更新时间:2023-11-03 15:17:29 25 4
gpt4 key购买 nike

我正在尝试制作一个可以加密和解密文件的控制台应用程序。我给加密文件一个自定义文件扩展名“.aes”(例如 samplefile.aes),现在问题是当我解密文件时,无法识别加密文件的原始扩展名是什么。我有机会从 AES 256 加密文件中获取文件类型吗?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Security.Cryptography;

namespace FileEncryption
{
class Program
{
static void Main(string[] args)
{
if (args.Length < 2)
{
Environment.ExitCode = 1;
Console.Error.WriteLine(Strings.CommandlineUsage);
return;
}

bool encrypt = args[0].StartsWith("-e", StringComparison.InvariantCultureIgnoreCase);
bool decrypt = args[0].StartsWith("-d", StringComparison.InvariantCultureIgnoreCase);

if (!(encrypt || decrypt))
{
Environment.ExitCode = 1;
Console.Error.WriteLine(Strings.CommandlineUnknownMode);
return;
}

string inputname = (args.Length >= 3) ? args[2] : null;

if (inputname != null && !File.Exists(inputname))
{
Environment.ExitCode = 2;
Console.Error.WriteLine(Strings.CommandlineInputFileNotFound);
return;
}

byte[] passwordBytes = Encoding.UTF8.GetBytes(args[1]);
// Hash the password with SHA256
passwordBytes = SHA256Managed.Create().ComputeHash(passwordBytes);

try
{
if (encrypt)
{
//Encrypt file
byte[] bytesToBeEncrypted = File.ReadAllBytes(inputname);
byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);

//Save encrypted file
string fileEncrypted = inputname.Remove(inputname.IndexOf('.')) + ".aes";
File.WriteAllBytes(fileEncrypted, bytesEncrypted);
}
else
{
byte[] bytesToBeDecrypted = File.ReadAllBytes(inputname);
byte[] bytesDecrypted = AES_Decrypt(bytesToBeDecrypted, passwordBytes);

string file = inputname;
File.WriteAllBytes(file, bytesDecrypted);
}
Environment.ExitCode = 0;
}
catch (Exception ex)
{
Console.Error.WriteLine(string.Format(Strings.CommandlineError, ex.Message));
}
}


//***********************************************************************************************
// --- HELPER FUNCTIONS ---
//*

//Encrypt File
public static byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
{
byte[] encryptedBytes = null;

// Set your salt here, change it to meet your flavor:
// The salt bytes must be at least 8 bytes.
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;

var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);

AES.Mode = CipherMode.CBC;

using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
cs.Close();
}
encryptedBytes = ms.ToArray();
}
}

return encryptedBytes;
}

//Decrypt File
public static byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
{
byte[] decryptedBytes = null;

// Set your salt here, change it to meet your flavor:
// The salt bytes must be at least 8 bytes.
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;

var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);

AES.Mode = CipherMode.CBC;

using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
cs.Close();
}
decryptedBytes = ms.ToArray();
}
}

return decryptedBytes;
}
}
}

我知道加密文件的本质是不识别原始扩展名的。我要做的是,当我加密文件时,我会给它 .originalextension.aes(例如 picture.png.aes),然后当我解密它时,我只需要删除 .aes 扩展名。只是想知道这是不是一个好方法?

最佳答案

文件类型是否需要加密隐藏是用户需求。您可能只想保护内容而不是文件类型。请注意,文件大小也可以向“攻击者”提供提示。是否需要隐藏此类元数据也取决于您。

如果没有扩展名,您可以使用文件指纹识别查看文件内容。许多文件格式都给出了一些关于它们是什么的提示。例如,猜测 .txt 文件的字符编码当然是可能的。 JPG 文件具有 JPG header ,zip 存档等也是如此。通常这些工具输出 MIME 文件类型(因为扩展名并不总是定义明确或标准化)。

在 GNU 系统上,您可以为此使用 file 命令行。这种指纹识别也用于许多内容管理系统 (CMS)。因此,您可以查看使用您的语言的 CMS,并尝试过滤掉其中的 file 命令功能。

或者,现在您知道了正确的搜索关键字,您可以在 StackOverflow 上简单地找到它:Using .NET, how can you find the mime type of a file based on the file signature not the extension在输入“指纹文件类型 c# mime”时被列为第 3 次命中。

请注意,由于扩展并不总是定义得那么好,您可能无法通过这种方式取回原始扩展。为此,您需要以明文(在文件名中)存储扩展名,增加文件名大小(!),或者您可以将其与数据一起加密存储。您必须为此创建一个加密协议(protocol)。

关于c# - 如何从 AES 256 加密文件中获取文件类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38449626/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com