⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inituser.c

📁 C++编程实践与技巧一书各章节的源码
💻 C
字号:
//container.c 密钥容器和密钥生成实例
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main(void) 
{ 
//--------------------------------------------------------------------


HCRYPTPROV hCryptProv;        // CSP上下文句柄。
HCRYPTKEY hKey;               // 公/私钥句柄
CHAR szUserName[100];         //存放密钥容器名字的缓存
DWORD dwUserNameLen = 100;    // 缓存长度
LPCSTR UserName= NULL;        // 可以输入用户名来作为密钥容器名,最大100个字符
                              // 该值可选
//--------------------------------------------------------------------
//开始处理,实现获取密钥容器上下文

//  如果想创建一个新的密钥容器,
//  可以在第二次调用CryptAcquireContext时替代第二个参数NULL,

if(CryptAcquireContext(
   &hCryptProv,               // CSP句柄
   UserName,                  // 密钥容器名
   MS_DEF_PROV,               // CSP名
   PROV_RSA_FULL,             // CSP类型
   0))                        // 标志值
{
    printf("已经在密钥容器 %s中获得加密上下文\n", UserName);
}
else
{ 
//--------------------------------------------------------------------
//如果在获取上下文的时候出现错误
// 则创建一个新的密钥容器

   if(CryptAcquireContext(
      &hCryptProv, 
      UserName, 
      MS_DEF_PROV, 
      PROV_RSA_FULL, 
      CRYPT_NEWKEYSET)) 
   {
      printf("新的密钥容器已经创建\n");
   }
   else
   {
      HandleError("不能创建新的密钥容器\n");
    }
} // End of else
//--------------------------------------------------------------------
// 已经有的加密上下文和密钥容器,
// 获取密钥容器的名字
if(CryptGetProvParam(
    hCryptProv,               // CSP句柄
    PP_CONTAINER,             // 获取密钥容器名
    (BYTE *)szUserName,       // 指向密钥容器名的指针
    &dwUserNameLen,           // 名字长度,预设为100
    0)) 
{
    printf("加密上下文已经获取\n");
    printf("密钥容器名字为 %s\n\n",szUserName);
}
else
{
    
    HandleError("上下文已经取得或创建\
      ,但获取密钥容器名字的时候出错\n");
} 

//--------------------------------------------------------------------
// 已经获得拥有密钥容器的上下文,
//下面试图获取密钥对(签名和交换)句柄

if(CryptGetUserKey(
   hCryptProv,                     // CSP句柄
   AT_SIGNATURE,                   // 密钥指定
   &hKey))                         // 密钥句柄
{
    printf("签名密钥已存在\n");
}
else
{
    printf("签名密钥不存在\n");
    if(GetLastError() == NTE_NO_KEY) 
    {
    //----------------------------------------------------------------
    // 有密钥容器,但没有密钥

    // 创建签名密钥对
       printf("签名密钥对不存在\n");
       printf("创建一个签名密钥对\n"); 
       if(CryptGenKey(
          hCryptProv,
          AT_SIGNATURE,
          0,
          &hKey)) 
       {
          printf("创建了一个签名密钥对\n");
       }
       else
       {
          HandleError("创建签名密钥的时候出错\n"); 
       }
    }
    else
    {
        HandleError("获取签名密钥的时候出现非NTE_NO_KEY错误\n");
    }
} // End of if

printf("签名密钥对存在或者已经创建\n\n");
CryptDestroyKey(hKey); 

//接下来检查交换密钥
if(CryptGetUserKey(
   hCryptProv,
   AT_KEYEXCHANGE,
   &hKey)) 
{
   printf("交换密钥存在\n");
}
else
{
     printf("交换密钥不存在\n");
     //检查是否需要创建一个交换密钥
     if(GetLastError()==NTE_NO_KEY) 
     { 
       // 创建一个交换密钥对
       printf("交换密钥不存在\n");
       printf("试图创建一个交换密钥对\n");
       if(CryptGenKey(
           hCryptProv,
           AT_KEYEXCHANGE,
           0,
           &hKey)) 
       {
           printf("交换密钥对已创建\n");
       }
       else
       {
          HandleError("试图创建交换密钥时出错\n");
       }
    }
    else
    {
       HandleError("出现一个非NTE_NO_KEY错误\n");
     }
}

printf("交换密钥对存在或已经创建\n\n");
CryptDestroyKey(hKey); 
CryptReleaseContext(hCryptProv,0); 
printf("所有的都创建成功\n");
printf("交换密钥对和签名密钥对存在于%s密钥容器中\n",UserName);  
} // End of main

//错误处理函数
void HandleError(char *s)
{
    printf("在运行程序时出现错误\n");
    printf("%s\n",s);
    printf("错误代号 %x\n.",GetLastError());
    printf("程序终止运行\n");
    exit(1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -