保存加密的文本,然后使用GUI应用程序打开解密的文本

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

enter image description here我已经构建了一个应用程序,可以在其中输入单词或消息并单击密码按钮,这将生成一个随机密钥并加密该消息,然后可以通过单击解密按钮来解密该消息。我的问题是我的保存和打开按钮的新功能我想以RAW加密格式保存一条消息,然后能够打开和解密该消息以及已加密和先前保存的所有其他消息。我的问题是这不起作用,我认为保存按钮可能有问题,因为我还需要保存密钥以及正确解密消息的消息,这只是我尝试过的事情之一,完全解决了这个问题,我们将不胜感激。此外,我使用的密码是凯撒密码

该图像是我正在工作的应用程序的第一阶段的GUI,消息上城的funk正在加密。显然,下面是代码。

编辑-我曾尝试创建一个元组类来解决我的问题,但我只使用过一次不用介意元组类的类,并且在盯着它看了几个小时后直言不讳地讲了一下,我不知道该怎么办工作会有所帮助。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Win32;
using System.IO;

namespace login_form
{
public partial class Main : Form
{

    public string cipherText;
    public string originalText;
    public string DecipherText;
    public int key;

    public Main()
    {
        InitializeComponent();
    }

    public static char cipher(char ch, int key)
    {
        if (!char.IsLetter(ch))
        {
            return ch;
        }

        char d = char.IsUpper(ch) ? 'A' : 'a';
        return (char)((((ch + key) - d) % 26) + d);
    }

    public static string Encipher(string input, int key)
    {
        string output = string.Empty;

        foreach (char ch in input)
            output += cipher(ch, key);

        return output;
    }

    public static string Decipher(string input, int key)
    {
        return Encipher(input, 26 - key);
    }

    private void Main_Load(object sender, EventArgs e)
    {

    }

    private void btnCipher_Click(object sender, EventArgs e)
    {

        Random rndNumber = new Random();
        tbKey.Text = rndNumber.Next(0, 26).ToString();
        originalText = tbWord.Text;
        try {
            key = Convert.ToInt32(tbKey.Text); 
        }
        catch {
            MessageBox.Show("Invalid Input! Please Try Again"); 
        }

        cipherText = Encipher(originalText, key);

        tbOutput.Text = Convert.ToString(cipherText);
    }

    private void btnDecipher_Click(object sender, EventArgs e)
    {
        DecipherText = tbOutput.Text;
        string DecipherOutput = Decipher(cipherText, key);
        tbDecipheredOutput.Text = Convert.ToString(DecipherOutput);
    }

    private void btnOpen_Click(object sender, EventArgs e)
    {
        var fileContent = string.Empty;
        var filePath = string.Empty;

        using (OpenFileDialog openFileDialog = new OpenFileDialog())
        {
            openFileDialog.InitialDirectory = "c:\\";
            openFileDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
            openFileDialog.FilterIndex = 2;
            openFileDialog.RestoreDirectory = true;

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                //Get the path of specified file
                filePath = openFileDialog.FileName;

                //Read the contents of the file into a stream
                var fileStream = openFileDialog.OpenFile();

                using (StreamReader reader = new StreamReader(fileStream))
                {
                    fileContent = reader.ReadToEnd();
                }
            }
        }
        tbOutput.Text = fileContent;

        MessageBox.Show("Path of File: " + filePath);//shows the path of the file 
    }

    private void btnSave_Click(object sender, EventArgs e)
    {
        SaveFileDialog saveFileDialog1 = new SaveFileDialog();

        saveFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";//the format the file will be saved in 
        saveFileDialog1.FilterIndex = 2;
        saveFileDialog1.RestoreDirectory = true;
        saveFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);//saves the folder to my documents 

        string Content = tbOutput.Text;//saves the contens of textbox output

        if (saveFileDialog1.ShowDialog() == DialogResult.OK)
        {
            try
            {
                File.WriteAllText((saveFileDialog1.FileName), Content);
            }
            catch (IOException)
            {
                MessageBox.Show("File Was not Saved");
            }
        }
    }
  }
}

             using System;
             using System.Collections.Generic;
             using System.Linq;
             using System.Text;
             using System.Threading.Tasks;

          namespace login_form
          {
    class tuple
    {
        int key;
        string cipherText;

        static public void Main()
        {

            // Creating tuple with two elements 

            // Using Create method 

            var My_Tuple = Tuple.Create("lol", 23);

            Console.WriteLine("Element 1: " + My_Tuple.Item1);
            Console.WriteLine("Element 2: " + My_Tuple.Item2);

        }
    }
    }



