Ejemplo n.º 1
0
        /// <summary>
        /// Decrypts a given message using the user's password-protected private key
        /// </summary>
        /// <param name="cipherMessage">The message to be decrypted</param>
        /// <param name="password">The user's password used to retrieve the user's private key</param>
        /// <returns>Decrypted message</returns>
        public static string DecryptMessage(string cipherMessage, string password)
        {
            bool   isSigned = false;
            string encryptedCryptKey;
            string encryptedAuthKey;
            string message;
            string signature;
            string pubKey = null;

            using (StringReader sr = new StringReader(cipherMessage))
            {
                string line;
                while ((line = sr.ReadLine()) != null)
                {
                    if (line == greeting)
                    {
                        break;
                    }
                }
                while ((line = sr.ReadLine()) != null)
                {
                    if (line == cryptKeyHeader)
                    {
                        break;
                    }
                }
                encryptedCryptKey = sr.ReadLine();

                while ((line = sr.ReadLine()) != null)
                {
                    if (line == authKeyHeader)
                    {
                        break;
                    }
                }
                encryptedAuthKey = sr.ReadLine();

                while ((line = sr.ReadLine()) != null)
                {
                    if (line == messageHeader)
                    {
                        break;
                    }
                }
                message = sr.ReadLine();

                while ((line = sr.ReadLine()) != null)
                {
                    if (line == signatureHeader)
                    {
                        isSigned = true;
                        break;
                    }
                }
                signature = sr.ReadLine();
                while ((line = sr.ReadLine()) != null)
                {
                    if (line == pubKeyHeader)
                    {
                        while ((line = sr.ReadLine()) != pubKeyTail)
                        {
                            pubKey += line;
                        }
                    }
                }
            }
            while (encryptedAuthKey.Length % 4 != 0)
            {
                encryptedAuthKey += "=";
            }
            while (signature != null && signature.Length % 4 != 0)
            {
                signature += "=";
            }
            while (encryptedCryptKey.Length % 4 != 0)
            {
                encryptedCryptKey += "=";
            }
            while (message.Length % 4 != 0)
            {
                message += "=";
            }
            RSAParameters keys = KeyVault.RetrieveRSAParams(password);

            byte[] encryptedCryptKeyBytes = Convert.FromBase64String(encryptedCryptKey);
            byte[] encryptedAuthKeyBytes  = Convert.FromBase64String(encryptedAuthKey);

            byte[] cryptKey         = RSAEncryption.DecryptRSA(encryptedCryptKeyBytes, keys);
            byte[] authKey          = RSAEncryption.DecryptRSA(encryptedAuthKeyBytes, keys);
            string plainTextMessage = AESThenHMAC.Decrypt(message, cryptKey, authKey);

            if (isSigned)
            {
                RSAParameters pubkey = KeyVault.DeserializeRSAParams(pubKey);
                if (!DigitalSignature.VerifySignature(pubkey, plainTextMessage, signature))
                {
                    string warning = "WARNING: this message appears to have a wrong digital signature.\n\n";
                    plainTextMessage = warning + plainTextMessage;
                }
                else
                {
                    string success = "This message is digitally signed properly.\n\n";
                    plainTextMessage = success + plainTextMessage;
                }
            }
            return(plainTextMessage);
        }