Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 带CryptVerifySignature的数字签名_C++_Winapi_Cryptography_Digital Signature - Fatal编程技术网

C++ 带CryptVerifySignature的数字签名

C++ 带CryptVerifySignature的数字签名,c++,winapi,cryptography,digital-signature,C++,Winapi,Cryptography,Digital Signature,我想使用CryptVerifySignature实现数字签名应用程序。我已经编写了以下代码(借助MSDN示例): DigSign函数必须对文件内容进行签名,并将签名和公钥写入另一个文件。若符号正确,则CheckSign必须返回true。但我不明白为什么我的代码不起作用。CheckDigSign-in\u tmain必须返回true,但返回false。有人能帮我吗?我取了你的整个代码样本,对其进行了一些修改,并使用CreateFile、ReadFile和WriteFile来处理所有文件I/O。它工

我想使用CryptVerifySignature实现数字签名应用程序。我已经编写了以下代码(借助MSDN示例):


DigSign函数必须对文件内容进行签名,并将签名和公钥写入另一个文件。若符号正确,则CheckSign必须返回true。但我不明白为什么我的代码不起作用。CheckDigSign-in\u tmain必须返回true,但返回false。有人能帮我吗?

我取了你的整个代码样本,对其进行了一些修改,并使用CreateFile、ReadFile和WriteFile来处理所有文件I/O。它工作正常。带有附加公钥的签名文件已根据源文件进行了检查

因此,我怀疑这是一种读/写文件的方法,特别是“w”和“r”与“wb”和“rb”的对比,它会占用您的字节。试着改变一下,看看你有什么想法

作为参考,修改后的代码如下所示,我所做的更改中没有错误检查,因此不要将其用于任何特殊用途,因为它实际上比打印在纸上的价值低(即,没有)


我取了你的整个代码样本,对它进行了一些修改,并对所有文件I/O使用了CreateFile、ReadFile和WriteFile。带有附加公钥的签名文件已根据源文件进行了检查

因此,我怀疑这是一种读/写文件的方法,特别是“w”和“r”与“wb”和“rb”的对比,它会占用您的字节。试着改变一下,看看你有什么想法

作为参考,修改后的代码如下所示,我所做的更改中没有错误检查,因此不要将其用于任何特殊用途,因为它实际上比打印在纸上的价值低(即,没有)


