【问题标题】:Encryption function gives different output on windows and unix加密函数在 windows 和 unix 上给出不同的输出
【发布时间】:2011-05-02 23:37:36
【问题描述】:

我有一个用 C# 编写的加密工具,它接受一个字符串作为输入。 当我在我的 windows 机器上运行编译的 exe 文件时,我得到的输出与我在远程 UNIX 服务器上使用单声道运行时不同。

这是一个例子:

窗户:

"encrypt.exe 01/01"
Output:
eR4et6LR9P19BfFnhGwPfA==

Unix:

"mono encrypt.exe 01/01"
Output:
Pa8pJCYBN7+U+R705TFq7Q==

我什至尝试将输入值放入脚本中,然后再次编译并运行它,我得到了相同的结果。

解密函数位于远程 Web 服务上,并使用硬编码的密钥和 IV 值(我正在使用这些值进行加密), 解密输出:

Input (String generated on windows):
eR4et6LR9P19BfFnhGwPfA==
Output:
01/01

Input (String generated on Unix):
Pa8pJCYBN7+U+R705TFq7Q==
Output:
????1

这是加密函数:

string text = args[0];
byte[] clearData = Encoding.Unicode.GetBytes(text);
PasswordDeriveBytes bytes = new PasswordDeriveBytes(password, new byte[] { 0x19, 0x76, 0x61, 110, 0x20, 0x4d, 0x65, 100, 0x76, 0x65, 100, 0x65, 0xf6 });
string a = Convert.ToBase64String(Encrypt(clearData, bytes.GetBytes(0x20), bytes.GetBytes(0x10)));
Console.Write(a);

public static byte[] Encrypt(byte[] clearData, byte[] Key, byte[] IV)
{
    MemoryStream stream = new MemoryStream();
    Rijndael rijndael = Rijndael.Create();
    rijndael.Key = Key;
    rijndael.IV = IV;
    CryptoStream stream2 = new CryptoStream(stream, rijndael.CreateEncryptor(), CryptoStreamMode.Write);
    stream2.Write(clearData, 0, clearData.Length);
    stream2.Close();
    return stream.ToArray();
}

这是解密函数(我无法对此进行更改):

byte[] cipherData = Convert.FromBase64String(encryptedString);
PasswordDeriveBytes bytes2 = new PasswordDeriveBytes(password, new byte[] { 0x19, 0x76, 0x61, 110, 0x20, 0x4d, 0x65, 100, 0x76, 0x65, 100, 0x65, 0xf6 });
byte[] buffer2 = Decrypt(cipherData, bytes2.GetBytes(0x20), bytes2.GetBytes(0x10));
string output = Encoding.Unicode.GetString(buffer2);
Console.Write(output); 

public static byte[] Decrypt(byte[] cipherData, byte[] Key, byte[] IV)
{
        MemoryStream stream = new MemoryStream();
        Rijndael rijndael = Rijndael.Create();
        rijndael.Key = Key;
        rijndael.IV = IV;
        CryptoStream stream2 = new CryptoStream(stream, rijndael.CreateDecryptor(), CryptoStreamMode.Write);
        stream2.Write(cipherData, 0, cipherData.Length);
        stream2.Close();
        return stream.ToArray();
}

【问题讨论】:

  • 我没有看到任何调试代码确保加密函数clearData 在两个平台上都是相同的。你确定是这样吗?另外,我希望您不要在示例之外使用常量 IV...

标签: c# .net encryption mono rijndael


【解决方案1】:

这个问题中的问题不是您要处理的问题,而是查看结果的差异,似乎填充是一个问题,因此您可能想查看此问题中的一些回复,但这个答案可能有助于解决您的问题。

http://social.msdn.microsoft.com/forums/en-US/clr/thread/3df8d5aa-ea99-4553-b071-42a2ea406c7f/

当 KEY、 IV 和加密数据并非全部 正确的块大小和 '方案'。避免这种情况的唯一方法 问题是使用 IV 和 KEY 算法生成的。你可以 使用 GenerateIV 得到算法 为您生成 IV。把这个收起来 安全的地方,因为你会需要它。 然后只需调用 encrypt 方法 并传入数据。算法 然后将加密数据并设置 新生成的关键属性 钥匙。将此与您的加密一起存储 数据。仅此而已。

虽然已经过时,但这里给出了不同原因的回复,但如果您可以解密,那么差异原因可能是有效的: http://lists.ximian.com/pipermail/mono-list/2006-November/033456.html

那么,如果您可以在一个上加密并在另一个上解密(您能做到这一点吗?)那么如果结果不同会有什么不同呢?

【讨论】:

  • 我将加密的数据发送到 Web 服务,该服务对其进行解密并将其保存在数据库中。问题是我无法更改解密功能。密钥和IV在解密函数中是硬编码的,所以加密时需要使用指定的密钥和IV。问题是当我解密我得到的单声道加密字符串时????在字符串前面,这是不可接受的。
  • @user735247 - argv[0] 有没有可能有一些空白?您可能希望在该字符串上使用 String.Trim() 以消除任何额外的空格。
  • 另外,当你解密时,在你解密之前是否使用base-64解码?
  • 我尝试在代码中设置值 text="01/01" 而不是 text=argv[0],但我仍然遇到同样的问题。是的,我正在使用 Convert.FromBase64String(encryptedString),我添加了 Web 服务正在使用的解密功能
【解决方案2】:

也许问题是输出是 unicode,并且终端显示的是 ascii。我经常看到?代替被误解的 unicode 字符。

检查字节数组的数值和数量。

Ascii 是 unicode 数量的一半,因为每个字符有两个字节。

【讨论】:

  • Unix 解码字符串:98 57 2 57 219 64 199 165 49 0 => ????1 Windows 解码字符串:48 0 49 0 47 0 48 0 49 0 => 01/01跨度>
【解决方案3】:

您是否检查过您的测试字符串是否有新行? Windows 测试字符串会有回车 + 换行,而 Unix 字符串只有换行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-28
    • 1970-01-01
    • 2015-11-10
    • 2012-12-25
    • 2021-08-04
    相关资源
    最近更新 更多