zoukankan      html  css  js  c++  java
  • crypto_2

     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_ATTR structures.
    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 of CERT_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          DWORD dwKeySpec,
      __in          DWORD dwCertEncodingType,
      __in          LPCSTR lpszStructType,
      __in          const void* pvStructInfo,
      __in          PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
      __in          const void* pvHashAuxInfo,
      __out         PBYTE pbEncoded,
      __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,用于存放数据的内存空间。
  • 相关阅读:
    std thread
    windows更新包发布地址
    How to set up logging level for Spark application in IntelliJ IDEA?
    spark 错误 How to set heap size in spark within the Eclipse environment?
    hadoop 常用命令
    windows 安装hadoop 3.2.1
    windows JAVA_HOME 路径有空格,执行软连接
    day01MyBatisPlus条件构造器(04)
    day01MyBatisPlus的CRUD 接口(03)
    day01MyBatisPlus入门(02)
  • 原文地址:https://www.cnblogs.com/lzjsky/p/1842053.html
Copyright © 2011-2022 走看看