你有这个特权,去争取吧。除了转储GetLastError()的printf()的结果,你的输出中有我们需要的一切。有没有可能你也可以发布呢?@CrazyCasta我试过,但后来它告诉我没有:(编辑:啊,我想这就是retag链接的作用,而不是“编辑”?@AK4749使用retag按钮?@WhozCraig在加密验证签名后返回NTE_BAD_签名你有这个特权,去吧。除了转储GetLastError()的printf()的结果之外,你的输出中有我们需要的所有东西。你有没有可能也发布它?@CrazyCasta我尝试过,但后来它告诉我没有:(编辑:啊,我怀疑这就是retag链接的作用,而不是“编辑”?@AK4749使用retag按钮?@WhozCraig在CryptVerifySignature之后返回NTE_BAD_签名
#define Check(condition, message) if (!(condition)) { fprintf(stderr, "%s\n", message); goto Exit; };
void DigSign(const char* inputFileName, const char* signFileName)
{

    HCRYPTPROV hProv;
    BYTE *pbBuffer= NULL;
    DWORD dwBufferLen = 0;
    HCRYPTHASH hHash;
    HCRYPTKEY hKey;
    HCRYPTKEY hPubKey;
    BYTE *pbKeyBlob;        
    BYTE *pbSignature;
    DWORD dwSigLen;
    DWORD dwBlobLen;

    FILE* inputFile = NULL;

    Check((inputFile = fopen(inputFileName, "r")) != NULL, "File does not exists");
    dwBufferLen = GetFileSize(inputFile);
    Check(pbBuffer = (BYTE*)malloc(dwBufferLen + 1), "cannot allocate memory");

    fread(pbBuffer, 1, dwBufferLen, inputFile);
    pbBuffer[dwBufferLen] = '\0';
    fclose(inputFile);


    //-------------------------------------------------------------------
    // Acquire a cryptographic provider context handle.

    Check(CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0), "Error during CryptAcquireContext.");


    if(!CryptGetUserKey(hProv, AT_SIGNATURE, &hKey)) 
    {
        if(NTE_NO_KEY == GetLastError())
        {
            Check(CryptGenKey(hProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &hKey), "Could not create a user public key.\n");
        }
        else
        {
            goto Exit;
        }
    }

    Check(CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwBlobLen), "Error computing BLOB length.");
    Check(pbKeyBlob = (BYTE*)malloc(dwBlobLen), "Out of memory. \n");
    Check(CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen), "Error during CryptExportKey.");

    //-------------------------------------------------------------------
    // Create the hash object.
    Check(CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash), "Error during CryptCreateHash.");

    //-------------------------------------------------------------------
    // Compute the cryptographic hash of the buffer.
    Check(CryptHashData(hHash, pbBuffer, dwBufferLen, 0), "Error during CryptHashData.");

    //-------------------------------------------------------------------
    // Determine the size of the signature and allocate memory.

    dwSigLen= 0;
    Check(CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, NULL, &dwSigLen), "Error during CryptSignHash.");

    //-------------------------------------------------------------------
    // Allocate memory for the signature buffer.
    Check(pbSignature = (BYTE *)malloc(dwSigLen), "Out of memory.");

    //-------------------------------------------------------------------
    // Sign the hash object.
    Check(CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, pbSignature, &dwSigLen), "Error during CryptSignHash.");

    FILE* f = fopen(signFileName, "w");
    fwrite(pbSignature, dwSigLen, 1, f);
    printf("W: %.128s\n", pbSignature);
    fwrite(pbKeyBlob, dwBlobLen, 1, f);
    printf("W: %.148s\n", pbKeyBlob);
    fclose(f);
    //-------------------------------------------------------------------
    // Destroy the hash object.

    if(hHash) 
        CryptDestroyHash(hHash);

    free(pbSignature);
    free(pbKeyBlob);

    if(hProv) 
        CryptReleaseContext(hProv, 0);

Exit:;
}


bool CheckDigSign(const char* inputFileName, const char* signFileName, const char* userName)
{
    bool result = false;
    HCRYPTPROV hProv;
    BYTE *pbBuffer= (BYTE *)"The data that is to be hashed and signed.";
    DWORD dwBufferLen = strlen((char *)pbBuffer)+1;
    HCRYPTHASH hHash;
    HCRYPTKEY hKey;
    HCRYPTKEY hPubKey;
    BYTE *pbKeyBlob;        
    BYTE *pbSignature;
    DWORD dwSigLen;
    DWORD dwBlobLen;

    FILE* inputFile = NULL;

    Check((inputFile = fopen(inputFileName, "r")) != NULL, "File does not exists");
    dwBufferLen = GetFileSize(inputFile);
    Check(pbBuffer = (BYTE*)malloc(dwBufferLen + 1), "cannot allocate memory");

    fread(pbBuffer, 1, dwBufferLen, inputFile);
    pbBuffer[dwBufferLen] = '\0';
    fclose(inputFile);


    FILE* signFile = NULL;
    Check((signFile = fopen(signFileName, "r")) != NULL, "File does not exists");
    DWORD dwSignFileLen = GetFileSize(signFile);
    dwSigLen = 128;
    pbSignature = (BYTE*)malloc(dwSigLen);
    dwBlobLen = dwSignFileLen - dwSigLen;
    pbKeyBlob = (BYTE*)malloc(dwBlobLen);
    fread(pbSignature, 1, dwSigLen, signFile);
    fread(pbKeyBlob, 1, dwBlobLen, signFile);
    fclose(signFile);



    printf("R: %.128s\n", pbSignature);
    printf("R: %.148s\n", pbKeyBlob);

    Check(CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0), "Error during CryptAcquireContext.");

    Check(CryptImportKey(hProv, pbKeyBlob, dwBlobLen, 0, 0, &hPubKey), "Public key import failed.");

    //-------------------------------------------------------------------
    // Create a new hash object.
    Check(CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash), "Error during CryptCreateHash.");

    //-------------------------------------------------------------------
    // Compute the cryptographic hash of the buffer.
    Check(CryptHashData(hHash, pbBuffer, dwBufferLen, 0), "Error during CryptHashData.");

    //-------------------------------------------------------------------
    // Validate the digital signature.

    result = CryptVerifySignature(hHash, pbSignature, dwSigLen, hPubKey, NULL, 0); 
    printf("%u %x", GetLastError(), GetLastError());
    //-------------------------------------------------------------------
    // Free memory to be used to store signature.

    if(pbSignature)
        free(pbSignature);

    //-------------------------------------------------------------------
    // Destroy the hash object.

    if(hHash) 
        CryptDestroyHash(hHash);

    //-------------------------------------------------------------------
    // Release the provider handle.

    if(hProv) 
        CryptReleaseContext(hProv, 0);