c# user-interface encryption savefiledialog caesar-cipher
1个回答
0
投票
您必须将密钥存储在某个地方。如果要为每个用户使用不同的密钥,则需要将密钥与值存储在一起,或者将密钥存储在一起或存储在两个字段中。

与您所做的事情不完全相同,但是在我的加密项目中,我必须将盐(随机的一组比特)与密码哈希存储在一起,以便以后可以验证密码哈希并添加4竖线字符||||在一起。

所以我最后得到一个像[PasswordHash] |||| [Salt]]这样的字符串>

它像这样以二进制数组形式出现:

-加密位示例

ꊧ汴皤雦㇋袭ᆐ||||뷁綊ꮱ⨭쇕ꐱ�

-然后,我对上面的内容进行加密,以便可以将其存储在SQL中以供以后验证。

Z / if9FTkP5dbJvaxsPIhsoX0v7ZyChFr7IdxZ / mAZzqYP7gWi6sVTDOQZw4KcSEJHwv5ThTuQIKGkRItLi1ree82mXdiHc5ru2l92m1zDRc =

这是我在Stack Overflow上遇到麻烦的地方,但是如果可以帮助一个人,我对此表示满意。我有一个开源项目:DataJuggler.Core.Cryptography(.Net Core)

https://github.com/DataJuggler/DataJuggler.Core.Cryptography

我将发布一个课程,如果您需要整个项目,可以查看其余课程:

Nuget:DataJuggler.Core.UltimateHelper

