Пример #1
0
        internal void closeDecMpeFile()
        {
            if (_decMpeFileInfo != null)
            {
                DecryptBtn.IsEnabled = false;
                DecQuestionListPanel.Children.RemoveRange(1, DecQuestionListPanel.Children.Count - 1);

                _decMpeFileInfo._encryptedFS.Close();
                _decMpeFileInfo = null;
            }
        }
Пример #2
0
        internal void openDecMpeFile(bool isShowMessage)
        {
            if (File.Exists(DecEncryptedFileTxt.Text) == false)
            {
                return;
            }
            var currentCursor = this.Cursor;

            this.Cursor = Cursors.Wait;

            string message;
            var    decMPEfileInfo = MPECore.readHeader(DecEncryptedFileTxt.Text);

            if (decMPEfileInfo._errorDetailMessage != "")
            {
                if (isShowMessage)
                {
                    message = ResourceService.Current.getMessage("MsgETargetNotMPE") + decMPEfileInfo._errorDetailMessage; // The specified file is not a Multiple Passwords Encrypted file.\r\n\r\nDetailed information:
                    MessageBox.Show(message, "Error", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
                }
                goto EXIT;
            }
            int nQuestions         = decMPEfileInfo._nQuestions;
            int nRequiredPasswords = decMPEfileInfo._nRequiredPasswords;

            // create UI
            _decPasswordTxts = new TextBox[nQuestions];
            setFlag(decMPEfileInfo._flag);

            DecryptBtn.IsEnabled = true;
            DecNumRequiredPasswordsCmb.Items.Clear();
            DecNumRequiredPasswordsCmb.Items.Add(nRequiredPasswords);
            DecNumRequiredPasswordsCmb.SelectedIndex = 0;
            for (int i = 0; i < nQuestions; ++i)
            {
                var question = decMPEfileInfo._decQuestions[i];

                var border = new Border();
                border.BorderThickness = TH_BOADER;
                border.BorderBrush     = Brushes.Gray;
                border.Margin          = TH_MARGIN_T5_R5;

                var scrollViewer = new ScrollViewer();
                scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
                scrollViewer.VerticalScrollBarVisibility   = ScrollBarVisibility.Disabled;
                scrollViewer.Padding = TH_PADDING_5;
                border.Child         = scrollViewer;

                var questionStackPanel = new StackPanel();
                questionStackPanel.Orientation = Orientation.Vertical;
                scrollViewer.Content           = questionStackPanel;

                var hintStackPanel = new StackPanel();
                hintStackPanel.Orientation = Orientation.Horizontal;
                questionStackPanel.Children.Add(hintStackPanel);

                var hintLabel = new Label();
                hintLabel.Content = "Hint" + (i + 1) + ":";
                hintLabel.Width   = HEADER_WIDTH;
                hintStackPanel.Children.Add(hintLabel);

                var hintTextBox = new TextBox();
                hintTextBox.MinWidth  = HINT_WIDTH;
                hintTextBox.IsEnabled = false;
                hintStackPanel.Children.Add(hintTextBox);
                hintTextBox.Text = question.hint;


                var questionRemoveButton = new Button();
                questionRemoveButton.Content   = "X";
                questionRemoveButton.Width     = HINT_REMOVE_BUTTON_WIDTH;
                questionRemoveButton.Margin    = TH_MARGIN_L10;
                questionRemoveButton.IsEnabled = false;
                hintStackPanel.Children.Add(questionRemoveButton);


                var passwordStackPanel = new StackPanel();
                passwordStackPanel.Orientation = Orientation.Horizontal;
                passwordStackPanel.Margin      = TH_MARGIN_T5;
                questionStackPanel.Children.Add(passwordStackPanel);

                var passwordLabel = new Label();
                passwordLabel.Content = "Password:"******"" && isShowMessage)
            {
                message = ResourceService.Current.getMessage("MsgWMPEInvalidFormat") + decMPEfileInfo._warningDetailMessage; // The specified file may not be decrypted properly.\r\n\r\nDetailed information:
                MessageBox.Show(message, "Warning", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK);
            }

            _decMpeFileInfo = decMPEfileInfo;
EXIT:
            this.Cursor = currentCursor;
        }
Пример #3
0
        internal static bool   Decrypt(
            DecMPEFileInfo decMpeFileInfo,
            string[] passwords,
            string outputDir,
            IProgress <string> progress = null)
        {
            int nQuestions         = decMpeFileInfo._nQuestions;
            int nRequiredPasswords = decMpeFileInfo._nRequiredPasswords;

            int nDecryptedQuestionKeys = 0;                                                      // Number of QuestionKeys that could be decoded. (J)複号できたQuestionKeyの数

            int[]  questionKeyIndexes = new int[nRequiredPasswords];                             // Index of QuestionKeys that could be decoded. (J)複号できたQuestionKeyのIndex
            byte[] questionKeys       = new byte[nRequiredPasswords * Crypto.AES_KEY_SIZE_BYTE]; // Combined Question Key (for decrypt dataKey)

            // check password
            for (int i = 0; i < nQuestions && nDecryptedQuestionKeys < nRequiredPasswords; ++i)
            {
                var passwordTxt = passwords[i];
                if (passwordTxt == "")
                {
                    continue;
                }
                var question = decMpeFileInfo._decQuestions[i];

                byte[] password = Encoding.UTF8.GetBytes(passwordTxt);
                for (int j = 0; j < question.nPasswords; ++j)
                {
                    var result = Crypto.decryptByte(question.encryptedQuestionKeys, j * Crypto.AES_KEY_SIZE_BYTE_WITH_PADDING, Crypto.AES_KEY_SIZE_BYTE_WITH_PADDING, password, Crypto.createSalt(i, j));
                    if (result != null)
                    {
                        if (result.Length != Crypto.AES_KEY_SIZE_BYTE)
                        {   // assertion
                            throw new Exception("broken file");
                        }

                        // store question key
                        Buffer.BlockCopy(result, 0, questionKeys, nDecryptedQuestionKeys * Crypto.AES_KEY_SIZE_BYTE, Crypto.AES_KEY_SIZE_BYTE);
                        questionKeyIndexes[nDecryptedQuestionKeys] = i;
                        nDecryptedQuestionKeys += 1;
                        break;
                    }
                }
            }

            if (nDecryptedQuestionKeys < nRequiredPasswords)
            {
                return(false);   // fail. number of passwords is not enough.
            }


            // decrypt data
            byte[]  dataKey      = null;
            int[][] combinaitons = Combination.enumerateCombination(nQuestions, nRequiredPasswords);
            for (int i = 0; i < combinaitons.Length; ++i)
            {
                if (combinaitons[i].SequenceEqual(questionKeyIndexes))
                {
                    dataKey = Crypto.decryptByte(decMpeFileInfo._encryptedDataKeys, i * Crypto.AES_KEY_SIZE_BYTE_WITH_PADDING, Crypto.AES_KEY_SIZE_BYTE_WITH_PADDING, questionKeys);
                    break;
                }
            }

            if (dataKey == null)
            {
                throw new Exception("broken file");
            }

            progress?.Report("(1/3) decripting archive.");
            // OK
            var tmpFileCompress = System.IO.Path.GetRandomFileName();

            try
            {
                using (FileStream zipFS = new FileStream(tmpFileCompress, FileMode.Create))
                {
                    decMpeFileInfo._encryptedFS.Position = decMpeFileInfo._dataStartPosition;
                    Crypto.decryptStream(decMpeFileInfo._encryptedFS, zipFS, dataKey);
                }

                // ZipFile.ExtractToDirectory can not read files unless Close() is done on zipFS
                //(J) zipFS を Close() しないと ZipFile.ExtractToDirectory はファイルを読み込めない
                try
                {
                    progress?.Report("(2/3) creating output file(s).");
                    System.IO.Compression.ZipFile.ExtractToDirectory(tmpFileCompress, outputDir);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            finally
            {
                File.Delete(tmpFileCompress);
            }
            progress?.Report("(3/3) finished.");

            return(true);    // succeed
        }
Пример #4
0
        internal static DecMPEFileInfo readHeader(string encryptedFileName)
        {
            // Anaryze MPE File.
            //(J) MPEファイル解析
            string errorDetailMessage   = "";
            string warningDetailMessage = "";
            var    encryptedFS          = new FileStream(encryptedFileName, FileMode.Open);

            byte[] buf      = new byte[AppConst.MPE_HEADER_SIZE];
            int    readByte = encryptedFS.Read(buf, 0, AppConst.MPE_HEADER_SIZE);

            if (readByte < AppConst.MPE_HEADER_SIZE)
            {
                errorDetailMessage = "File size is too small.";
                goto ERROR;
            }

            var reader = new MPEHeaderReader(buf);

            string headerConst = reader.ReadString(3);

            if (headerConst != AppConst.MPE_HEADER_CONST)
            {
                errorDetailMessage = "MPE Header constant is incorrect.";
                goto ERROR;
            }

            string warningDetail  = "";
            string archiveVersion = reader.ReadString(3);

            if (archiveVersion != AppConst.MPE_FORMAT_VERSION)
            {
                warningDetail += "archive format version:" + archiveVersion + " preferred:000\r\n";
            }
            string encoderVersion = reader.ReadString(3);

            if (encoderVersion != AppConst.MPE_ENCODER_VERSION)
            {
                warningDetail += "encoder version:" + encoderVersion + " preferred:000\r\n";
            }

            int questionHeaderLen = reader.ReadInt();

            byte[] questionHeaderCRC = reader.ReadBytes(4);
            long   dataLen           = reader.ReadLong();

            byte[] dataCRC = reader.ReadBytes(4);

            if (AppConst.MPE_HEADER_SIZE + questionHeaderLen + dataLen != encryptedFS.Length)
            {
                errorDetailMessage = "File size is incorrect.";
                goto ERROR;
            }

            // question header
            byte[] questionHeaderBuf = new byte[questionHeaderLen];
            encryptedFS.Read(questionHeaderBuf, 0, questionHeaderLen);
            byte[] questionHeaderCRCVerify;
            using (CRC crcProvider = new CRC(CRCpolynomial.CRC32_C))
            {
                questionHeaderCRCVerify = crcProvider.ComputeHash(questionHeaderBuf);
            }
            if (questionHeaderCRC.SequenceEqual(questionHeaderCRCVerify) == false)
            {
                warningDetail += "question header CRC32 unmatched.\r\n";
            }

            // TODO:別スレッドで検算
            long dataStartPosition = encryptedFS.Position;

            byte[] dataCRCVerify;
            using (CRC crcProvider = new CRC(CRCpolynomial.CRC32_C))
            {
                dataCRCVerify = crcProvider.ComputeHash(encryptedFS);
            }
            if (dataCRC.SequenceEqual(dataCRCVerify) == false)
            {
                warningDetail += "data CRC32 unmatched.\r\n";
            }

            byte flag;
            int  nQuestions;
            int  nRequiredPasswords;
            int  nPasswordCombinations;

            byte[]        encryptedDataKeys;
            DecQuestion[] questions;
            try
            {
                // parse question header
                reader = new MPEHeaderReader(questionHeaderBuf);

                flag                  = reader.ReadByte();
                nQuestions            = reader.ReadInt();
                nRequiredPasswords    = reader.ReadInt();
                nPasswordCombinations = reader.ReadInt();
                // assertion: nQuestions C nRequiredPasswords == nPasswordCombinations
                encryptedDataKeys = reader.ReadBytes(nPasswordCombinations * Crypto.AES_KEY_SIZE_BYTE_WITH_PADDING);

                questions = new DecQuestion[nQuestions];
                for (int i = 0; i < nQuestions; ++i)
                {
                    var question = new DecQuestion();
                    int hintLen  = reader.ReadInt();
                    question.hint                  = reader.ReadString(hintLen);
                    question.nPasswords            = reader.ReadInt();
                    question.encryptedQuestionKeys = reader.ReadBytes(question.nPasswords * Crypto.AES_KEY_SIZE_BYTE_WITH_PADDING);

                    questions[i] = question;
                }

                if (reader.Position != questionHeaderBuf.Length)
                {
                    errorDetailMessage = "MPE Header is incorrect.";
                    goto ERROR;
                }
            }
            catch (IndexOutOfRangeException)
            {
                errorDetailMessage = "MPE Header is incorrect.";
                goto ERROR;
            }

            var decMpeFileInfo = new DecMPEFileInfo();

            decMpeFileInfo._encryptedFS       = encryptedFS;
            decMpeFileInfo._dataStartPosition = dataStartPosition;
            decMpeFileInfo._flag               = flag;
            decMpeFileInfo._nQuestions         = nQuestions;
            decMpeFileInfo._nRequiredPasswords = nRequiredPasswords;
            decMpeFileInfo._encryptedDataKeys  = encryptedDataKeys;
            decMpeFileInfo._decQuestions       = questions;

            decMpeFileInfo._errorDetailMessage   = errorDetailMessage;
            decMpeFileInfo._warningDetailMessage = warningDetailMessage;
            return(decMpeFileInfo);

ERROR:
            encryptedFS.Close();
            decMpeFileInfo = new DecMPEFileInfo();
            decMpeFileInfo._warningDetailMessage = warningDetailMessage;
            decMpeFileInfo._errorDetailMessage   = errorDetailMessage;
            return(decMpeFileInfo);
        }