Exit:
    return result;
}


int _tmain(int argc, _TCHAR* argv[])
{


    DigSign("test3.txt", "test.sig");
    printf("TEST: %u\n", CheckDigSign("test3.txt", "test.sig", ""));
}
#define Check(condition, message) if (!(condition)) { fprintf(stderr, "%s\n", message); goto Exit; };
void DigSign(const char* inputFileName, const char* signFileName)
{

    HCRYPTPROV hProv;
    BYTE *pbBuffer= NULL;
    DWORD dwBufferLen = 0;
    HCRYPTHASH hHash;
    HCRYPTKEY hKey;
    BYTE *pbKeyBlob;        
    BYTE *pbSignature;
    DWORD dwSigLen;
    DWORD dwBlobLen;

    FILE* inputFile = NULL;

    HANDLE hFileInput = CreateFile(inputFileName,   // file to open
                         GENERIC_READ,              // open for reading
                         FILE_SHARE_READ,           // share for reading
                         NULL,                      // default security
                         OPEN_EXISTING,             // existing file only
                         FILE_ATTRIBUTE_NORMAL,     // normal file
                         NULL);    

    dwBufferLen = GetFileSize(hFileInput, NULL);
    Check(pbBuffer = (BYTE*)malloc(dwBufferLen + 1), "cannot allocate memory");

    DWORD dwBytesRead = 0L;
    ReadFile(hFileInput, pbBuffer, dwBufferLen, &dwBytesRead, NULL);
    pbBuffer[dwBufferLen] = 0;
    CloseHandle(hFileInput);


    //-------------------------------------------------------------------
    // Acquire a cryptographic provider context handle.

    Check(CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0), "Error during CryptAcquireContext.");


    if(!CryptGetUserKey(hProv, AT_SIGNATURE, &hKey)) 
    {
        if(NTE_NO_KEY == GetLastError())
        {
            Check(CryptGenKey(hProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &hKey), "Could not create a user public key.\n");
        }
        else
        {
            goto Exit;
        }
    }

    Check(CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwBlobLen), "Error computing BLOB length.");
    Check(pbKeyBlob = (BYTE*)malloc(dwBlobLen), "Out of memory. \n");
    Check(CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen), "Error during CryptExportKey.");

    //-------------------------------------------------------------------
    // Create the hash object.
    Check(CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash), "Error during CryptCreateHash.");

    //-------------------------------------------------------------------
    // Compute the cryptographic hash of the buffer.
    Check(CryptHashData(hHash, pbBuffer, dwBufferLen, 0), "Error during CryptHashData.");

    //-------------------------------------------------------------------
    // Determine the size of the signature and allocate memory.

    dwSigLen= 0;
    Check(CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, NULL, &dwSigLen), "Error during CryptSignHash.");

    //-------------------------------------------------------------------
    // Allocate memory for the signature buffer.
    Check(pbSignature = (BYTE *)malloc(dwSigLen), "Out of memory.");

    //-------------------------------------------------------------------
    // Sign the hash object.
    Check(CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, pbSignature, &dwSigLen), "Error during CryptSignHash.");

    HANDLE hFileSign = CreateFile(signFileName, // name of the write
                         GENERIC_WRITE,         // open for writing
                         0,                     // do not share
                         NULL,                  // default security
                         CREATE_NEW,            // create new file only
                         FILE_ATTRIBUTE_NORMAL, // normal file
                         NULL);                  // no attr. template

    DWORD dwBytesWritten = 0;
    WriteFile(hFileSign, pbSignature, dwSigLen, &dwBytesWritten, NULL);
    WriteFile(hFileSign, pbKeyBlob, dwBlobLen, &dwBytesWritten, NULL);
    CloseHandle(hFileSign);

    printf("W: %.128s\n", pbSignature);
    printf("W: %.148s\n", pbKeyBlob);

    //-------------------------------------------------------------------
    // Destroy the hash object.

    if(hHash) 
        CryptDestroyHash(hHash);

    free(pbSignature);
    free(pbKeyBlob);

    if(hProv) 
        CryptReleaseContext(hProv, 0);