#region using statements using System; using System.Text; using System.Security.Cryptography; using Konscious.Security.Cryptography; using System.Linq; using DataJuggler.UltimateHelper.Core; using DataJuggler.Core.Cryptography.Objects; #endregion namespace DataJuggler.Core.Cryptography { #region class CryptographyHelper /// <summary> /// This object hands all encryption for this application. /// </summary> public class CryptographyHelper { #region Private Variables // We can use a fixed pepper for the PBKDF2 salt. private static byte[] _pepper = new byte[] { 0x04, 0xC5, 0x02, 0xF8, 0xD3, 0xD4, 0x23, 0xB9 }; public const string DefaultPassword = "NotASecret"; #endregion #region Methods #region CreateSalt() /// <summary> /// This method creates a byte array to use /// </summary> /// <returns></returns> private static byte[] CreateSalt() { // initial value byte[] buffer = null; // Create a strong random number generator using (var rng = new RNGCryptoServiceProvider()) { buffer = new byte[16]; rng.GetBytes(buffer); } // return value return buffer; } #endregion #region DecryptString(string stringToDecrypt, string password) /// <summary> /// Decrypts a string passed in. /// </summary> /// <param customerName="stringToDecrypt">String that needs to be deciphered.</param> /// <param customerName="ProductPassword">Code to unlock this productPassword.</param> /// <returns></returns> public static string DecryptString(string stringToDecrypt, string password) { // initial value string decryptedValue = ""; try { // if both strings exist if (TextHelper.Exists(stringToDecrypt, password)) { var ivAndCiphertext = Convert.FromBase64String(stringToDecrypt); if (ivAndCiphertext.Length >= 16) { var iv = new byte[16]; var ciphertext = new byte[ivAndCiphertext.Length - 16]; Array.Copy(ivAndCiphertext, 0, iv, 0, iv.Length); Array.Copy(ivAndCiphertext, iv.Length, ciphertext, 0, ciphertext.Length); using (var aes = AesManaged.Create()) using (var pbkdf2 = new Rfc2898DeriveBytes(password, _pepper, 32767)) { var key = pbkdf2.GetBytes(32); aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; aes.Key = key; aes.IV = iv; // create a new Decryptor using (var aesTransformer = aes.CreateDecryptor()) { // get a byte array of the plain text var plaintext = aesTransformer.TransformFinalBlock(ciphertext, 0, ciphertext.Length); // set the return value decryptedValue = Encoding.UTF8.GetString(plaintext); } } } } } catch { } // return value return decryptedValue; } #endregion #region DecryptString(string stringToDecrypt) /// <summary> /// This method decrypts a string using the default password. /// </summary> /// <param name="stringToDecrypt"></param> /// <returns></returns> public static string DecryptString(string stringToDecrypt) { // return value return DecryptString(stringToDecrypt, DefaultPassword); } #endregion #region EncryptString(string stringToEncrypt, string password) /// <summary> /// Encrypts a strings passed in using CBC mode and a moderately decent KDF. Does not provide integrity. /// This method will return a different value every time called, yet will still decrypt correctly. /// </summary> /// <param customerName="stringToEncrypt">String to encrypt</param> /// <param customerName="productPassword">productPassword needed to unlock encrypted string</param> /// <returns>A new string that must have the same productPassword passed in to unlock.</returns> public static string EncryptString(string stringToEncrypt, string password) { // initial value string encryptedString = ""; try { // if both strings exist if (TextHelper.Exists(stringToEncrypt, password)) { // Remember to dispose of types that implement IDisposable - this old code had lots of memory leaks. using (var aes = AesManaged.Create()) using (var pbkdf2 = new Rfc2898DeriveBytes(password, _pepper, 32767)) // MD5 is insecure as KDF, we use PBKDF2 instead. using (var rng = new RNGCryptoServiceProvider()) { var key = pbkdf2.GetBytes(32); // Let's use AES-256. var iv = new byte[16]; rng.GetBytes(iv); // We always create a new, random IV for each operation. var plaintext = Encoding.UTF8.GetBytes(stringToEncrypt); // We use UTF8 aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; aes.Key = key; aes.IV = iv; using (var aesTransformer = aes.CreateEncryptor()) { var ciphertext = aesTransformer.TransformFinalBlock(plaintext, 0, plaintext.Length); var ivAndCiphertext = new byte[iv.Length + ciphertext.Length]; Array.Copy(iv, 0, ivAndCiphertext, 0, iv.Length); Array.Copy(ciphertext, 0, ivAndCiphertext, iv.Length, ciphertext.Length); encryptedString = Convert.ToBase64String(ivAndCiphertext); } } } } catch { } // return value return encryptedString; } #endregion #region EncryptString(string stringToEncrypt) /// <summary> /// Override that uses default password /// </summary> /// <param name="stringToEncrypt"></param> /// <returns></returns> public static string EncryptString(string stringToEncrypt) { return EncryptString(stringToEncrypt, DefaultPassword); } #endregion #region GeneratePasswordHash(string password, int verifyRetries = 0) /// <summary> /// This method hashes the password using Konscious.Security.Cryptography's implementation of Argon2. /// The salt is returned with the password separated by 4 | (pipe characters I think is the name). /// You can decrypt from the encrypted password hash to determine the passwordhash and salt, but you cannot decrypt from /// password hash back to the password. /// This method uses the default password, which is NotASecret. /// </summary> /// <param name="password">The password to create a hash for</param> /// <param name="verifyRetries">If verify retries is above 0, this method will attempt to verify /// the generated password hash with the same credentials. If it can't be verified, it will retry /// up until this value for retries count. The value must be between 0 and 3. After 3 it fails.</param> /// <returns></returns> public static string GeneratePasswordHash(string password, int verifyRetries = 0) { // call the override return GeneratePasswordHash(password, DefaultPassword, verifyRetries); } #endregion #region GeneratePasswordHash(string password, string keyCode, int verifyRetries = 0) /// <summary> /// This method hashes the password using Konscious.Security.Cryptography's implementation of Argon2. /// The salt is returned with the password separated by 4 | (pipe characters I think is the name). /// You can decrypt from the encrypted password hash to determine the passwordhash and salt, but you cannot decrypt from /// password hash back to the password. /// </summary> /// <param name="password">The password to create a hash for</param> /// <param name="keyCode">A keycode string you create that is used to encrypt/decrypt the password hash /// after it is created. You can decrypt from the encrypted password hash to determine the passwordhash and salt, but you cannot decrypt from /// password hash back to the password. /// </param> /// <param name="verifyRetries">If verify retries is above 0, this method will attempt to verify /// the generated password hash with the same credentials. If it can't be verified, it will retry /// up until this value for retries count. The value must be between 0 and 3. After 3 it fails.</param> /// <returns></returns> public static string GeneratePasswordHash(string password, string keyCode, int verifyRetries = 0) { // get the passwordHash string passwordHash = null; // local bool verified = false; // if the password exists if (TextHelper.Exists(password, keyCode)) { // get the passwordHash passwordHash = HashPart1(password, keyCode); // it will only try up to 3 times, then it bails if ((verifyRetries > 0) && (verifyRetries <= 3)) { // try up to 3 times if verifyRetries is set to 3 for (int x = 0; x < verifyRetries; x++) { // if all 3 strings exist if (TextHelper.Exists(password, password, keyCode)) { // does verified = VerifyHash(password, keyCode, passwordHash); } // if the value for verified is true if (verified) { // break out of the loop break; } // get the passwordHash (again) passwordHash = HashPart1(password, keyCode); } // if not veriified if (!verified) { // password hash could not be created passwordHash = ""; } } } // return value return passwordHash; } #endregion #region HashPart1(string password, string keyCode) /// <summary> /// This method is used to call some portions of the GeneratePasswordHash /// multiple times. /// </summary> /// <param name="part1"></param> /// <param name="keyCode"></param> /// <returns></returns> private static string HashPart1(string password, string keyCode) { // initial value string part1 = ""; try { // Update 1.0.9 create the salt every time as the salt might be the problem (?) byte[] salt = CreateSalt(); // get the byte array byte[] passwordBits = HashPassword(password, salt); // create the hashInfo PasswordHashInfo hashInfo = new PasswordHashInfo(passwordBits, salt); // get the hashInfo string partI = hashInfo.ToString(); // set the return value part1 = EncryptString(partI, keyCode); } catch (Exception error) { // for debugging only for now, I may return a response one day DebugHelper.WriteDebugError("HashPart1", "CryptographyHelper", error); // explicit set to null part1 = ""; } // return value return part1; } #endregion #region HashPassword(string password, byte[] salt) /// <summary> /// Hash this password /// </summary> /// <param name="password"></param> /// <param name="keyCode"></param> /// <param name="salt"></param> /// <returns></returns> private static byte[] HashPassword(string password, byte[] salt) { // initial value byte[] hash = null; // if all 3 strings exist if (TextHelper.Exists(password)) { // Create a new instance of an 'Argon2id' object. var argon2 = new Argon2id(Encoding.Unicode.GetBytes(password)); argon2.Salt = salt; argon2.DegreeOfParallelism = 8; // four cores argon2.Iterations = 2; argon2.MemorySize = 1024 * 1024; // 1 GB // get the hash hash = argon2.GetBytes(16); } // return value return hash; } #endregion #region VerifyHash(string userTypedPassword, string storedPasswordHash) /// <summary> /// This method is used to verify the Hash created is the same as a hash stored in the database. /// This method uses the default password, which is NotASecret. If you stored the password with a keycode /// you must use that keycode to decrypt and if you used the default value to encrypt you must use the default /// password to decrypt. /// </summary> /// <param name="userTypedPassword">The password typed in by a user for a login attempt.</param> /// <param name="storedPasswordHash">The password hash that is stored with the salt.</param> /// <returns></returns> public static bool VerifyHash(string userTypedPassword, string storedPasswordHash) { return VerifyHash(userTypedPassword, DefaultPassword, storedPasswordHash); } #endregion #region VerifyHash(string userTypedPassword, string keyCode, string storedPasswordHash) /// <summary> /// This method is used to verify the Hash created is the same as a hash stored in the database. /// </summary> /// <param name="password"></param> /// <param name="keyCode"></param> /// <param name="salt"></param> /// <returns></returns> public static bool VerifyHash(string userTypedPassword, string keyCode, string storedPasswordHash) { // initial value bool verified = false; try { // locals // get the password up until the separator string password = ""; string salty = ""; byte[] salt = null; byte[] storedHash = null; // if all the parameters exist if (TextHelper.Exists(userTypedPassword, keyCode, storedPasswordHash)) { // we must first decrypt the storedPasswordHash with the keycode string decryptedHash = DecryptString(storedPasswordHash, keyCode); // if the decryptedHash exists if (TextHelper.Exists(decryptedHash)) { // get the index of the 4 pipe characters int index = decryptedHash.IndexOf("||||"); // if the index was found if (index >= 0) { // get the password password = decryptedHash.Substring(0, index); salty = decryptedHash.Substring(index + 4); salt = Encoding.Unicode.GetBytes(salty); storedHash = Encoding.Unicode.GetBytes(password); } // now verify with the override verified = VerifyHash(userTypedPassword, salt, storedHash); } } } catch { } // return value return verified; } #endregion #region VerifyHash(string password, byte[] salt, byte[] storedHash) /// <summary> /// This method is used to verify the Hash created is the same as the /// </summary> /// <param name="password"></param> /// <param name="keyCode"></param> /// <param name="salt"></param> /// <param name="newHash"></param> /// <returns></returns> public static bool VerifyHash(string password, byte[] salt, byte[] storedHash) { // initial value bool verified = false; // if all the parameters exist if (TextHelper.Exists(password) && (salt.Length > 0) && (storedHash.Length > 0)) { // generate the loginHash again var newHash = HashPassword(password, salt); // set the return value verified = storedHash.SequenceEqual(newHash); } // return value return verified; } #endregion #endregion } #endregion }

以及使用上述项目的示例项目:https://github.com/DataJuggler/Blazor.Crypto

并且现场演示在我的网站上:https://blazorcrypto.datajuggler.com/

视频教程在这里:https://youtu.be/w4NrmpeHykE

并且对于不想帮助那位可能会阅读此帖子或代码的1个人有用的Stack Overflow主持人,为什么不希望他们学习?

[如果我冒犯了任何人,对不起。如果1个人学到了一些东西或发现任何免费的有用代码,则它不是垃圾邮件。互联网上没有一个地方免费为免费提供代码的开发人员与其他可能需要它的开发人员进行交流。

谢谢

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