- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 CNG 新手。我正在玩 msdn 站点的基本程序。我修改了输入纯字符串并使用提供 aes cbc 加密输出的其他网站测试了输出。不幸的是只有上半场匹配,下半场不匹配。如果有人能指出错误所在,那就太好了,
来自 msdn 的原始代码是 here .
这是我的代码生成的输出(如下)。请注意,除了修改输入纯字符串外,我的代码没有任何区别。
这是在线网站的输出(http://aes.online-domain-tools.com/ 和 anothersite)
上半场结束于“B0 C4 29 18”..之后,下半场不匹配。
这是代码片段
#include <windows.h>
#include <stdio.h>
#include <bcrypt.h>
#pragma comment(lib, "bcrypt.lib")
#ifndef STATUS_UNSUCCESSFUL
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
#endif // !STATUS_UNSUCCESSFUL
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#endif
void
print_inhex(char *buf, int len) {
for (int i = 0; i < len; i++)
printf(" %02x", buf[i]);
printf("\n");
}
const BYTE rgbPlaintext[] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
static const BYTE rgbIV[] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
static const BYTE rgbAES128Key[] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
void
CNG_aes_cbc()
{
BCRYPT_ALG_HANDLE hAesAlg = NULL;
BCRYPT_KEY_HANDLE hKey = NULL;
NTSTATUS status = STATUS_UNSUCCESSFUL;
DWORD cbCipherText = 0,
cbPlainText = 0,
cbData = 0,
cbKeyObject = 0,
cbBlockLen = 0,
cbBlob = 0;
PBYTE pbCipherText = NULL,
pbPlainText = NULL,
pbKeyObject = NULL,
pbIV = NULL,
pbBlob = NULL;
// Open an algorithm handle.
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hAesAlg, BCRYPT_AES_ALGORITHM, NULL, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
goto Cleanup;
}
// Calculate the size of the buffer to hold the KeyObject.
if (!NT_SUCCESS(status = BCryptGetProperty(hAesAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbKeyObject, sizeof(DWORD), &cbData, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptGetProperty\n", status);
goto Cleanup;
}
// Allocate the key object on the heap.
pbKeyObject = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbKeyObject);
if (NULL == pbKeyObject) {
wprintf(L"**** memory allocation failed\n");
goto Cleanup;
}
// Calculate the block length for the IV.
if (!NT_SUCCESS(status = BCryptGetProperty(hAesAlg, BCRYPT_BLOCK_LENGTH, (PBYTE)&cbBlockLen, sizeof(DWORD), &cbData, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptGetProperty\n", status);
goto Cleanup;
}
// Determine whether the cbBlockLen is not longer than the IV length.
if (cbBlockLen > sizeof(rgbIV)) {
wprintf(L"**** block length is longer than the provided IV length\n");
goto Cleanup;
}
// Allocate a buffer for the IV. The buffer is consumed during the
// encrypt/decrypt process.
pbIV = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbBlockLen);
if (NULL == pbIV) {
wprintf(L"**** memory allocation failed\n");
goto Cleanup;
}
memcpy(pbIV, rgbIV, cbBlockLen);
if (!NT_SUCCESS(status = BCryptSetProperty(hAesAlg, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0))) {
wprintf(L"**** Error 0x%x returned by BCryptSetProperty\n", status);
goto Cleanup;
}
// Generate the key from supplied input key bytes.
if (!NT_SUCCESS(status = BCryptGenerateSymmetricKey(hAesAlg, &hKey, pbKeyObject, cbKeyObject, (PBYTE)rgbAES128Key, sizeof(rgbAES128Key), 0))) {
wprintf(L"**** Error 0x%x returned by BCryptGenerateSymmetricKey\n", status);
goto Cleanup;
}
// Save another copy of the key for later.
if (!NT_SUCCESS(status = BCryptExportKey(hKey, NULL, BCRYPT_KEY_DATA_BLOB, NULL, 0, &cbBlob, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptExportKey\n", status);
goto Cleanup;
}
// Allocate the buffer to hold the BLOB.
PUCHAR pbBlob_1 = (PUCHAR)malloc(sizeof(PUCHAR) * cbBlob);
//pbBlob = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbBlob);
if (NULL == pbBlob_1) {
wprintf(L"**** memory allocation failed\n");
goto Cleanup;
}
if (!NT_SUCCESS(status = BCryptExportKey(hKey, NULL, BCRYPT_KEY_DATA_BLOB, pbBlob_1, cbBlob, &cbBlob, 0))) {
wprintf(L"**** Error 0x%x returned by BCryptExportKey\n", status);
goto Cleanup;
}
PUCHAR blob = pbBlob_1 + sizeof(BCRYPT_KEY_DATA_BLOB_HEADER);
int len = cbBlob - sizeof(BCRYPT_KEY_DATA_BLOB_HEADER);
printf("key:");
print_inhex(blob, len);
cbPlainText = sizeof(rgbPlaintext);
pbPlainText = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbPlainText);
if (NULL == pbPlainText) {
wprintf(L"**** memory allocation failed\n");
goto Cleanup;
}
/*memcpy(pbPlainText, rgbPlaintext, sizeof(rgbPlaintext));*/
char *test_msg = "This is my test msg";
cbPlainText = strlen(test_msg) + 1;
memcpy(pbPlainText, test_msg, cbPlainText);
printf("plain text:");
print_inhex(test_msg, strlen(test_msg));
// Get the output buffer size.
if (!NT_SUCCESS(status = BCryptEncrypt(hKey, pbPlainText, cbPlainText, NULL, pbIV, cbBlockLen, NULL, 0, &cbCipherText, BCRYPT_BLOCK_PADDING))) {
wprintf(L"**** Error 0x%x returned by BCryptEncrypt\n", status);
goto Cleanup;
}
pbCipherText = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbCipherText);
if (NULL == pbCipherText) {
wprintf(L"**** memory allocation failed\n");
goto Cleanup;
}
// Use the key to encrypt the plaintext buffer.
// For block sized messages, block padding will add an extra block.
if (!NT_SUCCESS(status = BCryptEncrypt(hKey, pbPlainText, cbPlainText, NULL, pbIV,
cbBlockLen, pbCipherText, cbCipherText, &cbData, BCRYPT_BLOCK_PADDING))){
wprintf(L"**** Error 0x%x returned by BCryptEncrypt\n", status);
goto Cleanup;
}
printf("cipher text:");
for (int i = 0; i < cbCipherText; i++)
printf(" %02x", pbCipherText[i]);
wprintf(L"\nSuccess!\n");
Cleanup:
if (hAesAlg)
BCryptCloseAlgorithmProvider(hAesAlg, 0);
if (hKey)
BCryptDestroyKey(hKey);
if (pbCipherText)
HeapFree(GetProcessHeap(), 0, pbCipherText);
if (pbKeyObject)
HeapFree(GetProcessHeap(), 0, pbKeyObject);
if (pbIV)
HeapFree(GetProcessHeap(), 0, pbIV);
}
最佳答案
您与 cbPlainText
的值不一致。
旁白:
你用十六进制打印了 strlen 个 tst_msg。但是你设置了 cbPlainText = strlen(tst_msg) + 1
。如果你将它设置为 strlen(tst_msg)
那么你会得到@zaph 的答案(46CC2228E81B2A05E8E8EBF2B0C42918EC496128D7C45BD0B19BB2D6452A3936
)。
您不匹配该网站,因为您使用了带有 PKCS#7 填充的 CNG,而该网站使用了零填充。您可以通过获取输出密文并将其作为明文然后点击解密来识别网站中使用的填充。然后它说您的输入是 54686973206973206d792074657374206d736700000000000000000000000000
。或者,如果您在网站输入中添加 00 0C 0C 0C 0C 0C 0C 0C 0C 0C 0C 0C 0C
,您将获得原始答案。或者添加 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D
,你会得到@zaph 的答案。
那么,要做的事情:
关于c++ - CNG 中的 AES-CBC 加密输出与在线工具不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43011261/
我正在编写一个供我正在从事的项目内部使用的小型库,我是一名业余 Javascript 开发人员,所以请注意我的错误。 我写了一个小的 html 文件以及下面的 javascript,
我试图弄清楚 ECDiffieHellman 在 .Net 下是如何工作的。 我想知道,为什么 ECDiffieHellman 有两个看起来非常相似的实现。 Cng 代表 Cryptography N
我想用 C# 编写一个可以打开 KeePass 的程序1.x kdb 文件。我下载了源代码并尝试移植密码数据库读取功能。数据库内容已加密。加密 key 通过以下方式获得: 用户输入密码; 计算密码的
我有一组用于对称加密/解密的预定义明文 key 。这些 key 用于与连接到 PC 的硬件设备进行加密通信。我想使用 CNG key 存储提供程序来安全地存储这些 key 。加密和解密必须在 CNG
我正在尝试围绕 CNG 的 AES 实现 AES-OFB 包装器以进行对称加密。 我遇到了一个我无法理解的问题...我创建了一个 AES 算法句柄 (BCRYPT_AES_ALGORITHM) 并导入
我有兴趣尝试从数字签名中读取字段。我有调用 CryptQueryObject 的代码,然后是 CryptMsgGetParam 来获取一些字段,最后是 CertFindCertificateInSto
我正在使用 Microsoft CNG Cryptography API 并尝试创建自签名证书。 我们有使用 CertCreateSelfSignCertificate 的现有代码方法,结合NCryp
我是 CNG 新手。我正在玩 msdn 站点的基本程序。我修改了输入纯字符串并使用提供 aes cbc 加密输出的其他网站测试了输出。不幸的是只有上半场匹配,下半场不匹配。如果有人能指出错误所在,那就
我想导入一个使用 CngKey.Export(CngKeyBlobFormat.EccPrivateBlob) 导出的 key ,为 key 命名,并将其保存在 keystore 中。这应该很简单,但
多年来,我一直在尝试寻找如何通过任何方式从文件中导入 ECC key 。我曾尝试从 Windows 证书存储、.p12 文件和 PKCS#8 OpenSSL key 文件访问 ECC 证书,但均未成功
所以我想知道哈希算法的各种实现之间是否存在重大差异,以SHA系列算法为例。它们每个都有 3 个实现,1 个在托管代码中,2 个围绕不同的 native 加密 API 进行包装,但是使用它们之间有什么主
我使用以下 CNG API 序列成功生成了 RSA key : BCryptOpenAlgorithmProvider(.., BCRYPT_RSA_ALGORITHM, ...); BCryptGe
将现有的框架应用程序移植到核心,我们早已将 System.Security.Cryptography.SHA256 和 System.Security.Cryptography.SHA256Manag
我想在 Windows 上运行的 C++ 应用程序中实现数据加密和解密。我花了相当多的时间在网上浏览,我想我可能应该使用 Windows Cryptography API: Next Generati
我正在使用 Crypto API 的 CryptAcquireContext 函数 ( https://docs.microsoft.com/en-us/windows/desktop/api/Win
https://learn.microsoft.com/en-us/sql/relational-databases/security/encryption/extensible-key-manage
我需要使用 Windows 的 Cryptography API: Next Generation 验证消息的签名.我有消息、它的签名和 PEM 格式的公钥,以及展示所需行为的原型(prototype
我需要使用 Windows 加密 API 方法验证签名的 JAR 文件。我对加密和签名问题只有基本的了解。我也不熟悉那些加密 API(WinCrypt、Bcrypt、Ncrypt)。验证文件哈希不是问
我需要使用 Windows 的 Cryptography API: Next Generation 验证消息的签名.我有消息、它的签名和 PEM 格式的公钥,以及展示所需行为的原型(prototype
我需要使用 Windows 加密 API 方法验证签名的 JAR 文件。我对加密和签名问题只有基本的了解。我也不熟悉那些加密 API(WinCrypt、Bcrypt、Ncrypt)。验证文件哈希不是问
我是一名优秀的程序员,十分优秀!