sexta-feira, setembro 20, 2013

Criptografar senhas em C# .net

Estava eu criando uma biblioteca de utilidades que precisarei em um novo projeto em que estou participando e este é todo desenvolvido em .net C#, quando pensei que precisaria traduzir meu algoritmo de criptografia de senhas de Java para C#. E então comecei a pesquisar sobre o assunto criptografia em .net / C#.

Assustei-me um pouco quando vi a quantidade de gente postando a seguinte pergunta por aí "como eu criptografo e 'descriptografo' uma senha em C#?". É sabido (ou deveria ser) que senhas devem ser criptografadas em via de mão única (one way) sem poder ser revertidas novamente. Lembre-se sempre de que uma senha não precisará nunca voltar a ser legível, não é como uma mensagem que eu quero mandar cifrada para, se, interceptada não possa ser lida por pessoas não autorizadas.

Enfim, achei o pacote namespace System.Security.Cryptography e com isso fiz meu algoritmo para criptografar senhas que lhes deixo aqui como dica, inspiração, presente de grego, etc...

using System;
using System.Text;
using System.Security.Cryptography;
 
namespace com.blogspot.jeanjmichel.utilitieslibrary.password
{
    class Program
    {
        /// <summary>
        /// This method will encrypt a password passed by parameter using an
        /// algorithm SHA-1 of 256 bits.
        /// </summary>
        /// <param name="password">
        /// The password in plain text format to be encrypted.
        /// </param>
        /// <returns>
        /// An encrypted password (restrained in 64 characters).
        /// </returns>
        /// <author>
        /// Jean J. Michel (http://jeanjmichel.blogspot.com)
        /// </author>
        private static String EncryptPassword(String password)
        {
            SHA256Managed encryptionAlgorithm = new SHA256Managed();
            byte[] encryptedHash, passwordBytes;
            String encryptedPassword = "";
            
            //The firs step is get the password in bytes.
            UnicodeEncoding ue = new UnicodeEncoding();
            passwordBytes = ue.GetBytes(password);
            
            /*
             * After it, pass the bytes to the algorithm and receives the
             * encrypted hash.
             */
            encryptedHash = encryptionAlgorithm.ComputeHash(passwordBytes);
            
            //Now is just store the hash in a String
            foreach (byte b in encryptedHash)
            {
                encryptedPassword += String.Format("{0:x2}", b);
            }
            
            //And returns it ;)
            return encryptedPassword;
        }
        
        static void Main(string[] args)
        {
            int i = 0;
            
            //Creating a list of my favorites passwords
            String[] myPasswords = {"my5&cR&7P@55w0rD", "5&cR&7",
                                    "boo!", "^..^ oinc oinc!"};
            
            //And preparing a list to receive this passwords encrypted
            String[] myPasswordsEncrypted = new String[myPasswords.Length];
            
            Console.WriteLine("Encripting passwords");
            Console.WriteLine("");
            Console.Write("64 characters scale");
            Console.Write(".........................");
            Console.Write("012345678901234567890123456789");
            Console.WriteLine("0123456789012345678901234567890123");
            Console.WriteLine("");
            
            foreach (String s in myPasswords)
            {
                //Encrypting and store the password
                myPasswordsEncrypted[i++] = EncryptPassword(s);
                
                //Printing the original string and the encrypted string
                Console.WriteLine("Plain text: " +
                                  s.PadRight(20, ' ') +
                                  " Encrypted: " +
                                  myPasswordsEncrypted[--i]);
            }
            
            //This is the expected result for the generation of a password for
            //'5&cR&7' and we will compare it againt the password generated here
            String hashToCompare =
                "936ad4c3854a6b26f3f278702d36b8253e7bd438ac749518b53354079bd77a63";
            
            Console.WriteLine("");
            Console.WriteLine("Comparing two hashes");
            Console.WriteLine("");
            Console.Write("Is euquals ");
            Console.Write("936ad4c3854a6b26f3f278702d36b8253e7bd438ac749518b53354079bd77a63");
            Console.WriteLine(" and the generated hash of 5&cR&7?");
            Console.Write("Answer: ");
            Console.WriteLine(hashToCompare.Equals(EncryptPassword(myPasswords[1])));
            
            Console.Read();
        }
    }
}

Agora é só rodar e conferir o resultado ;)

Um comentário:

TA 05 disse...

Espero um dia chegar nesse nível.. hehehe