Расшифровка C# дает неверный результат [Обновление 1]

В моей программе происходит следующее.

  1. Произвольная строка генерируется и шифруется.Это процедура шифрования:

    private static readonly byte[] SALT = new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c };
        //TODO: The SALT needs to be derived and unique for each user!
    
        internal  byte[] Encrypt(byte[] plain)
        {
            string password = Properties.Settings.Default.PasswordOne;
            MemoryStream memoryStream;
            CryptoStream cryptoStream;
            Rijndael rijndael = Rijndael.Create();
            rijndael.Padding = PaddingMode.Zeros;
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, SALT);
            rijndael.Key = pdb.GetBytes(32);
            rijndael.IV = pdb.GetBytes(16);
            memoryStream = new MemoryStream();
            cryptoStream = new CryptoStream(memoryStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write);
            cryptoStream.Write(plain, 0, plain.Length);
            cryptoStream.Close();
            return memoryStream.ToArray();
        }
    
  2. Эта зашифрованная строка сохраняется в файле с именем DEFT.Это процедура сохранения:

     private void CreateDeft2(FileSystemEncryption fse, string Deft2FileName, string drive)
    {
        if (DrivesLog != null) DrivesLog("Creating DEFT2");
        FileStream fs = null;
        StreamWriter sw = null;
        string location = Path.Combine(drive, Deft2FileName);
        try
        {
            fs = new FileStream(location, FileMode.CreateNew, FileAccess.Write, FileShare.None);
            sw = new StreamWriter(fs, Encoding.Unicode);
    
            if (DrivesLog != null) DrivesLog("Creating Random Contents");
            string fakeContents = CreateRandomString(1024000);      // Create the fake contents
            if (DrivesLog != null) DrivesLog("Converting Random Contents to Bytes");
            byte[] bFakeContents = GetBytes(fakeContents);          // Convert to bytes
            if (DrivesLog != null) DrivesLog("Encrypting Random Content Bytes");
            byte[] ebFakeContents = fse.Encrypt(bFakeContents);     // Encrypt
            if (DrivesLog != null) DrivesLog("Converting Encrypted Bytes to String");
            string sedFakeContents = GetString(ebFakeContents);     // Convert to string
    
            if (DrivesLog != null) DrivesLog("Writing DEFT2");
            sw.Write(sedFakeContents);                              // Write it out
            fs.Flush();                                             // Flush the buffer
    
            sw.Close();
            fs.Close();
            if (DrivesLog != null) DrivesLog("Successfully Created DEFT2");
        }
        catch (Exception ex)
        {
            if (DrivesLog != null) DrivesLog("Failed to Create DEFT2 " + ex.Message);
            sw.Close();
            fs.Close();
        }
    }
    
  3. В определенном месте в файле DEFT создается и сохраняется другая строка из 32 символов.Вот код для этого:

    private void InsertDEFT2NameLength(FileSystemEncryption fse, FileStream fs, StreamWriter sw)
        {
            if (DrivesLog != null) DrivesLog("Inserting DEFT2 Name");
            string deft2NameLength = "0";                                       // init the length
            if (DrivesLog != null) DrivesLog("Converting DEFT2 Name to Bytes");
            if (fDEFT2Name.Length < 32)
            {
                for (int idx = fDEFT2Name.Length; idx < 32; idx++)
                {
                    fDEFT2Name = fDEFT2Name + "!";
                }
            }
            byte[] bdeft2Name = GetBytes(fDEFT2Name);                        // convert filename to bytes
            if (DrivesLog != null) DrivesLog("Encrypting DEFT2 Name");
            byte[] ebdeft2Name = fse.Encrypt(bdeft2Name);                       // Encrypt
            if (DrivesLog != null) DrivesLog("Getting Length of Encrypted DEFT2 Name");
            long ebdeft2NameLength = ebdeft2Name.LongLength;                    // Get Length of the Encrypted Bytes as a long
            if (DrivesLog != null) DrivesLog("Converting DEFT2 Name Length to String");
            string sebdeft2NameLength = ebdeft2NameLength.ToString();     // Convert Length to string Add Shebang so we know when we have read the full length
            if (DrivesLog != null) DrivesLog("Converting DEFT2 Name Length to Bytes");
            byte[] bsebdeft2NameLength = GetBytes(sebdeft2NameLength);          // Convert length string to bytes
            if (DrivesLog != null) DrivesLog("Encrypting DEFT2 Name Length");
            byte[] ebsebdeft2NameLength = fse.Encrypt(bsebdeft2NameLength);     // Encrypt
            if (DrivesLog != null) DrivesLog("Converting Encrypted DEFT2 Name Length to String");
            deft2NameLength = GetString(ebsebdeft2NameLength);                  // Convert to string
    
            if (DrivesLog != null) DrivesLog("Seeking to Correct Location");
            long startPos = GenerateDEFT2LengthStartPosition();
            fs.Seek(startPos, SeekOrigin.Current);    // Seek to correct location
            if (DrivesLog != null) DrivesLog("New Position " + startPos.ToString("N0"));
            if (DrivesLog != null) DrivesLog("Writing Encrypted Name Length to New Position");
            sw.Write(deft2NameLength);                                          // Write the Encrypted length
            fs.Flush();                                                         // Flush the buffer immediately
        }
    
    1. Затем я пытаюсь расшифровать эту новую строку. Это расшифровывает строку (или, по крайней мере, так должно быть!)

      private long ReadDEFT2Len (строка DEFT, long lenPos, FileSystemEncryption fse) { if (DrivesLog!= null) DrivesLog("Чтение длины имени DEFT2"); StringBuilder sb = new StringBuilder();

          FileStream fs = null;
          StreamReader sr = null;
      
          try
          {
              fs = new FileStream(DEFT, FileMode.Open, FileAccess.Read, FileShare.Read);
              sr = new StreamReader(fs, Encoding.Unicode);
      
              char[] C = new char[32];
              fs.Seek(lenPos, SeekOrigin.Begin);
              sr.Read(C, 0, 32);
      
              string sC = new string(C);
              byte[] bsC = GetBytes(sC);
      
              byte[] dRes = fse.Decrypt(bsC);
              string sbdRes = GetString(dRes);
              foreach (char ic in sbdRes)
              {
                  if (ic == '!') break;
                  sb.Append(ic.ToString());
              }
      
              sr.Close();
              fs.Close();
      
              if (DrivesLog != null) DrivesLog("DEFT2 Name Length = " + sb.ToString());
              return long.Parse(sb.ToString());
          }
          catch (Exception ex)
          {
              if (DrivesLog != null) DrivesLog("ERROR Reading DEFT2 Name Length " + ex.Message);
              if (sr != null) sr.Close();
              if (fs != null) fs.Close();
              return -1;
          }
      
      }
      

