我决定编写一个简单的示例程序来帮助您理解为什么简单地复制和粘贴一个字符串(简单地放置一个字节数组)会使您丢失数据,因此无法从给定的字符串中正确解密。顺便说一句,您在 cmets 中发帖的the answer 完美地解释了为什么将加密数据存储在字符串中是一件坏事。
将加密数据存储在字符串中并不是一个好主意因为它们用于人类可读的文本,而不是用于任意二进制数据。对于二进制数据,最好使用 byte[]
正如评论部分中的许多其他人所提到的那样,在进行任何编码时,很可能存在一些不可打印的字符,即没有可在屏幕上打印的表示。因此,如果您的加密文本包含一些不可打印的字符,屏幕上的字符串解释将丢弃信息。我还将尝试解释为什么在您的生产服务器中,代码“似乎”可以工作。
提示:你提到了
...在接收方以相同的方式工作,首先将加密的电子邮件正文作为字符串(不是字节数组形式)接收
没有通过电子邮件发送string 这样的东西,它只是字节,你只是在接收端看到它的解释。无论如何,让我们回到手头的问题。
首先,让我抽象一下您的加密实现。一位伟大的哲学家曾经said
我们在软件开发中喜欢抽象。
这是您使用 CBC 模式的 AES 加密,我试过了:
private byte[] EncryptString(string inputText) {
// great encryption stuff
return encryptedBytes;
}
在你的代码中,你可以这样使用它:
// you mention in comments that this is your code page
var encoder = Encoding.GetEncoding(437);
var encrypted = EncryptString(body);
var email = new MailMessage {
...
Body = encoder.GetString(encryptedBytes)
...
};
现在让我们看看它到目前为止的样子!一些屏幕截图正在制作中。
对于给定的密钥和 iv,我得到了以下 26 元素加密字节数组!
var encyrpted = new byte[] {
8, 9, 10, 11, 12, 13, 14, 15, 16,
65, 66, 67, 68, 69, 70, 71, 72,
73, 74, 75, 0, 1, 2, 3, 4, 5
}
Aaaaand 主体在调试器中的外观如何?看起来有些字符已经不可打印,控制字符如\b 退格或\t 制表符或\f 弹出纸张/清洁视频终端。
无论如何,字符串表示形式如何呢?请注意,我已使用 CTRL + A 选择所有可用的字符串信息,并 CTRL + C 将其放入我的剪贴板。
现在让我们使用相同的编码还原复制粘贴的字符串,看看是否得到相同的字节数组?剧透:哈哈当然不是
在使用复制粘贴字符串之前我有 26 个字节,现在我只有 17 个字节,这 9 个字节发生了什么?因为它们不可打印,所以当我在文本编辑器之间移动它们时,它们根本没有被复制。
由于您没有加密前后的全部信息(因此如 cmets 丢弃的信息中所述),您不能期望在 Python 中正确解密它。
为什么它在生产服务器中工作 - 待编辑