CSP介绍、以及使用CryptoAPI枚举CSP并获取其属性
CSP,全名为“加密服务提供者(Cryptographic Service Provider)”,是微软定义的一套password服务API。眼下经常使用的password规范或者标准有3套:CSP,PKCS#11和国密标准。
前两者主要是为RSA算法提供服务,当然PKCS#11最新的扩展也開始支持ECC算法。而国家password管理制定的国密标准。主要提供SM2(实际上也是ECC)服务,当然国密标准同一时候支持RSA。只是大多数情况下RSA的应用还是使用CSP和PKCS#11来实现。
一、CSP为一个独立的密钥服务模块
CSP能够是软件。比方Windows自带的“Microsoft Base Cryptographic Provider v1.0”和“Microsoft Enhanced Cryptographic Provider v1.0”。
CSP也能够是硬件设备。通常是USBKey。比方飞天诚信等厂商生产的。
二、一个CSP相应一个密钥容器
CSP没有设备(Key)的概念,这点和PKCS11以及国密规范都不一样。一个CSP直接相应一个密钥容器。通过CSP名和容器名直接定位密钥模块,假设不指定容器名,则是定位缺省的容器(普通情况下为第一个容器)。所以对CSP来说。最好容器名要求唯一。通常是使用GUID来作为容器名的。
假设同一个CSP有多个设备,在须要确定使用哪个设备时(比方新建容器),CSP会弹出选择框。依据设备的SN来选择使用哪个设备。
三、一个密钥容器能够包括一对签名密钥、一对加密钥、一个签名证书以及一个加密证书
通常CSP的一个密钥容器仅仅包括一对密钥对和相应的证书,可是理论上能够把签名密钥对和加密密钥对放在同一个容器,然后通过AT_SIGNATURE和AT_KEYEXCHANGE来查找密钥。
四、枚举系统中的CSP
系统中的CSP。都在注冊表:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider文件夹下,我们能够通过API:CryptEnumProviders()来枚举想要的CSP,如以下代码所看到的:
void CTestCSPDlg::EnumCSP()
{
DWORD dwIndex = 0;
DWORD dwType = 0;
DWORD dwNameLen = 0;
CComboBox* pCSPList = (CComboBox*)GetDlgItem(IDC_COMBO_CSPLIST);
pCSPList->ResetContent(); while (CryptEnumProviders(dwIndex, NULL, 0, &dwType, NULL, &dwNameLen))
{
DWORD dwItem = 0;
TCHAR * pName = new TCHAR[dwNameLen + 1 ];
if (CryptEnumProviders(dwIndex++, NULL, 0, &dwType, pName, &dwNameLen))
{
dwItem = pCSPList->AddString(pName);
pCSPList->SetItemData(dwItem, dwType);
}
delete []pName;
}
pCSPList->SetCurSel(0);
OnCbnSelchangeComboCsplist();
}
五、获取CSP属性
得到CSP句柄之后,能够通过API:CryptGetProvParam()获取CSP的属性。比方该CSP具有的容器名、实现类型、支持算法等等。
比方以下的代码为获取当前CSP使用的容器名:
//获取CSP容器名称
dwParamLen = 2048;
memset(btParamData, 0, 2048);
pList->InsertItem(dwIndex, _T("PP_CONTAINER"), 0);
pList->SetItemText(dwIndex, 1, _T("密钥容器名称"));
if (CryptGetProvParam(hProv, PP_CONTAINER, btParamData, &dwParamLen, 0))
{
TCHAR *tcValue = NULL;
#ifdef UNICODE
tcValue = A2W((char*)btParamData);
#else
tcValue = (char*)btParamData;
#endif
pList->SetItemText(dwIndex, 2, tcValue);
}
else
{
pList->SetItemText(dwIndex, 2, _T("Failed!"));
}
以下的代码枚举CSP全部的容器名:
//获取CSP全部的容器名称
dwParamLen = 2048;
memset(btParamData, 0, 2048);
pList->InsertItem(dwIndex, _T("PP_ENUMCONTAINERS"), 0);
pList->SetItemText(dwIndex, 1, _T("全部容器名"));
if (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, btParamData, &dwParamLen, CRYPT_FIRST))
{
CString strContianers;
TCHAR *tcValue = NULL;
#ifdef UNICODE
tcValue = A2W((char*)btParamData);
#else
tcValue = btParamData;
#endif
strContianers += tcValue; dwParamLen = 2048;
memset(btParamData, 0, 2048);
while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, btParamData, &dwParamLen, CRYPT_NEXT))
{
#ifdef UNICODE
tcValue = A2W((char*)btParamData);
#else
tcValue = btParamData;
#endif
strContianers += _T("/");
strContianers += tcValue;
}
pList->SetItemText(dwIndex, 2, strContianers);
}
else
{
pList->SetItemText(dwIndex, 2, _T("Failed!"));
}
以下的代码获取CSP的所支持的算法:
//获取CSP所支持的算法信息
dwParamLen = 2048;
memset(btParamData, 0, 2048);
pList->InsertItem(dwIndex, _T("PP_ENUMALGS"), 0);
pList->SetItemText(dwIndex, 1, _T("支持的算法信息"));
if (CryptGetProvParam(hProv, PP_ENUMALGS, btParamData, &dwParamLen, CRYPT_FIRST))
{
CString strAlgs;
PROV_ENUMALGS* alg = (PROV_ENUMALGS*)btParamData;
TCHAR *tcValue = NULL;
#ifdef UNICODE
tcValue = A2W(alg->szName);
#else
tcValue = alg->szName;
#endif
strAlgs += tcValue; dwParamLen = 2048;
memset(btParamData, 0, 2048);
while (CryptGetProvParam(hProv, PP_ENUMALGS, btParamData, &dwParamLen, CRYPT_NEXT))
{
alg = (PROV_ENUMALGS*)btParamData;
#ifdef UNICODE
tcValue = A2W(alg->szName);
#else
tcValue = alg->szName;
#endif
strAlgs += _T("/");
strAlgs += tcValue;
}
pList->SetItemText(dwIndex, 2, strAlgs);
}
else
{
pList->SetItemText(dwIndex, 2, _T("Failed!"));
}
等等。
假设须要具体代码,请下载本人枚举CSP的样例。下载连接为:枚举CSP并获取属性
CSP介绍、以及使用CryptoAPI枚举CSP并获取其属性的更多相关文章
- Content Security Policy (CSP) 介绍
当我不经意间在 Twitter 页面 view source 后,发现了惊喜. <!DOCTYPE html> <html lang="en"> <h ...
- Effective Java —— 用私有构造器或枚举类型强化单例属性
本文参考 本篇文章参考自<Effective Java>第三版第三条"Enforce the singleton property with a private construc ...
- 枚举扩展方法获取枚举Description
枚举扩展方法 /// <summary> /// 扩展方法,获得枚举的Description /// </summary> /// <param name="v ...
- c# 枚举的定义,枚举的用法,获取枚举值
1.定义枚举类型 public enum Test { 男 = , 女 = } 2.获取枚举值 public void EnumsAction() { var s = Test.男;//男 var a ...
- Spring整合Struts2框架的第一种方式(Action由Struts2框架来创建)。在我的上一篇博文中介绍的通过web工厂的方式获取servcie的方法因为太麻烦,所以开发的时候不会使用。
1. spring整合struts的基本操作见我的上一篇博文:https://www.cnblogs.com/wyhluckdog/p/10140588.html,这里面将spring与struts2 ...
- JAVA枚举操作(获取值,转map集合)
JAVA枚举相对来说比.NET的枚举功能强大,感觉就像是一种简化版的类对象,可以有构造方法,可以重载,可以继承接口等等,但不能继承类,JAVA枚举在实际开发中应用相当频繁,以下几个封装方法在实际开发中 ...
- 如何在类中根据枚举值,获取枚举的message的工具类
枚举类为: public enum OrderStatusEnum implements CondeEnum{ NEW(0, "新订单"), FINISHED(1, "完 ...
- SpringBoot返回枚举对象中的指定属性
枚举 package com.meeno.boot.oa.employee.enums; import com.alibaba.fastjson.annotation.JSONType; import ...
- C#遍历获取枚举的值,名和属性
获取: Type type = typeof(ParamServiceType); var values = Enum.GetValues(type); ; i < values.Length; ...
随机推荐
- PCB MS CLR 聚合函数 joinString加排序实现
准备着手,动态列SQL查询,要实现动态列SQL,会运用到聚合函数,而SQL本身聚合函数有限, 无满足此用户任意字段组合变化,再加上工艺流程重复相同工序,如;沉铜1,沉铜2对应工序代码都是相同的 而通常 ...
- 【Python】循环语句
while循环 当条件成立时,循环体的内容可以一直执行,但是避免死循环,需要有一个跳出循环的条件才行. for循环 遍历任何序列(列表和字符串)中的每一个元素 >>> a = [&q ...
- B - Eleven
Problem description Eleven wants to choose a new name for herself. As a bunch of geeks, her friends ...
- java热部署
最近使用java做项目,研究了一下热部署,能够提高工作效率. 需要准备的工具: 1.安装文件http://update.zeroturnaround.com/update-site/ 2.破解 下载破 ...
- 树莓派-基于raspivid实现拍视频
经过上一篇<<树莓派-安装摄像头模块>>之后 想要用摄像头模块拍一段视频的话,可以从命令行运行 raspivid 工具.下面这句命令会按照默认配置(长度5秒,分辨率1920x1 ...
- 详细解读css中的浮动以及清除浮动的方法
对于前端初学者来说,css浮动部分的知识是一块比较难以理解的部分,下面我将把我学习过程中的心得分享给大家. 导读: 1.css块级元素讲解 2.css中浮动是如何产生的 3.出现浮动后,如何清除浮 ...
- Java上传视频
页面: 上传文件时的关键词:enctype="multipart/form-data" <%@ page language="java" import=& ...
- python爬虫:找房助手V1.0-爬取58同城租房信息
1.用于爬取58上的租房信息,限成都,其他地方的,可以把网址改改: 2.这个爬虫有一点问题,就是没用多线程,因为我用了之后总是会报: 'module' object has no attribute ...
- 设置Hadoop的 dataNode的单个Map的内存配置
1.进入hadoop的配置目录 ,找到 环境变量的 $HADOOP_HOME cd $HADOOP_HOME 2.修改dataNode 节点的 单个map的能使用的内存配置 找到配置的文件: /opt ...
- [Advanced Algorithm] - Validate US Telephone Numbers
题目 如果传入字符串是一个有效的美国电话号码,则返回 true. 用户可以在表单中填入一个任意有效美国电话号码. 下面是一些有效号码的例子(还有下面测试时用到的一些变体写法): 555-555-555 ...