+7(960) 250-82-68 info@mirossa.ru


 mirossa        1С           C         PHP       JAVA  


Статьи
 
 
mingw-w64


//https://docs.microsoft.com/en-us/windows/desktop/seccng/cng-portal
//https://docs.microsoft.com/en-us/windows/desktop/seccng/encrypting-data-with-cng
//https://docs.microsoft.com/en-us/windows/desktop/seccng/signing-data-with-cng

// What is the difference between encrypting and signing in asymmetric encryption?
// When encrypting, you use their public key to write message and they use their private key to read it.
// When signing, you use your private key to write message's signature, and they use your public key to check if it's really yours.

//If you are developing a CNG cryptographic algorithm provider or key storage provider, you must download the Cryptographic Provider Development Kit(https://www.microsoft.com/en-us/download/details.aspx?id=30688) (or here )from Microsoft.

//HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider

// https://xakep.ru/2008/03/06/42665/

// ----------------------------------
// CNG Token Binding Functions (https://docs.microsoft.com/ru-ru/windows/desktop/SecCNG/cng-token-binding-functions)
// Cryptography API: Next Generation (CNG) defines the following functions which are used to perform CNG Token Binding operations.

// TokenBindingDeleteBinding
// TokenBindingGenerateBinding
// TokenBindingGenerateMessage
// TokenBindingGetKeyTypesClient
// TokenBindingGetKeyTypesServer
// TokenBindingVerifyMessage
// Эти функции находятся в Windows 10 SDK(https://docs.microsoft.com/en-us/windows/desktop/api/index) в tokenbinding.h и Tokenbinding.lib.
// Архив Windows SDK и эмуляторов(https://developer.microsoft.com/ru-ru/windows/downloads/sdk-archive)
// ----------------------------------
#include <windows.h>
#include <stdio.h>
#include <bcrypt.h>
#include <ncrypt.h>

//CMD.exe
//cd "C:\Program Files (x86)\mingw-w64\i686-8.1.0-win32-dwarf-rt_v6-rev0\mingw32\bin"
// i686-w64-mingw32-gcc.exe -I"C:\Program Files (x86)\Windows Kits\8.0\Cryptographic Provider Development Kit\Include" 
     test_crypt.c -L"C:\Program Files (x86)\Windows Kits\8.0\Cryptographic Provider Development Kit\Lib\win8\x64"
        -lbcrypt_provider -lcng_provider -lncrypt_provider -o test_crypt.exe // -mwindows
