Ich bin neu in CNG. Ich spiele mit dem Basisprogramm von msdn site. Ich habe die Eingabe-Plain-String geändert und testen Sie die Ausgabe mit anderen Websites, die die aes cbc-verschlüsselte Ausgabe bietet. Leider nur die erste Hälfte passt und die nächste Hälfte stimmt nicht überein. Es wäre toll, wenn mir jemand zeigen könnte, wo der Fehler liegt,AES-CBC verschlüsselte Ausgabe in CNG passt nicht mit Online-Tools
Original-Code von msdn ist here.
Hier ist die Ausgabe von meinem Code (unten) generiert. Bitte beachten Sie, dass es keinen Unterschied in meinem Code gibt, abgesehen von der Eingabe der einfachen Zeichenfolge. Hier
ist die Ausgabe von der Online-Website (http://aes.online-domain-tools.com/ und anothersite)
Die erste Hälfte endet mit "B0 C4 29 18" .. nach, dass die zweite Hälfte nicht übereinstimmt.
Hier ist der Code
#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);
}
Die IV ist nicht 256-Bits, es ist in Hex w = hier jedes Zeichen repräsentiert 4-Bit, 32-Zeichen * 4-Bit = 128-Bits. Geben Sie auch nicht die Eingabe, den Schlüssel und die IV in einem Screenshot an. – zaph
Aber ich benutze die gleiche IV in meinem Programm und Online-Websites als auch .. keiner von ihnen beschwerte .. es ist der gleiche Code von msdn, so gehe ich davon aus, dass IV möglicherweise nicht das Problem sein. – ABCDEFG
Die Länge der Daten ist kein exaktes Vielfaches der Blockgröße (16 Bytes für AES), daher wird padding hinzugefügt. Das ist, wo die Implementierung entweder die Daten zurückweist, Pads mit einer Standardmethode wie 0x00 (cryptomathisch), PKCS # 7 (das allgemein verwendete Padding) oder was auch immer junbk den bereitgestellten Daten im Speicher folgt. Es ist am besten, das Auffüllen bei der Instanziierung von AES anzugeben. – zaph