CERT_INFO结构

1,解码CERT_INFO结构
   给定一个证书,第一步是调用函数CertCreateCertificateContext解码证书BLOB。当这个函数被调用,那么产生一个编码证书的复制品,创建一个CERT_CONETXT类型的结构和一个CERT_INFO类型的结构。一个certificate_context包含一个原始证书BLOB,一个CERT_CONETXT类型的结构以及一个CERT_INFO类型的结构。下面我们具体看看CERT_CONETXT以及CERT_INFO的结构(wincrypt.h):
  typedef struct _CERT_CONTEXT {
   DWORD dwCertEncodingType;
   BYTE *pbCertEncoded;
   DWORD cbCertEncoded;
   PCERT_INFO pCertInfo;
   HCERTSTORE hCertStore;
  } CERT_CONTEXT, *PCERT_CONTEXT;
  typedef const CERT_CONTEXT *PCCERT_CONTEXT;
  typedef struct _CERT_INFO {
   DWORD dwVersion;
   CRYPT_INTEGER_BLOB SerialNumber;
   CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;
   CERT_NAME_BLOB Issuer;
   FILETIME NotBefore;
   FILETIME NotAfter;
   CERT_NAME_BLOB Subject;
   CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo;
   CRYPT_BIT_BLOB IssuerUniqueId;
   CRYPT_BIT_BLOB SubjectUniqueId;
   DWORD cExtension;
   PCERT_EXTENSION rgExtension;
  } CERT_INFO, *PCERT_INFO;
  typedef struct _CERT_EXTENSIONS {
   DWORD cExtension;
   PCERT_EXTENSION rgExtension;
  } CERT_EXTENSIONS, *PCERT_EXTENSIONS;
  由上面的三个结构可以明显的看出证书的存储过程。(具体参数意思可以由参数名看出来)
   2,编码一个CERT_INFO结构
   编码过程和解码过程是相反的,下面事例如何增加签发者到CERT_INFO结构中。
   1,创建一个包含签发者名字的字符串。
   2,创建一个CERT_RDN_ATTR结构的数组,它初始化后能够包含刚刚创建的字符串。
   3,创建一个CERT_RDN结构的数组,它包含刚刚初始化的CERT_RDN_ATTR结构的数组
   4,创建一个CERT_NAME_INFO结构指向刚刚创建的CERT_RDN结构的数组的指针
   5,调用CryptEncodeObject函数来获取输出编码后BLOB的长度。
   6,为BLOB分配内存空间
   7,再次调用CryptEncodeObject函数,将有关编码信息写入
   8,设置CERT_INFO结构中的Issuer.cbData为第5步得到的长度,设置Issuer.pbData为第6步得到的地址,那么现在签发者就存在于CERT_INFO结构中了。
   添加一个编码后的扩展信息到CERT_INFO结构中
   1,初始化一个扩展信息结构。
   2,调用CryptEncodeObject,来获取所需空间大小。
   3,分配空间
   4,再次调用CryptEncodeObject来获取编码后的信息。
   5,创建一个CERT_EXTENSION结构数组
   6,初始化CERT_EXTENSION,并且在CERT_EXTENSION中添加刚刚编码后的信息。
   7,初始化CERT_INFO结构的rgExtension,并且把他指向CERT_EXTENSION结构数组(

 

接上:

1.CERT_RDN_ATTR 结构体

typedef struct _CERT_RDN_ATTR {
LPSTR pszObjId;
DWORD dwValueType;
CERT_RDN_VALUE_BLOB Value; } CERT_RDN_ATTR, 
*PCERT_RDN_ATTR;
pszObjId:对象标识符,用于标识证书属性,具体可以查看MSDN中的解析,也可以查看wincrypt.h文件查看相应的定义。譬如szOID_STATE_OR_PROVINCE_NAME,表示省名。
dwValueType:对成员Value的解析,取值查看MSDN,当主要是初始化证书属性时,Value的值主要是一些字符串时,该值可以为CERT_RDN_PRINTABLE_STRING,表示可以打印的字符串。
Value:一个结构体,在这里初始化证书属性。
typedef struct _CRYPTOAPI_BLOB {
DWORD cbData;
BYTE* pbData; } ,其中cbData表示大小,pbData指向一个内存空间。
2.CERT_RDN 结构体:The CERT_RDN structure contains a relative distinguished name (RDN) consisting of an array of CERT_RDN_ATTRstructures.
typedef struct _CERT_RDN {
DWORD cRDNAttr;
PCERT_RDN_ATTR rgRDNAttr; } CERT_RDN, 
*PCERT_RDN;
参数:cRDNAttr:rgRDNAttr数组元素的个数;rgRDNAttr:指向CERT_RDN_ATTR结构元素的数组地址。
3.CERT_NAME_INFO 结构体:The CERT_NAME_INFO structure contains subject or issuer names.The information is represented as an array ofCERT_RDN structures.
typedef struct _CERT_NAME_INFO {
DWORD cRDN;
PCERT_RDN rgRDN; } CERT_NAME_INFO, 
*PCERT_NAME_INFO;
参数:同上差不多。
4.CERT_REQUEST_INFO 证书请求结构体:这个结构体包含证书请求的主体,主体公钥,属性块等信息,这些信息都是经过编码的。
 
typedef struct _CERT_REQUEST_INFO {
DWORD dwVersion;
CERT_NAME_BLOB Subject;
CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo;
DWORD cAttribute;
PCRYPT_ATTRIBUTE rgAttribute; } CERT_REQUEST_INFO, 
*PCERT_REQUEST_INFO;
 
 
参数:dwVersion:证书版本号,可以为CERT_V1等,根据属性扩展情况,符合不同版本证书;Subject:证书主题;SubjectPublicKeyInfo:证书主题中的公钥信息;cAttribute:rgAttribute数组元素个数,可以为0;rgAttribute:属性参数数组,可以为NULL;
 
以上信息都是要经过编码后的信息来填充的。
5.CryptSignAndEncodeCertificate函数,用来创建自签名证书
 
BOOL WINAPI CryptSignAndEncodeCertificate( __in HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey, __in DWORDdwKeySpec, __in DWORD dwCertEncodingType, __in LPCSTR lpszStructType, __in const void* pvStructInfo, __in PCRYPT_ALGORITHM_IDENTIFIERpSignatureAlgorithm, __in const void* pvHashAuxInfo, __out PBYTEpbEncoded, __in_out DWORD* pcbEncoded ); 参数:1,CSP句柄;2,指明公钥是来自签名公钥还是交换公钥,可以为AT_KEYEXCHANGE或者AT_SIGNATURE之一;3,指明编码类型,可以为X509_ASN_ENCODING;4,结构体类型,和第5个参数配合起来使用,可以为X509_CERT_CRL_TO_BE_SIGNED或者X509_CERT_REQUEST_TO_BE_SIGNED或者X509_CERT_TO_BE_SIGNED或者X509_KEYGEN_REQUEST_TO_BE_SIGNED,意思可以查看MSDN。
 
6,签名算法结构体,指明签名算法,算法标识可以为szOID_RSA_MD5RSA 或者szOID_RSA_SHA1RSA 或者szOID_X957_SHA1DSA ;7,可以不用,设为NULL;8,签名后数据的长度,当设为NULL时,可以用来求数据的长度;9,用于存放数据的内存空间。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值