带文件IO的解密过程

Decryption process with file IO

我正在尝试制作一个关于密码管理器的控制台应用程序。它具有加密和解密输入的能力,以增加安全性。但是我在解密数据时遇到错误。

更新代码:

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

namespace ProjectNumeroUno
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string[] vs = { };
            Console.Write("Welcome to your personal password database.\nData will be protected, and cannot be accessed directly.\nVery personalized and secure!\n\n1.New Data entry\n2.Display and search\n3.exit\nEnter your option: ");
            string option = Console.ReadLine();
            string path = @"D:\Pass.txt";
            while (option != "3")
            {
                if (option == "1")
                {
                    Console.Write("Enter website: ");
                    string url = Console.ReadLine();
                    Console.Write("Enter username: ");
                    string usr = Console.ReadLine();
                    Console.Write("Enter password: ");
                    string pwd = Console.ReadLine();
                    string mmm = "URL: " + url + " Username: " + usr + " Password: " + pwd;
                    using (Aes Entry = Aes.Create())
                    {
                        Entry.Key = Encoding.Default.GetBytes(new string('j', 16));
                        Entry.IV = Encoding.Default.GetBytes(new string('j', 16));
                        byte[] encrypted = EncryptionOfContent(mmm, Entry.Key, Entry.IV);
                        using (StreamWriter sw = File.AppendText(path))
                        {
                            sw.WriteLine(Encoding.Default.GetString(encrypted));
                        }
                    }
                }
                else if (option == "2")
                {
                    try
                    {
                        string[] lines = Regex.Split(File.ReadAllText(path), "\r\n|\r|\n");
                        byte[][] lineData = lines.Select(l => Encoding.Default.GetBytes(l)).Where(l => l.Length > 0).ToArray();

                        foreach (var data in lineData)
                        {
                            using (Aes entry = Aes.Create())
                            {
                                entry.Key = Encoding.Default.GetBytes(new string('j', 16));
                                entry.IV = Encoding.Default.GetBytes(new string('j', 16));
                                string decrypted = DecryptionOfContent(data, entry.Key, entry.IV);
                                vs.Append(decrypted);
                                Console.WriteLine(decrypted);
                            }
                        }
                    }
                    catch (IOException e)
                    {
                        Console.WriteLine("The file could not be read:");
                        Console.WriteLine(e.Message);
                    }
                }
                Console.Write("\n1.New Data entry\n2.Display and search\n3.exit\nEnter your option: ");
                option = Console.ReadLine();
            }
        }

        static byte[] EncryptionOfContent(string plainText, byte[] Key, byte[] IV)
        {
            // Check arguments.
            if (plainText == null || plainText.Length <= 0)
                throw new ArgumentNullException("plainText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("IV");
            byte[] encrypted;

            // Create an Aes object
            // with the specified key and IV.
            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = Key;
                aesAlg.IV = IV;

                // Create an encryptor to perform the stream transform.
                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

                // Create the streams used for encryption.
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            //Write all data to the stream.
                            swEncrypt.Write(plainText);
                        }
                        encrypted = msEncrypt.ToArray();
                    }
                }
            }

            // Return the encrypted bytes from the memory stream.
            return encrypted;
        }

        static string DecryptionOfContent(byte[] cipherText, byte[] Key, byte[] IV)
        {
            // Check arguments.
            if (cipherText == null || cipherText.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("IV");

            // Declare the string used to hold
            // the decrypted text.
            string plaintext = null;

            // Create an Aes object
            // with the specified key and IV.
            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = Key;
                aesAlg.IV = IV;

                // Create a decryptor to perform the stream transform.
                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

                // Create the streams used for decryption.
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {

                            // Read the decrypted bytes from the decrypting stream
                            // and place them in a string.
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }
            }
            return plaintext;
        }
    }
}

选项 1,似乎工作得很好,当涉及到显示数据时,它在从数据数组中删除尾随的“\n”或“10”和“13”字节后工作。但是,如果我尝试另一个输入,第一个数据和第二个数据之间会有一组“13”和“10”,这会增加字节大小,并且在 [=30 时返回错误=].

错误:

我仍然想要不同输入之间的“\n”,以区分输入,而不是混淆打印。但我该怎么做呢?如何增加字节大小,使其不会导致异常错误?我试过 aesAlg.Blocksize += 2;这也不起作用。

编辑:“如果加密输出不是单行怎么办”问题

这就是呃,我有4个输入,但是加密后,有一个额外的行,就像加密里面有“\n”一样smh。它现在抛出另一个异常。虽然这个错误大约每 5-10 次出现一次,但有时,加密本身会失控,有时它会在加密后开始写入汉字。 :\

您需要将您的加密文本拆分成不带行结束字符的单独数组,然后对每一行进行解密:

string[] lines = Regex.Split(File.ReadAllText(path), "\r\n|\r|\n");
byte[][] lineData = lines.Select(l => Encoding.Default.GetBytes(l)).Where(l => l.Length > 0).ToArray();

foreach (var data in lineData)
{
    using Aes entry = Aes.Create();
    entry.Key = Encoding.Default.GetBytes(new string('j', 16));
    entry.IV = Encoding.Default.GetBytes(new string('j', 16));
    string decrypted = DecryptionOfContent(data, entry.Key, entry.IV);
    Console.WriteLine(decrypted);
}

您可以考虑更改以下几项内容:

  1. 您想使用换行符来分隔不同的输入,但您的代码没有考虑到加密数据本身可能包含换行符。
  2. 由于您使用 WriteLine 写入文件,您最好使用 ReadLine 读取文件,这样您就不需要自己处理换行符。

对于 #1,您可以将 Base64 编码的字符串写入您的文件:

byte[] encrypted = EncryptionOfContent(mmm, Entry.Key, Entry.IV);
...
sw.WriteLine(Convert.ToBase64String(encrypted));

对于 #2,您可以更改读取文件的方式:

var inputs = File.ReadAllLines(path);
foreach (var input in inputs)
{
    var data = Convert.FromBase64String(input);
    ...
    string decrypted = DecryptionOfContent(data, Entry.Key, Entry.IV);
}