- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一些用 C# 加密的代码,我必须用 C++ 重写我在 SO 上看到了几个类似的问题,但不知何故我仍然无法弄清楚。使用相同的密码对相同的字符串进行编码会产生不同的结果。
C#代码
byte[] TestEncrypt(string data)
{
byte[] plainText = System.Text.Encoding.ASCII.GetBytes(data);
TripleDES des3 = new System.Security.Cryptography.TripleDESCryptoServiceProvider();
des3.Mode = CipherMode.CBC;
des3.Key = System.Text.Encoding.ASCII.GetBytes("12656b2e4ba2f22e");
des3.IV = System.Text.Encoding.ASCII.GetBytes("d566gdbc");
ICryptoTransform transform = des3.CreateEncryptor();
MemoryStream memStreamEncryptedData = new MemoryStream();
CryptoStream encStream = new CryptoStream(memStreamEncryptedData,
transform, CryptoStreamMode.Write);
encStream.Write(plainText, 0, plainText.Length);
encStream.FlushFinalBlock();
encStream.Close();
byte[] cipherText = memStreamEncryptedData.ToArray();
return cipherText;
}
结果 255,142,22,151,93,255,156,10,174,10,250,92,144,0,60,142编辑:添加了新的 C++ 版本
string Test3DES()
{
string key = "12656b2e4ba2f22e";
HCRYPTPROV hCryptProv = NULL;
HCRYPTHASH hHash = NULL;
HCRYPTKEY hCryptKey = NULL;
char pIV[] = "d566gdbc"; //simple test IV for 3DES
CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL,CRYPT_VERIFYCONTEXT);
PlainTextKeyBlob keyBlob ={0};
keyBlob.hdr.bType = PLAINTEXTKEYBLOB;
keyBlob.hdr.bVersion = CUR_BLOB_VERSION;
keyBlob.hdr.reserved = 0;
keyBlob.hdr.aiKeyAlg = CALG_3DES_112;
keyBlob.cbKeySize = key.size();
memcpy(keyBlob.key, key.c_str(), key.size());
DWORD dwSizeBlob = sizeof(BLOBHEADER)+sizeof(DWORD)+key.size();
ret = CryptImportKey( hCryptProv, (const BYTE*)&keyBlob, dwSizeBlob, 0, CRYPT_EXPORTABLE, &hCryptKey );
DWORD dwMode = CRYPT_MODE_CBC;
CryptSetKeyParam(hCryptKey, KP_MODE, (BYTE*)&dwMode, 0);
CryptSetKeyParam(hCryptKey, KP_IV,(const BYTE*) pIV, 0) ;
DWORD dwFilled = 0;
BOOL ret = CryptEncrypt( hCryptKey, NULL, TRUE, 0, (LPBYTE)cipherText.c_str(), &dwFilled, (DWORD)str.size());
cipherText.resize(dwFilled);
if( hCryptKey ) CryptDestroyKey( hCryptKey );
if( hHash ) CryptDestroyHash( hHash );
if( hCryptProv ) CryptReleaseContext( hCryptProv, 0 );
return cipherText;
}
结果 167,177,201,56,123,240,169,174
旧的 C++ 版本
C++
string Test3DES()
{
string key = "12656b2e4ba2f22e";
HCRYPTPROV hCryptProv = NULL;
HCRYPTHASH hHash = NULL;
HCRYPTKEY hCryptKey = NULL;
char pIV[] = "d566gdbc"; //simple test IV for 3DES
CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
CryptCreateHash( hCryptProv, CALG_MD5, NULL, 0, &hHash );
CryptHashData( hHash, (LPBYTE)key.c_str(), (DWORD)key.size(), 0 );
DWORD dwMode = CRYPT_MODE_CBC;
CryptDeriveKey(hCryptProv, CALG_3DES, hHash, 0, &hCryptKey);
CryptSetKeyParam(hCryptKey, KP_MODE, (BYTE*)&dwMode, 0);
CryptSetKeyParam(hCryptKey, KP_IV,(const BYTE*) pIV, 0) ;
DWORD dwFilled = 0;
BOOL ret = CryptEncrypt( hCryptKey, NULL, TRUE, 0, (LPBYTE)cipherText.c_str(), &dwFilled, (DWORD)str.size());
cipherText.resize(dwFilled);
if( hCryptKey ) CryptDestroyKey( hCryptKey );
if( hHash ) CryptDestroyHash( hHash );
if( hCryptProv ) CryptReleaseContext( hCryptProv, 0 );
return cipherText;
}
最佳答案
我从您的代码开始设置了一些示例项目。您没有包含所有内容,所以我不得不添加一些内容。当我编译和测试时,我在 C++ 和 C# 中得到了相同的答案。我怀疑问题可能出在您指定 cipherText 缓冲区的方式上?这是我所有的测试代码,所以你应该很容易设置一些示例项目,看看你是否也得到相同的结果,然后也许你可以从那里弄清楚:
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
namespace _3dtest
{
class Program
{
static byte[] TestEncrypt(string data)
{
byte[] plainText = System.Text.Encoding.ASCII.GetBytes(data);
TripleDES des3 = new System.Security.Cryptography.TripleDESCryptoServiceProvider();
des3.Mode = CipherMode.CBC;
des3.Key = System.Text.Encoding.ASCII.GetBytes("12656b2e4ba2f22e");
des3.IV = System.Text.Encoding.ASCII.GetBytes("d566gdbc");
ICryptoTransform transform = des3.CreateEncryptor();
MemoryStream memStreamEncryptedData = new MemoryStream();
CryptoStream encStream = new CryptoStream(memStreamEncryptedData,
transform, CryptoStreamMode.Write);
encStream.Write(plainText, 0, plainText.Length);
encStream.FlushFinalBlock();
encStream.Close();
byte[] cipherText = memStreamEncryptedData.ToArray();
return cipherText;
}
static void Main(string[] args)
{
var info = TestEncrypt("password");
foreach (byte b in info)
{
Console.Write(b.ToString());
Console.Write(", ");
}
Console.WriteLine();
}
}
}
C++
#include "stdafx.h"
#include <Windows.h>
#include <WinCrypt.h>
#include <cassert>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
struct PlainTextKeyBlob {
BLOBHEADER hdr;
DWORD cbKeySize;
BYTE key[16];
};
std::wstring LastError(DWORD lasterr)
{
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
return (wchar_t*)lpMsgBuf; // Leaking, don't care
}
std::vector<BYTE> Test3DES(const std::string& passwd)
{
string key = "12656b2e4ba2f22e";
unsigned char pIV[] = "d566gdbc"; //simple test IV for 3DES
HCRYPTPROV hCryptProv = NULL;
HCRYPTHASH hHash = NULL;
HCRYPTKEY hCryptKey = NULL;
DWORD ret = CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL,CRYPT_VERIFYCONTEXT);
if( ret == 0 ) std::wcout << LastError(GetLastError()) << std::endl;
PlainTextKeyBlob keyBlob ={0};
keyBlob.hdr.bType = PLAINTEXTKEYBLOB;
keyBlob.hdr.bVersion = CUR_BLOB_VERSION;
keyBlob.hdr.reserved = 0;
keyBlob.hdr.aiKeyAlg = CALG_3DES_112;
keyBlob.cbKeySize = key.size();
memcpy(keyBlob.key, key.c_str(), key.size());
DWORD dwSizeBlob = sizeof(BLOBHEADER)+sizeof(DWORD)+key.size();
ret = CryptImportKey( hCryptProv, (const BYTE*)&keyBlob, dwSizeBlob, 0, CRYPT_EXPORTABLE, &hCryptKey );
if( ret == 0 ) std::wcout << LastError(GetLastError()) << std::endl;
DWORD dwMode = CRYPT_MODE_CBC;
CryptSetKeyParam(hCryptKey, KP_MODE, (BYTE*)&dwMode, 0);
CryptSetKeyParam(hCryptKey, KP_IV,(const BYTE*) pIV, 0) ;
std::vector< BYTE > buffer( 1024 );
memcpy( &buffer[0], passwd.c_str(), passwd.size() );
DWORD dwFilled = passwd.size();
ret = CryptEncrypt( hCryptKey, NULL, TRUE, 0, (LPBYTE)&buffer[0], &dwFilled, (DWORD)buffer.size());
if( ret == 0 ) std::wcout << LastError(GetLastError()) << std::endl;
buffer.resize(dwFilled);
if( hCryptKey ) CryptDestroyKey( hCryptKey );
if( hHash ) CryptDestroyHash( hHash );
if( hCryptProv ) CryptReleaseContext( hCryptProv, 0 );
return buffer;
}
int _tmain(int argc, _TCHAR* argv[])
{
auto result = Test3DES("password");
std::for_each( begin(result), end(result), [](BYTE b) {
cout << to_string( (_ULonglong)b ) << " ";
});
cout << std::endl;
return 0;
}
关于c# - .NET 三重 des 到 Windows API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10258302/
创建使用.NET框架的asp.net页面时,访问该页面的客户端是否需要在其计算机上安装.NET框架? IE。用户访问www.fakesite.com/default.aspx,如果他们没有安装框架,他
我阅读了很多不同的博客和 StackOverflow 问题,试图找到我的问题的答案,但最后我找不到任何东西,所以我想自己问这个问题。 我正在构建一个应用程序,其中有一个长时间运行的工作线程,它执行一些
已锁定。这个问题及其答案是locked因为这个问题是题外话,但却具有历史意义。目前不接受新的答案或互动。 我一直想知道为什么微软为这样一个伟大的平台选择了一个如此奇怪的、对搜索引擎不友好的名称。他们就
.Net Framework .Net .NET Standard的区别 1、.NET Framework 在未来.NET Framework或许成为过去时,目前还是有很多地方在使用的。这一套
如果有选择的话,您会走哪条路? ASP.NET Webforms + ASP.NET AJAX 或 ASP.NET MVC + JavaScript Framework of your Choice
我有一个 Web 服务,它通过专用连接通过 https 使用第三方 Web 服务,我应用了 ServicePointManager.ServerCertificateValidationCallbac
为什么我应该选择ASP.NET Web Application (.NET Framework)而不是ASP.NET Core Web Application (.NET Framework)? 我在
我在网络上没有找到任何关于包含 .NET Standard、.NET Core 和 .NET Framework 项目的 .NET 解决方案的公认命名约定。 就我而言,我们在 .NET 框架项目中有以
.NET Compact 是 .NET 的完美子集吗? 假设我考虑了屏幕大小和其他限制并避免了 .NET Compact 不支持的类和方法,或者 .NET Compact 是一个不同且不兼容的 GUI
我已经阅读了所有我能找到的关于 connectionManagement 中的 maxconnection 设置的文章:即 http://support.microsoft.com/kb/821268
我现在正在使用asp.net mvc,想知道使用内置的Json或 Json.Net哪个是更好的选择,但我不确定一个人是否比另一个人有优势。 另外,如果我确实选择沿用Json.Net的路线,那么我应该选
在 Visual Studio 中,您至少可以创建三种不同类型的类库: 类库(.NET Framework) 类库(.NET 标准) 类库(.NET Core) 虽然第一个是我们多年来一直使用的,但我
.NET 和 ASP.NET 之间有什么区别?它们有什么关系? 最佳答案 ASP.Net 基于 .Net 框架构建,提供有关 Web 开发的附加功能。 你可以去看看wikipedia article
在安装更高版本(3.0)之前,我需要安装.net框架1.1和2.0吗?或者单独安装 3.0 框架就足够了,并为在早期框架版本上编写的软件提供支持?谢谢 ,丽然 最佳答案 不,您不必安装以前的框架。 我
我正在开发一个项目,人们可以“更新”类别,例如更改类别的名称。我收到以下消息 This is called after clicking update 按钮 with the SQL statemen
.NET 类 System.Net.CookieContainer 线程安全吗? --更新:交 key 答复-- 是否有任何方法可以确保异步请求期间修改的变量(即 HttpWebRequest.Coo
我正在使用 JScript.NET 在我编写的 C# WinForms 应用程序中编写脚本。它工作得很好,但我只是尝试在脚本中放置一些异常处理,但我无法弄清楚如何判断我的 C# 代码抛出了哪种类型的异
我需要你的帮助, 比如我有一个小数类型的变量,我想这样取整。 例如 3.0 = 3 3.1 = 4 3.2 = 4 3.3 = 4 3.4 = 4 3.5 = 4 3.6 = 4 3.7 = 4 3.
我使用过这样的代码:http://msdn.microsoft.com/en-us/library/dw70f090.aspx在 ASP.NET 中工作之前访问数据库(2-3 年前)。我没有意识到我正
自 ConfigurationManager .NET Standard 中不存在,检索正在执行的程序集的应用程序设置的最佳方法是什么,无论是 web.config或 appSettings.{env
我是一名优秀的程序员,十分优秀!