【发布时间】:2017-04-27 18:25:52
【问题描述】:
我正在尝试使用具有 Crypto++ 的 C++ 应用程序和使用 TripleDESCryptoServiceProvider 的 .NET 应用程序使用 TripleDES 获得相同的结果。我尝试将 Key 和 IV 设置为相同,但得到不同的结果。
这个问题已经问过here,但没有明确的答案。
这里是 C++ 示例
#include <stdio.h>
#include <cstdlib>
#include <string>
#include <iostream>
#include "dll.h"
#include "mybase64.h"
using namespace std;
USING_NAMESPACE(CryptoPP)
int main()
{
std::cout << "Crypto++ Example" << endl;
std:cout << "TEST" << endl;
const int textSize = 4;
const int keySize = 24;
byte iv[] = { 240, 4, 37, 12, 167, 153, 233, 177 };
byte key[] = {191, 231, 220, 196, 173, 36, 92, 125, 146, 210, 117, 220, 95, 104, 154, 69, 180, 113, 146, 19, 124, 62, 60, 79};
byte encryptedText[textSize];
char cText[] = {'T', 'E', 'S', 'T'};
byte* text = new byte[textSize];
for (int ndx = 0; ndx<4; ndx++)
{
text[ndx] = (byte)cText[ndx];
}
CFB_FIPS_Mode<DES_EDE3>::Encryption encryption;
encryption.SetKeyWithIV(key, keySize, iv);
encryption.ProcessString(encryptedText, text, 4);
string encoded;
encoded = base64_encode(encryptedText, 4);
cout << encoded << endl;
system("pause");
return 0;
}
产生以下结果:
K3zUUA==
这是 C# 示例:
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
namespace TripleDESExample
{
class Program
{
static void Main(string[] args)
{
string message = "TEST";
byte[] iv = { 240, 4, 37, 12, 167, 153, 233, 177 };
byte[] key = { 191, 231, 220, 196, 173, 36, 92, 125, 146, 210, 117, 220, 95, 104, 154, 69, 180, 113, 146, 19, 124, 62, 60, 79 };
byte[] data = Encoding.ASCII.GetBytes(message);
using (var tdes = new TripleDESCryptoServiceProvider())
{
tdes.Mode = CipherMode.CFB;
tdes.Padding = PaddingMode.Zeros;
tdes.IV = iv;
tdes.Key = key;
using (var ms = new MemoryStream())
{
using (var crypto = new CryptoStream(ms, tdes.CreateEncryptor(), CryptoStreamMode.Write))
{
crypto.Write(data, 0, data.Length);
crypto.Close();
}
Array.Copy(ms.ToArray(), data, data.Length);
Console.WriteLine(string.Format("Encrypted: {0}", Convert.ToBase64String(data)));
}
}
Console.WriteLine("Press any key...");
Console.ReadKey();
}
}
}
这会产生以下结果:
K7nXyg==
所以你可以看到它们产生了不同的结果。
K7nXyg==
K3zUUA==
谁能指出他们显示不同结果的问题。
如果可能,请提供示例代码。
---------------------2017 年 4 月 27 日更新-------------------- ---------------------
现在尝试使用稍微不同的 .NET 实现也给了我不同的结果......
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
namespace TripleDESExample
{
class Program
{
static void Main(string[] args)
{
string message = "TEST";
byte[] iv = { 240, 4, 37, 12, 167, 153, 233, 177 };
byte[] key = { 191, 231, 220, 196, 173, 36, 92, 125, 146, 210, 117, 220, 95, 104, 154, 69, 180, 113, 146, 19, 124, 62, 60, 79 };
byte[] bytes = Encoding.ASCII.GetBytes(message);
TripleDESCryptoServiceProvider cryptoServiceProvider1 = new TripleDESCryptoServiceProvider();
cryptoServiceProvider1.Key = key;
cryptoServiceProvider1.IV = iv;
cryptoServiceProvider1.Mode = CipherMode.CFB;
cryptoServiceProvider1.Padding = PaddingMode.Zeros;
TripleDESCryptoServiceProvider cryptoServiceProvider2 = cryptoServiceProvider1;
byte[] inArray = cryptoServiceProvider2.CreateEncryptor().TransformFinalBlock(bytes, 0, bytes.Length);
cryptoServiceProvider2.Clear();
Console.WriteLine(string.Format("Encrypted: {0}", Convert.ToBase64String(inArray, 0, inArray.Length)));
Console.WriteLine("Press any key...");
Console.ReadKey();
}
}
}
这给了我:
K7nXyp+x9kY=
为什么?
--------2017 年 4 月 28 日更新------------
This 文章很好地描述了 Crypto++ 的实现。
当我尝试增加 BlockSize 和 FeedbackSize 时,我收到以下错误:
根据here 的讨论,似乎 .NET TripleDESCryptoServiceProvider 使用 8 位 CipherMode.CFB,而 Crypto++ 使用 128 位。当尝试将 .NET 的 FeedbackSize 设置得更高时,它会引发异常。
有人知道如何解决这个问题吗?
【问题讨论】:
-
问题可能是反馈大小。我相信 .Net 对 CFB 模式使用较小的反馈大小,例如 8 位。 Crypto++ 使用 CFB 模式的完整块大小。我建议使用 CBC 模式获取基线。一旦你在 .Net 和 Crypto++ 中得到相同的结果,然后切换到 CFB 模式并转动反馈大小的旋钮。
-
你有例子如何做到这一点?
-
“听起来问题可能与消息填充有关......” - 我不相信 CFB 模式被填充。问题可能是反馈大小。我不是 Windows 开发人员,所以我无法在 .Net 方面提供帮助。一个 .Net 人将不得不告诉你如何设置反馈大小。顺便问一下,为什么
FeedbackSize不起作用?你得到什么例外? -
我尝试使用 .NET 中的所有选项进行填充,但仍然无法产生与 Crypto++ 相同的结果
标签: c# c++ .net crypto++ tripledes