VC++网络安全编程范例(5)-创建创建密钥容器和密钥

密钥是一种参数,它是在明文转换为密文或将密文转换为明文的算法中输入的数据。

密钥分为两种:对称密钥与非对称密钥

对称密钥加密,又称私钥加密,即信息的发送方和接收方
  用一个密钥去加密和解密数据。它的最大优势是加/解密速度快,
  适合于对大数据量进行加密,但密钥管理困难。
  非对称密钥加密系统,又称公钥密钥加密。它需要使用一对密钥
  来分别完成加密和解密操作,一个公开发布,即公开密钥,另一
  个由用户自己秘密保存,即私用密钥。信息发送者用公开密钥去
  加密,而信息接收者则用私用密钥去解密。公钥机制灵活,但加
  密和解密速度却比对称密钥加密慢得多。

  密钥容器(Key Container)是一个密钥数据库的一部分,其包含了属于一个特定用户的所有的密钥对(交换和签名密钥对)。

每个容器有一个唯一的名称,其被用于当调用CryptAcquireContext函数来获得对这个容器的处理时。

简单的公共密钥例子可以用素数表示,将素数相乘的算法作为公钥,将所得的乘积分解成原来的素数的算法就是私钥,加密就是将想要传递的信息在编码时加入素数,编码之后传送给收信人,任何人收到此信息后,若没有此收信人所拥有的私钥,则解密的过程中(实为寻找素数的过程),将会因为找素数的过程(分解质因数)过久而无法解读信息。