Извините за форматирование - он просто не будет играть хорошо!

Процедура дешифрования не дешифрует исходную строку - она ​​просто возвращает непонятный текст. Расшифровка маршрутизации здесь:

internal  byte[] Decrypt(byte[] cipher)
    {
        string password = Properties.Settings.Default.PasswordOne;
        MemoryStream memoryStream;
        CryptoStream cryptoStream;
        Rijndael rijndael = Rijndael.Create();
        rijndael.Padding = PaddingMode.Zeros;
        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, SALT);
        rijndael.Key = pdb.GetBytes(32);
        rijndael.IV = pdb.GetBytes(16);
        memoryStream = new MemoryStream();
        cryptoStream = new CryptoStream(memoryStream, rijndael.CreateDecryptor(), CryptoStreamMode.Write);
        cryptoStream.Write(cipher, 0, cipher.Length);
        cryptoStream.FlushFinalBlock();
        cryptoStream.Close();
        return memoryStream.ToArray();
    }

Он использует ту же соль, что и шифратор. Пароль тот же, а количество прочитанных байтов одинаковое и из правильного места в файле. Итак, есть идеи, почему это так?

ОБНОВЛЕНИЕ 1:

Этот код предоставляет мне место, куда я вставлю в ранее созданный зашифрованный файл DEFT новый фрагмент информации.

private long GenerateDEFT2LengthStartPosition()
        {
            if (DrivesLog != null) DrivesLog("Generating DEFT2 Length Start Position");
            return long.Parse((Properties.Settings.Default.PasswordOne.Length * Properties.Settings.Default.PasswordOne.Length).ToString());
        }

Пока я использую тот же пароль, который он будет использовать при сохранении (для целей тестирования), он будет возвращать то же место, чтобы вставить вновь зашифрованный текст. В этом случае всегда возвращается 100.

Однако в шестнадцатеричном редакторе, использующем десятичные дроби для смещений, он показывает, что вновь зашифрованный текст сохраняется со смещением 418.

Зачем сохранять текст так:

long startPos = GenerateDEFT2LengthStartPosition();
            fs.Seek(startPos, SeekOrigin.Current);    // Seek to correct location                
            sw.Write(deft2NameLength);                                          

и загружаем это так:

long lenPos = GenerateDEFT2LengthStartPosition();
 char[] C = new char[32];
                fs.Seek(lenPos, SeekOrigin.Begin);
                sr.Read(C, 0, 32);

поместить меня в совершенно другое положение в файле?

Итак, Вопрос: Почему используется одно и то же значение 100 для записи и чтения зашифрованного текста в файле, помещая текст в другое место, откуда он читается?

0 ответов

Другие вопросы по тегам