pananning 发表于 2024-4-23 04:34

怎么使用win CNG API AES算法解密

python代码如下
keys = AES.new(dg.digest(), AES.MODE_ECB).decrypt(lsakey)
#include <Windows.h>
#include <bcrypt.h>
#include <stdio.h>

#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)

void PrintHex(const BYTE* data, DWORD dataSize);

int main() {
    BCRYPT_ALG_HANDLE hAlgorithm = NULL;
    BCRYPT_KEY_HANDLE hKey = NULL;
    NTSTATUS status;

    BYTE syskey[] = { /* your syskey bytes here */ };
    BYTE lsakey[] = { /* your lsakey bytes here */ };
    BYTE aesKey;// AES-256 密钥大小为 32 字节

    // 打开 AES 加密提供程序
    status = BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_AES_ALGORITHM, NULL, 0);
    if (!NT_SUCCESS(status)) {
      printf("BCryptOpenAlgorithmProvider failed with status: 0x%x\n", status);
      return 1;
    }

    // 设置密钥对象
    status = BCryptGenerateSymmetricKey(hAlgorithm, &hKey, NULL, 0, syskey, sizeof(syskey), 0);
    if (!NT_SUCCESS(status)) {
      printf("BCryptGenerateSymmetricKey failed with status: 0x%x\n", status);
      BCryptCloseAlgorithmProvider(hAlgorithm, 0);
      return 1;
    }

    // 解密 lsakey 使用 ECB 模式
    BYTE decryptedKey;// 解密后的密钥大小为 32 字节
    status = BCryptDecrypt(hKey, lsakey + 60, 32, NULL, NULL, 0, decryptedKey, sizeof(decryptedKey), NULL, 0);
    if (!NT_SUCCESS(status)) {
      printf("BCryptDecrypt failed with status: 0x%x\n", status);
    } else {
      printf("Decrypted key:\n");
      PrintHex(decryptedKey, sizeof(decryptedKey));
    }

    // 清理资源
    BCryptDestroyKey(hKey);
    BCryptCloseAlgorithmProvider(hAlgorithm, 0);

    return 0;
}

void PrintHex(const BYTE* data, DWORD dataSize) {
    for (DWORD i = 0; i < dataSize; ++i) {
      printf("%02x", data);
    }
    printf("\n");
}

虽然运行没出错,但结果不一样,求大佬把这个python代码改成c++

508 发表于 2024-4-23 06:19

Python代码用于AES解密,使用`Crypto.Cipher.AES`模块。我将提供一个简化的C++实现,这个实现使用Windows的加密API,类似于你提供的C++代码示例。

你的Python代码似乎是从中间开始的,可能缺失了一些关键的初始化部分。但是,我会假设`dg.digest()`返回一个256位(32字节)的AES密钥,并且你已经有了一个名为`lsakey`的数据数组,你想从第60字节开始解密剩余部分。

下面是一个改写的C++版本,它模拟了你描述的Python代码的行为:

```cpp
#include <Windows.h>
#include <bcrypt.h>
#include <stdio.h>

#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)

void PrintHex(const BYTE* data, DWORD dataSize);

int main() {
    BCRYPT_ALG_HANDLE hAlgorithm = NULL;
    BCRYPT_KEY_HANDLE hKey = NULL;
    NTSTATUS status;

    // 假设 dg.digest() 的结果存储在 aesKey 中,这应是32字节的密钥
    BYTE aesKey = { /* 从 dg.digest() 得到的 AES-256 密钥数据 */ };
    BYTE lsakey = { /* 包含密文和可能的其他数据,确保总长度至少为 92 字节 */ };

    // 打开 AES 加密提供程序
    status = BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_AES_ALGORITHM, NULL, 0);
    if (!NT_SUCCESS(status)) {
      printf("BCryptOpenAlgorithmProvider failed with status: 0x%x\n", status);
      return 1;
    }

    // 设置密钥对象
    status = BCryptGenerateSymmetricKey(hAlgorithm, &hKey, NULL, 0, aesKey, sizeof(aesKey), 0);
    if (!NT_SUCCESS(status)) {
      printf("BCryptGenerateSymmetricKey failed with status: 0x%x\n", status);
      BCryptCloseAlgorithmProvider(hAlgorithm, 0);
      return 1;
    }

    // 解密 lsakey 使用 ECB 模式
    BYTE decryptedData; // 根据你的需求调整大小
    DWORD decryptedDataSize = sizeof(decryptedData);
    status = BCryptDecrypt(hKey, lsakey + 60, 32, NULL, NULL, 0, decryptedData, decryptedDataSize, &decryptedDataSize, 0);
    if (!NT_SUCCESS(status)) {
      printf("BCryptDecrypt failed with status: 0x%x\n", status);
    } else {
      printf("Decrypted data:\n");
      PrintHex(decryptedData, decryptedDataSize);
    }

    // 清理资源
    BCryptDestroyKey(hKey);
    BCryptCloseAlgorithmProvider(hAlgorithm, 0);

    return 0;
}

void PrintHex(const BYTE* data, DWORD dataSize) {
    for (DWORD i = 0; i < dataSize; ++i) {
      printf("%02x", data);
    }
    printf("\n");
}
```