VC++实现案例如下,详细分析代码注释

  1. #include <stdio.h> 
  2. #include <windows.h> 
  3. #include <wincrypt.h> 
  4. #define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) 
  5. void HandleError(char *s); 
  6.  
  7. void main(void)  
  8. {  
  9.     //-------------------------------------------------------------------- 
  10.     // 申明、初始化变量 
  11.  
  12.     HCRYPTPROV hCryptProv;        // CSP句柄  
  13.                                   
  14.     HCRYPTKEY hKey;               // 公私密钥对句柄 
  15.     CHAR szUserName[100];         // 密钥容器名称  
  16.                                    
  17.     DWORD dwUserNameLen = 100;    // 密钥容器名称长度 
  18.     LPCSTR UserName= "ticai";        // 用户名,作为密钥容器名 
  19.                                   
  20.     //-------------------------------------------------------------------- 
  21.     // 创建默认密钥容器。若需要创建一个密钥容器则替换CryptAcquireContext函数中的“NULL” 
  22.  
  23.     if(CryptAcquireContext( 
  24.       &hCryptProv,               // CSP句柄 
  25.        UserName,                  // 密钥容器名  
  26.        NULL,                      // 使用默认CSP 
  27.        PROV_RSA_FULL,             // CSP类型 
  28.        0))                        // 标志位 
  29.     { 
  30.         printf("一个名为 %s 的密钥容器的句柄 \n", UserName); 
  31.         printf("已经获取.\n\n"); 
  32.     } 
  33.     else 
  34.     {  
  35.     //-------------------------------------------------------------------- 
  36.     // 如果获取CSP出现错误,则创建一个新的默认密钥容器 
  37.  
  38.        if(CryptAcquireContext( 
  39.           &hCryptProv,  
  40.           UserName,  
  41.           NULL,  
  42.           PROV_RSA_FULL,  
  43.           CRYPT_NEWKEYSET)) //创建密钥容器 
  44.        { 
  45.           printf("一个新的密钥容器已经被创建.\n"); 
  46.        } 
  47.        else 
  48.        { 
  49.           HandleError("不能创建新的密钥容器.\n"); 
  50.         } 
  51.     } // End of else 
  52.  
  53.     //-------------------------------------------------------------------- 
  54.     // 已获取包含密钥容器的CSP,获取其密钥容器名。 
  55.  
  56.     if(CryptGetProvParam( 
  57.         hCryptProv,               // CSP句柄 
  58.         PP_CONTAINER,             // 获取参数类型,密钥容器名 
  59.         (BYTE *)szUserName,       // 密钥容器名指针 
  60.         &dwUserNameLen,           // 密钥容器名长度,设为100 
  61.         0))  
  62.     { 
  63.         printf("一个已经包含密钥容器的CSP句柄已被获取并且 \n"); 
  64.         printf("所包含的密钥容器的名称为 %s.\n\n",szUserName); 
  65.     } 
  66.     else 
  67.     { 
  68.         // 获取其密钥容器名出错 
  69.         HandleError("一个CSP句柄已经获取或创建, 但是\ 
  70.           在获取密钥容器名称的时候发生了错误.\n"); 
  71.     }  
  72.  
  73.     //-------------------------------------------------------------------- 
  74.     // 密钥容器已存在 
  75.  
  76.     if(CryptGetUserKey( 
  77.        hCryptProv,                     // CSP句柄 
  78.        AT_SIGNATURE,                   // 密钥类型,签名密钥 
  79.        &hKey))                         // 密钥句柄 
  80.     { 
  81.         printf("签名密钥已经存在.\n"); 
  82.     } 
  83.     else 
  84.     { 
  85.         printf("没有签名密钥存在.\n"); 
  86.         if(GetLastError() == NTE_NO_KEY)  
  87.         { 
  88.         //---------------------------------------------------------------- 
  89.         // 当错误为:密钥不存在时,重新创建签名密钥对。 
  90.  
  91.            printf("签名密钥已经不存在.\n"); 
  92.            printf("创建一个签名密钥对.\n");  
  93.            if(CryptGenKey( 
  94.               hCryptProv, 
  95.               AT_SIGNATURE, 
  96.               0, 
  97.               &hKey))  
  98.            { 
  99.               printf("已经创建了一个签名密钥对.\n"); 
  100.            } 
  101.            else 
  102.            { 
  103.               HandleError("创建签名密钥出错.\n");  
  104.            } 
  105.         } 
  106.         else 
  107.         { 
  108.             HandleError("在获得签名密钥时发生了一个不同于 NTE_NO_KEY 的错误.\n"); 
  109.         } 
  110.     } // End of if 
  111.  
  112.     printf("一个签名密钥对已经存在或被创建.\n\n"); 
  113.  
  114.     CryptDestroyKey(hKey);  
  115.  
  116.     // 检查交换密钥 
  117.     if(CryptGetUserKey( 
  118.        hCryptProv, 
  119.        AT_KEYEXCHANGE, 
  120.        &hKey))  
  121.     { 
  122.        printf("有一对交换密钥存在. \n"); 
  123.     } 
  124.     else 
  125.     { 
  126.          printf("没有交换密钥存在.\n"); 
  127.          // 检查交换密钥是否存在 
  128.          if(GetLastError()==NTE_NO_KEY)  
  129.          {  
  130.            // 创建交换密钥 
  131.            printf("交换密钥不存在.\n"); 
  132.            printf("正在试图创建一个交换密钥对.\n"); 
  133.            if(CryptGenKey( 
  134.                hCryptProv, 
  135.                AT_KEYEXCHANGE, 
  136.                0, 
  137.                &hKey))  
  138.            { 
  139.                printf("交换密钥对已经存在.\n"); 
  140.            } 
  141.            else 
  142.            { 
  143.               HandleError("在试图创建交换密钥时发生错误.\n"); 
  144.            } 
  145.         } 
  146.         else 
  147.         { 
  148.            HandleError("发生了一个不同于 NTE_NO_KEY 的错误.\n"); 
  149.          } 
  150.     } 
  151.  
  152.     printf("一个交换密钥对已经存在或被创建.\n\n"); 
  153.  
  154.     CryptDestroyKey(hKey); //销毁密钥句柄 
  155.  
  156.     CryptReleaseContext(hCryptProv,0); //释放CSP句柄 
  157.  
  158.     printf("一切就绪.\n"); 
  159.     printf("在 %s 密钥容器中存在\n",szUserName); 
  160.     printf("一个签名密钥对和一个交换密钥对.\n");   
  161. } // End of main 
  162.  
  163. //  HandleError:错误处理函数,打印错误信息,并退出程序 
  164. void HandleError(char *s) 
  165.     printf("程序执行发生错误!\n"); 
  166.     printf("%s\n",s); 
  167.     printf("错误代码为: %x.\n",GetLastError()); 
  168.     printf("程序终止执行!\n"); 
  169.     exit(1); 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值