gpt4 book ai didi

c# - .NET 三重 des 到 Windows API

转载 作者:太空狗 更新时间:2023-10-29 23:46:35 24 4
gpt4 key购买 nike

我有一些用 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com