C# 加密word文档会更改最后一个字节

C# 加密word文档会更改最后一个字节,c#,encryption,byte,document,caesar-cipher,C#,Encryption,Byte,Document,Caesar Cipher,因此,我尝试使用Caesar密码移位对word文档进行加密/解密。我的Caesar类适用于图像(.png)和(.txt)文档。但是,当我加密word文档(.docx)并再次解密该word文档时,最后一个字节会被修改。下图显示了我的意思: 除最后一个字节外,其他所有字节都已正确更改。修改后的文档不包含NUL字节,而是包含一个SOH字节,该字节显然是“头的开始” 这是我的caeser密码类,包含加密和解密功能: static char ciphChar(char ch, int k

因此,我尝试使用Caesar密码移位对word文档进行加密/解密。我的Caesar类适用于图像(.png)和(.txt)文档。但是,当我加密word文档(.docx)并再次解密该word文档时,最后一个字节会被修改。下图显示了我的意思:

除最后一个字节外,其他所有字节都已正确更改。修改后的文档不包含NUL字节,而是包含一个SOH字节,该字节显然是“头的开始”

这是我的caeser密码类,包含加密和解密功能:

        static char ciphChar(char ch, int key)
    {
        if (!char.IsLetter(ch))
        {
            return ch;
        }
        char d = char.IsUpper(ch) ? 'A' : 'a';
        return (char)((((ch + key) - d) % 26) + d);
    }

    public static string Cipher(string message, int key, bool cipherMode) 
    {
        if (cipherMode == false)
        {
            key = 26 - key;
        }
        string output = string.Empty;
        foreach (char ch in message)
            output += ciphChar(ch, key);
        return output;
    }
加密和解密功能也在下面(Caeser密码根据密钥的数字移动消息。因此,例如,如果消息为“a”,密钥为3,则消息变为“d”,因为字母表中的“a”移动了3个字母为“d”):

要在文档上使用加密函数,我使用
convert.ToBase64String
将文档字节转换为字符串。在将字节作为字符串读入后,我使用enciphe/deciphe函数,并使用以下代码将字符串转换回字节
convert.FromBase64String

我的代码成功加密和解密.txt文件和.png文件。但是,对于.docx文件,最后一个字节无法正确解码。。我感谢任何能帮助我解决问题的指导,谢谢

编辑:我添加了一些代码,以便您可以重建我正在处理的问题

  • 创建一个名为caesarShift的类,并从我的原始帖子中所写的caesar密码和加密/解密函数中复制代码

  • 创建一个包含3个按钮和1个文本框的主窗体。复制以下代码:

        public static byte[] EncryptFile(string filePath)
    {
        byte[] fileBytes = File.ReadAllBytes(filePath);
        byte[] bytesEncrypted = Enciphe(fileBytes);
        File.WriteAllBytes(filePath, bytesEncrypted);
        return bytesEncrypted;
    }
    
    public static byte[] DecryptFile(string filePath)
    {
        byte[] fileBytes = File.ReadAllBytes(filePath);
        byte[] bytesDecrypted = Deciphe(fileBytes);
        File.WriteAllBytes(filePath, bytesDecrypted);
        return bytesDecrypted;
    }
    
    static byte[] Enciphe(byte[] file)
    {
        var fileToString = Convert.ToBase64String(file);
        string caeser;
        caeser = caesarShift.Encipher(fileToString, 3);
        file = Convert.FromBase64String(caeser); 
        return file;
    }
    
    static byte[] Deciphe(byte[] file)
    {
        var fileToString = Convert.ToBase64String(file);
        string caeser;
        caeser = caesarShift.Decipher(fileToString, 3);
        file = Convert.FromBase64String(caeser);
        return file;
    }
    
    private void button1_Click(object sender, EventArgs e)
    {
        OpenFileDialog openFileDialog1 = new OpenFileDialog();
        openFileDialog1.Filter = "encryptable files|*.rtf;*.docx;*.jpg;*.txt;*.png;";
        openFileDialog1.Title = "Select File";
        if (Directory.Exists(textBox1.Text))
        {
            openFileDialog1.InitialDirectory = textBox1.Text;
        }
        else
        {
            openFileDialog1.InitialDirectory = @"C:\";
        }
    
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            textBox1.Text = openFileDialog1.FileName;
        }
    }
    
    private void button2_Click(object sender, EventArgs e)
    {
       EncryptFile(textBox1.Text);
    }
    
    private void button3_Click(object sender, EventArgs e)
    {
        DecryptFile(textBox1.Text);
    }
    
  • 创建一个虚拟word文档并测试加密/解密功能。您还可以测试.jpg和.txt文件(它们正在工作)

  • 我想知道Base64转换过程中缺少了什么,例如在加密/解密过程中处理填充等号?我不确定。所有其他NUL字节都被正确编码/解码回NUL。只有最后一个字节转换错误。我的转换代码就是这样的:var fileToString=Convert.ToBase64String(file);其中file等于字节[]。然后我应用加密(fileToString,3),并使用file=convert.FromBase64String(fileToString)将其转换回字节;关于加密/解密,我发布的ciphChar函数或Cipher函数都有问题。然而,我正在努力找出问题所在,特别是因为我的断点在VS中不起作用!我用在线编译器试过你的代码,它在我能想到的所有情况下都能正常运行。所以我想知道那里是否有奇迹。或者如果你可以共享这个.docx文件?我创建的任何word文档都会导致相同的错误。我的word文档包含以下文本:Hello 123 testingABCDEFIKHJDSFLKIH重复了大约30次。
        public static byte[] EncryptFile(string filePath)
    {
        byte[] fileBytes = File.ReadAllBytes(filePath);
        byte[] bytesEncrypted = Enciphe(fileBytes);
        File.WriteAllBytes(filePath, bytesEncrypted);
        return bytesEncrypted;
    }
    
    public static byte[] DecryptFile(string filePath)
    {
        byte[] fileBytes = File.ReadAllBytes(filePath);
        byte[] bytesDecrypted = Deciphe(fileBytes);
        File.WriteAllBytes(filePath, bytesDecrypted);
        return bytesDecrypted;
    }
    
    static byte[] Enciphe(byte[] file)
    {
        var fileToString = Convert.ToBase64String(file);
        string caeser;
        caeser = caesarShift.Encipher(fileToString, 3);
        file = Convert.FromBase64String(caeser); 
        return file;
    }
    
    static byte[] Deciphe(byte[] file)
    {
        var fileToString = Convert.ToBase64String(file);
        string caeser;
        caeser = caesarShift.Decipher(fileToString, 3);
        file = Convert.FromBase64String(caeser);
        return file;
    }
    
    private void button1_Click(object sender, EventArgs e)
    {
        OpenFileDialog openFileDialog1 = new OpenFileDialog();
        openFileDialog1.Filter = "encryptable files|*.rtf;*.docx;*.jpg;*.txt;*.png;";
        openFileDialog1.Title = "Select File";
        if (Directory.Exists(textBox1.Text))
        {
            openFileDialog1.InitialDirectory = textBox1.Text;
        }
        else
        {
            openFileDialog1.InitialDirectory = @"C:\";
        }
    
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            textBox1.Text = openFileDialog1.FileName;
        }
    }
    
    private void button2_Click(object sender, EventArgs e)
    {
       EncryptFile(textBox1.Text);
    }
    
    private void button3_Click(object sender, EventArgs e)
    {
        DecryptFile(textBox1.Text);
    }