// i686-w64-mingw32-gcc.exe -I"C:\Program Files (x86)\Windows Kits\8.0\Cryptographic Provider Development Kit\Include"
     test_crypt.c -L"C:\Program Files (x86)\Windows Kits\8.0\Cryptographic Provider Development Kit\Lib\win8\x86"
        -lbcrypt_provider -lcng_provider -lncrypt_provider -o test_crypt.exe // -mwindows
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) #define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) // void __cdecl wmain( // int argc, // __in_ecount(argc) LPWSTR *wargv) // { int main() { SetConsoleCP(1251); // На ввод SetConsoleOutputCP(1251); //На вывод. wprintf(L"ok\n"); // NCRYPT_PROV_HANDLE hProv = NULL; // NCRYPT_KEY_HANDLE hKey = NULL; BCRYPT_KEY_HANDLE hTmpKey = NULL; SECURITY_STATUS secStatus = ERROR_SUCCESS; BCRYPT_ALG_HANDLE hHashAlg = NULL, hSignAlg = NULL; BCRYPT_HASH_HANDLE hHash = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; DWORD cbData = 0, cbHash = 0, cbBlob = 0, cbSignature = 0, cbHashObject = 0; PBYTE pbHashObject = NULL; PBYTE pbHash = NULL, pbBlob = NULL, pbSignature = NULL; NCRYPT_PROV_HANDLE hProv; PUCHAR rgbMsg; NCRYPT_KEY_HANDLE hKey; // UNREFERENCED_PARAMETER(argc); // UNREFERENCED_PARAMETER(wargv); //open an algorithm handle if(!NT_SUCCESS(status = BCryptOpenAlgorithmProvider( &hHashAlg, BCRYPT_SHA1_ALGORITHM, NULL, 0))) { wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status); goto Cleanup; } //calculate the size of the buffer to hold the hash object if(!NT_SUCCESS(status = BCryptGetProperty( hHashAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbHashObject, sizeof(DWORD), &cbData, 0))) { wprintf(L"**** Error 0x%x returned by BCryptGetProperty\n", status); goto Cleanup; } //allocate the hash object on the heap pbHashObject = (PBYTE)HeapAlloc (GetProcessHeap (), 0, cbHashObject); if(NULL == pbHashObject) { wprintf(L"**** memory allocation failed\n"); goto Cleanup; } //calculate the length of the hash if(!NT_SUCCESS(status = BCryptGetProperty( hHashAlg, BCRYPT_HASH_LENGTH, (PBYTE)&cbHash, sizeof(DWORD), &cbData, 0))) { wprintf(L"**** Error 0x%x returned by BCryptGetProperty\n", status); goto Cleanup; } //allocate the hash buffer on the heap pbHash = (PBYTE)HeapAlloc (GetProcessHeap (), 0, cbHash); if(NULL == pbHash) { wprintf(L"**** memory allocation failed\n"); goto Cleanup; } //create a hash if(!NT_SUCCESS(status = BCryptCreateHash( hHashAlg, &hHash, pbHashObject, cbHashObject, NULL, 0, 0))) { wprintf(L"**** Error 0x%x returned by BCryptCreateHash\n", status); goto Cleanup; } //hash some data if(!NT_SUCCESS(status = BCryptHashData( hHash, (PBYTE)rgbMsg, sizeof(rgbMsg), 0))) { wprintf(L"**** Error 0x%x returned by BCryptHashData\n", status); goto Cleanup; } //close the hash if(!NT_SUCCESS(status = BCryptFinishHash( hHash, pbHash, cbHash, 0))) { wprintf(L"**** Error 0x%x returned by BCryptFinishHash\n", status); goto Cleanup; } //open handle to KSP if(FAILED(secStatus = NCryptOpenStorageProvider( &hProv, MS_KEY_STORAGE_PROVIDER, 0))) { wprintf(L"**** Error 0x%x returned by NCryptOpenStorageProvider\n", secStatus); goto Cleanup; } //create a persisted key if(FAILED(secStatus = NCryptCreatePersistedKey( hProv, &hKey, NCRYPT_ECDSA_P256_ALGORITHM, L"my ecc key", 0, 0))) { wprintf(L"**** Error 0x%x returned by NCryptCreatePersistedKey\n", secStatus); goto Cleanup; } //create key on disk if(FAILED(secStatus = NCryptFinalizeKey(hKey, 0))) { wprintf(L"**** Error 0x%x returned by NCryptFinalizeKey\n", secStatus); goto Cleanup; } //sign the hash if(FAILED(secStatus = NCryptSignHash( hKey, NULL, pbHash, cbHash, NULL, 0, &cbSignature, 0))) { wprintf(L"**** Error 0x%x returned by NCryptSignHash\n", secStatus); goto Cleanup; } //allocate the signature buffer pbSignature = (PBYTE)HeapAlloc (GetProcessHeap (), 0, cbSignature); if(NULL == pbSignature) { wprintf(L"**** memory allocation failed\n"); goto Cleanup; } if(FAILED(secStatus = NCryptSignHash( hKey, NULL, pbHash, cbHash, pbSignature, cbSignature, &cbSignature, 0))) { wprintf(L"**** Error 0x%x returned by NCryptSignHash\n", secStatus); goto Cleanup; } // if(FAILED(secStatus = NCryptExportKey( // hKey, // NULL, // BCRYPT_ECCPUBLIC_BLOB, // NULL, // NULL, // 0, // &cbBlob, // 0))) // { // wprintf(L"**** Error 0x%x returned by NCryptExportKey\n", secStatus); // goto Cleanup; // } // pbBlob = (PBYTE)HeapAlloc (GetProcessHeap (), 0, cbBlob); // if(NULL == pbBlob) // { // wprintf(L"**** memory allocation failed\n"); // goto Cleanup; // } // if(FAILED(secStatus = NCryptExportKey( // hKey, // NULL, // BCRYPT_ECCPUBLIC_BLOB, // NULL, // pbBlob, // cbBlob, // &cbBlob, // 0))) // { // wprintf(L"**** Error 0x%x returned by NCryptExportKey\n", secStatus); // goto Cleanup; // } if(!NT_SUCCESS(status = BCryptImportKeyPair( hSignAlg, NULL, BCRYPT_ECCPUBLIC_BLOB, &hTmpKey, pbBlob, cbBlob, 0))) { wprintf(L"**** Error 0x%x returned by BCryptImportKeyPair\n", status); goto Cleanup; } if(!NT_SUCCESS(status = BCryptVerifySignature( hTmpKey, NULL, pbHash, cbHash, pbSignature, cbSignature, 0))) { wprintf(L"**** Error 0x%x returned by BCryptVerifySignature\n", status); goto Cleanup; } wprintf(L"Success!\n"); Cleanup: if(hHashAlg) { BCryptCloseAlgorithmProvider(hHashAlg,0); } if(hSignAlg) { BCryptCloseAlgorithmProvider(hSignAlg,0); } if (hHash) { BCryptDestroyHash(hHash); } if(pbHashObject) { HeapFree(GetProcessHeap(), 0, pbHashObject); } if(pbHash) { HeapFree(GetProcessHeap(), 0, pbHash); } if(pbSignature) { HeapFree(GetProcessHeap(), 0, pbSignature); } if(pbBlob) { HeapFree(GetProcessHeap(), 0, pbBlob); } if (hTmpKey) { BCryptDestroyKey(hTmpKey); } if (hKey) { NCryptDeleteKey(hKey, 0); } if (hProv) { NCryptFreeObject(hProv); } return 0; }

to be continued...