Exit:;
}


bool CheckDigSign(const char* inputFileName, const char* signFileName, const char* userName)
{
    BOOL result = false;
    HCRYPTPROV hProv;
    BYTE *pbBuffer= (BYTE *)"The data that is to be hashed and signed.";
    DWORD dwBufferLen = strlen((char *)pbBuffer)+1;
    HCRYPTHASH hHash;
    HCRYPTKEY hPubKey;
    BYTE *pbKeyBlob;        
    BYTE *pbSignature;
    DWORD dwSigLen;
    DWORD dwBlobLen;

    HANDLE hFileInput = CreateFile(inputFileName,   // file to open
                         GENERIC_READ,              // open for reading
                         FILE_SHARE_READ,           // share for reading
                         NULL,                      // default security
                         OPEN_EXISTING,             // existing file only
                         FILE_ATTRIBUTE_NORMAL,     // normal file
                         NULL);

    dwBufferLen = GetFileSize(hFileInput, NULL);
    Check(pbBuffer = (BYTE*)malloc(dwBufferLen + 1), "cannot allocate memory");

    DWORD dwBytesRead = 0;
    ReadFile(hFileInput, pbBuffer, dwBufferLen, &dwBytesRead, NULL);
    pbBuffer[dwBufferLen] = 0;
    CloseHandle(hFileInput);

    HANDLE hFileSig = CreateFile(signFileName,      // file to open
                         GENERIC_READ,              // open for reading
                         FILE_SHARE_READ,           // share for reading
                         NULL,                      // default security
                         OPEN_EXISTING,             // existing file only
                         FILE_ATTRIBUTE_NORMAL,     // normal file
                         NULL);

    DWORD dwSignFileLen = GetFileSize(hFileSig, NULL);
    dwSigLen = 128;
    pbSignature = (BYTE*)malloc(dwSigLen);
    dwBlobLen = dwSignFileLen - dwSigLen;
    pbKeyBlob = (BYTE*)malloc(dwBlobLen);
    ReadFile(hFileSig, pbSignature, dwSigLen, &dwBytesRead, NULL);
    ReadFile(hFileSig, pbKeyBlob, dwBlobLen, &dwBytesRead, NULL);
    CloseHandle(hFileSig);

    printf("R: %.128s\n", pbSignature);
    printf("R: %.148s\n", pbKeyBlob);

    Check(CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0), "Error during CryptAcquireContext.");
    Check(CryptImportKey(hProv, pbKeyBlob, dwBlobLen, 0, 0, &hPubKey), "Public key import failed.");

    //-------------------------------------------------------------------
    // Create a new hash object.
    Check(CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash), "Error during CryptCreateHash.");

    //-------------------------------------------------------------------
    // Compute the cryptographic hash of the buffer.
    Check(CryptHashData(hHash, pbBuffer, dwBufferLen, 0), "Error during CryptHashData.");

    //-------------------------------------------------------------------
    // Validate the digital signature.

    result = CryptVerifySignature(hHash, pbSignature, dwSigLen, hPubKey, NULL, 0); 
    printf("%u %x", GetLastError(), GetLastError());
    //-------------------------------------------------------------------
    // Free memory to be used to store signature.

    if(pbSignature)
        free(pbSignature);

    //-------------------------------------------------------------------
    // Destroy the hash object.

    if(hHash) 
        CryptDestroyHash(hHash);

    //-------------------------------------------------------------------
    // Release the provider handle.

    if(hProv) 
        CryptReleaseContext(hProv, 0);

Exit:
    return !!result;
}


int _tmain(int argc, _TCHAR* argv[])
{
    if (argc == 3)
    {
        DigSign(argv[1], argv[2]);
        printf("TEST: %u\n", CheckDigSign(argv[1], argv[2],""));
        return 0;
    }
    return 1;
}