请注意,你需要将`aesKey`数组填充为正确的值,即从`dg.digest()`函数得到的值,此函数在你的原始Python代码中被调用。此外,确保`lsakey`数组足够大,可以包含至少92字节的数据(60字节偏移加32字节解密数据)。这个示例假设你解密的数据是32字节长,这通常对应于AES-256加密块的大小。根据你的具体需求调整大小和参数。

tyq2003 发表于 2024-4-23 08:10

我就看看,学习学习

cfnm123 发表于 2024-5-14 17:57

#include <Windows.h>
#include <bcrypt.h>
#include <iostream>
#include <vector>

#pragma comment(lib, "bcrypt.lib")

void PrintHex(const BYTE* data, DWORD dataSize);

int main() {
    BCRYPT_ALG_HANDLE hAlgorithm = NULL;
    BCRYPT_KEY_HANDLE hKey = NULL;
    NTSTATUS status;

    std::vector<BYTE> syskey = {/* your syskey bytes here, ensure it's the same length as in Python code */};
    std::vector<BYTE> lsakey = {/* your lsakey bytes here */};
    std::vector<BYTE> decryptedKey(32);// AES-256, key size is 32 bytes

    // Open the AES algorithm provider
    status = BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_AES_ALGORITHM, NULL, 0);
    if (!NT_SUCCESS(status)) {
      std::cerr << "BCryptOpenAlgorithmProvider failed with status: 0x" << std::hex << status << std::endl;
      return 1;
    }

    // Import the key - assuming syskey is already the correct key derived similarly to dg.digest()
    status = BCryptGenerateSymmetricKey(hAlgorithm, &hKey, NULL, 0, syskey.data(), syskey.size(), 0);
    if (!NT_SUCCESS(status)) {
      std::cerr << "BCryptGenerateSymmetricKey failed with status: 0x" << std::hex << status << std::endl;
      BCryptCloseAlgorithmProvider(hAlgorithm, 0);
      return 1;
    }

    // Decrypt lsakey using ECB mode
    DWORD decryptedSize = 0;
    status = BCryptDecrypt(hKey, lsakey.data() + 60, 32, NULL, NULL, 0, decryptedKey.data(), decryptedKey.size(), &decryptedSize, BCRYPT_BLOCK_PADDING);
    if (!NT_SUCCESS(status)) {
      std::cerr << "BCryptDecrypt failed with status: 0x" << std::hex << status << std::endl;
    } else {
      std::cout << "Decrypted key:" << std::endl;
      PrintHex(decryptedKey.data(), decryptedSize);
    }

    // Clean up
    BCryptDestroyKey(hKey);
    BCryptCloseAlgorithmProvider(hAlgorithm, 0);

    return 0;
}

void PrintHex(const BYTE* data, DWORD dataSize) {
    for (DWORD i = 0; i < dataSize; ++i) {
      std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(data);
    }
    std::cout << std::endl;
}
页: [1]
查看完整版本: 怎么使用win CNG API AES算法解密