BinaryRead/Write/FileStream.Read/Write/File.Read/WireAllByte

本文关键字:Read Write File WireAllByte FileStream BinaryRead | 更新日期: 2023-09-27 17:58:37

我正在做文件加密/解密应用程序,并被困了很长时间。我不敢相信仅仅读写文件就这么难。

这是可变

    byte[] FileBytes = null; //file bytes
    byte[] KeyBytes = null; //key bytes
    byte[] ResBytes = null; //result bytes

从文件读取所有字节

    private void ReadFile()
    {
        using (BinaryReader br = new BinaryReader(File.Open(this.txtFilePath.Text, FileMode.Open, FileAccess.Read)))
        {
            int x = 0;
            this.FileBytes = new byte[(int)br.BaseStream.Length];
            int length = (int)br.BaseStream.Length;
            while (x < length)
            {
                this.FileBytes[x] = br.ReadByte();
                x++;
            }
            br.Close();
        }
    }

写入文件

    private void WriteFile()
    {
        using (BinaryWriter bw = new BinaryWriter(File.Open(this.OutputPath, FileMode.Create)))
        {
            // 3. Use foreach and write all 12 integers.
            foreach (byte b in this.ResBytes)
            {
                bw.Write(b);
            }
            bw.Flush();
            bw.Close();
        }
    }

加密方法

    public byte ApplyVernam(byte inByte, byte keyByte)
    {
        if (inByte == keyByte) { return inByte; }
        else { return (byte)(inByte ^ keyByte); }
    }

这是执行按钮点击事件(我把FileBytes[1]作为键),是的,除了文本文档外,文件已经损坏。我认为BinaryWriter可以很好地进行文件加密,但为什么它不起作用呢?我的代码有问题吗?我需要在这里解释。非常感谢。

    private void btnExecute_Click(object sender, EventArgs e)
    {
        try
        {
            this.ReadFile();
            this.ResBytes = new byte[this.FileBytes.Length];
            int x = 0;
            while (x < this.FileBytes.Length)
            {
                this.ResBytes[x] = this.ApplyVernam(this.FileBytes[x], this.FileBytes[1]);
                x++;
            }
            this.WriteFile();
        }
        catch
        {
            throw;
        }
    }

BinaryRead/Write/FileStream.Read/Write/File.Read/WireAllByte

您的加密方法是不可逆的,因此您无法用它可靠地解密通用二进制消息。之所以会出现此问题,是因为两个不同的明文值可能会加密到相同的密文值,而当这种情况发生时,您无法确定何时解密哪个是正确的输入值。

示例:

if inByte = 100 and keyByte = 100:
    ApplyVernam(100, 100) = 100
if inByte = 0, keyByte = 100:
    ApplyVernam(0, 100) = 100

现在,在尝试解密时,无法判断原始明文字节是0还是100

我建议从ApplyVernam方法中删除行:if (inByte == keyByte) { return inByte; },这样它总是XORs是带键的输入,因此是完全可逆的。

正如我在评论中所提到的,您的"密钥"是输入中位置1处的字节,但这也是加密的,因此当您解密时,位置1的字节不再是原始密钥。更改以下行可以解决问题:

发件人:

this.ResBytes[x] = this.ApplyVernam(this.FileBytes[x], this.FileBytes[1]);

收件人:

this.ResBytes[x] = x == 1 ? this.FileBytes[x] : this.ApplyVernam(this.FileBytes[x], this.FileBytes[1]);

这将确保密钥字节在未加密的情况下写入输出。