Jump to content

Windows form c#, encryption and adding additional character

Go to solution Solved by Razhan,

 

How do I implement a seed in such a way that the key uses the seed to encrypt and decrypt. 

For example:

Key = {3, 2, 4, 9, 5, 8, 1, 7};
aaa = 2yyy
 
This means that every time the password is encrypted it uses different keys based on the seed.
 
static private List<char> Charset =            new List<char>("PQOWIEURYTLAKSJDHFGMZNXBCV"                + "olpikmujnyhbtgvrfcedxwszaq"                + "1597362480"                + "~!@#$%^&*()_+"                + "PQOWIEURYTLAKSJDHFGMZNXBCV"                + "olpikmujnyhbtgvrfcedxwszaq"                + "1597362480"                + "~!@#$%^&*()_+");       static List<int> Key = new List<int>()       {3,7,2,8,9,12,45,24,35,46,74,56,82,12,34,22,72,       };        static public string Encrypt(string plain, int iv = 55)        {            string cipher = "";            int key = iv % 75;            foreach (char i in plain)            {                key += Charset.IndexOf(i);                key %= 75;                cipher += Charset.ElementAt(key);            }            return cipher;        }        static public string Decrypt(string cipher, int iv = 55)        {            string plain = "";            int key = iv % 75;            int oldkey = 0;            foreach (char i in cipher)            {                oldkey = key;                key = Charset.LastIndexOf(i);                plain += Charset.ElementAt((key + 75 - oldkey) % 75);            }            return plain;        }    }
 

I've put in this code as the seed:

static List<int> Key = new List<int>()       {3,7,2,8,9,12,45,24,35,46,74,56,82,12,34,22,72,       };

This is a very simple cipher algorithm, so you have limited options. The real "key" is somehow the permutation of characters you have in the Charset. However, you could use the InitializationVector as some sort of key. A password encrypted with this algorithm and a specific iv will only be decrypted using that same iv.

 

Bear in mind the iv range is limited to exactly 75 numers (the range from 0 to 74), any IV higher than that is redundant (the iv 75 is equal to 0, 76 to 1...)

 

The code is already prepared to use different ivs. By default, if you call Encrypt(string) it will encrypt the code using 55 as the iv, but you can call Encrypt(string, int) to use a different IV.

 

For example:

string encrypted = Encrypt("Password", 24);

To decrypt this, you will need to call:

string decrypted = Decrypt(decrypted, 24);

Calling:

string decrypted = Decrypt(decrypted);

Will generate garbarge (most likely, never tried)

 

Is this what you were looking for? Using a "random" key is not really a good option, as you need to know which one is used to decrypt the password

 

PS: If you really, really want to have a seed to dictate the key we are going to use, you could do something like (I do not have access to VisualStudio right now, there may be some stupid mistakes in the code):

public static int GetKey(string seed){  Random rdgen = new Random(seed.GetHashCode());  return rdgen.NextInt(75);} public static int GetKey(int seed){  Random rdgen = new Random(seed);  return rdgen.NextInt(75);}

 

You could call this GetKey() method to choose a key between 0 and 74 based on a string or int seed. The method will choose the same key for the same seed, but as the whole domain for keys is only 75... well, there are going to be a lot of collisions

 

Hey man I was trying to do AES on my code, btw it's a windows form. So I did this, I'm able to build but when I debug, visual studio will crash which means there are some problems with the codes I did. Could you provide a sample or correct any mistakes here? Thanks.

 

 class CipherMachine    {        static public string Encrypt    (        string plain = "",        string passPhrase = "Pas5pr@se",        string saltValue = "s@1tValue",        string hashAlgorithm = "SHA1",        int passwordIterations = 2,        string initVector = "@1B2c3D4e5F6g7H8",        int keySize = 256    )        {            byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);            byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);            byte[] plainTextBytes = Encoding.UTF8.GetBytes(plain);            PasswordDeriveBytes Password = new PasswordDeriveBytes            (                passPhrase,                saltValueBytes,                hashAlgorithm,                passwordIterations            );            byte[] keyBytes = Password.GetBytes(keySize / 8);            RijndaelManaged symmetricKey = new RijndaelManaged();            symmetricKey.Mode = CipherMode.CBC;            ICryptoTransform encryptor = symmetricKey.CreateEncryptor            (                keyBytes,                initVectorBytes            );            MemoryStream memoryStream = new MemoryStream();            CryptoStream cryptoStream = new CryptoStream            (                memoryStream,                encryptor,                CryptoStreamMode.Write            );            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);            cryptoStream.FlushFinalBlock();            byte[] cipherTextBytes = memoryStream.ToArray();            memoryStream.Close();            cryptoStream.Close();            string cipher = Convert.ToBase64String(cipherTextBytes);            return cipher;        }        static public string Decrypt        (            string cipher,            string passPhrase = "Pas5pr@se",            string saltValue = "s@1tValue",            string hashAlgorithm = "SHA1",            int passwordIterations = 2,            string initVector = "@1B2c3D4e5F6g7H8",            int keySize = 256        )        {            byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);            byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);            byte[] cipherTextBytes = Convert.FromBase64String(cipher);            PasswordDeriveBytes Password = new PasswordDeriveBytes            (                passPhrase,                saltValueBytes,                hashAlgorithm,                passwordIterations            );            byte[] keyBytes = Password.GetBytes(keySize / 8);            RijndaelManaged symmetricKey = new RijndaelManaged();            symmetricKey.Mode = CipherMode.CBC;            ICryptoTransform decryptor = symmetricKey.CreateDecryptor            (                keyBytes,                initVectorBytes            );            MemoryStream memoryStream = new MemoryStream(cipherTextBytes);            CryptoStream cryptoStream = new CryptoStream            (                memoryStream,                decryptor,                CryptoStreamMode.Read            );            byte[] plainTextBytes = new byte[cipherTextBytes.Length];            int decryptedByteCount = cryptoStream.Read            (                plainTextBytes,                0,                plainTextBytes.Length            );            memoryStream.Close();            cryptoStream.Close();            string plain = Encoding.UTF8.GetString            (                plainTextBytes,                0,                decryptedByteCount            );            return plain;        }    }}

Btw, when doing AESManaged or RijndaelManaged, is it a must to put in this?

using System.IO;using System.Security.Cryptography;

Thanks for all your help!

 

 

Ok, so first, the easy question

 

In the code you are using MemoryStream, so yes, you need the using for System.IO. Also, RijndaelManaged (and many other classes in your code) are from System.Security.Cryptography, so both usings are a must

 

Regarding the code, I think it is Ok. I have created a simple program calling your CipherMachine:

using System;class Program{    static void Main(string[] args)    {        string plain = "This is the text to cipher";        string pass = "This is the pasphrase";         string encrypted = CipherMachine.Encrypt(plain, pass);        string decrypted = CipherMachine.Decrypt(encrypted, pass);        Console.WriteLine("PlainText: {0}", plain);        Console.WriteLine("Passphrase: {0}", pass);        Console.WriteLine("Encrypted text: {0}", encrypted);        Console.WriteLine("Decrypted text: {0}", decrypted);        Console.ReadLine();    }}
And it seems to work:
PlainText: This is the text to cipherPassphrase: This is the pasphraseEncrypted text: KqyR4MLVrFfdWw+BcLRoqs+ijzMTJE/Nbn/X5+JDq/k=Decrypted text: This is the text to cipher

I only removed an extra } at the end of your code

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×