CST(Crypto Systems Toolkit) 7.1学习笔记-chapter6

6,加密入门
 6.1,使用密码则安全
  非对称加密包括RSA,DSA,Diffie-Hellman...
  对称加密包括DES, Triple DES,RC2,RC4,IDEA,RC5,Blowfish,CAST...
  
  使用非对称和对称加密术来安全地发送一个消息:
  1,Generate a DES key.
  2,Encrypt the message M with the DES key to get M*.
  3,Get the recipient's RSA public key.
  4,Encrypt the DES key with the recipient's RSA public key to get K*.
  5,Send {K*, M*}.
  6.1.1,介绍术语key
 6.2,CST中的算法命名规则
  CST可以简单地使用不同的算法来写程序,它们使用相同的代码结构。例如:CST的BSAPI 产生key 使用bsapi_generate_key_ALG函数,
  如果ALG是一个对称算法(des,triple_des,rc2,bsa4,bsa5,rc4),函数产生一个secret key(私钥);如果ALG是一个非对称算法(dsa,rsa),
  它则产生一个公钥和私钥对.例如:使用bsapi_generate_key_des来产生一个对称DES的key.
  Algorithm   ALG
  DES      des
  Triple DES  triple_des
  RC2      rc2
  RC4      rc4
  DSA      dsa
  RSA      rsa
  BSA4     bsa4
  BSA5     bsa5
 6.3,产生一个key
  通过下面的四步来产生一个key:
  1,初始化一个随机数发生器;
  2,搜集随机数给发生器做种;
  3,如果可能,设置key产生参数;
  4,传递发生器和参数到一个key产生函数.
  
  在CST中,key参数结构:
  union bsapi_kparam_u
  {
   bsapi_kparam_des des;
   bsapi_kparam_rsa rsa;
   bsapi_kparam_dsa_com dsa_com;
   bsapi_kparam_dsa_key dsa_key;
   bsapi_kparam_rc2 rc2;
   bsapi_kparam_rc4 rc4;
  }bsapi_kparam;

  下面的代码使用这些参数来为DES产生一个key:
  prng_inst *prng;  //pseudo-random number generator
  bsapi_kparam kparam; //key generation parameters
  if (!(prng = prng_create_bbs(0)))
  {
   // log error
   ut_log0(0UL,UT_ACONTINUE,"Couldn't start prng");
   // insert your own error handling code here and stop processing
  }
  kparam.des.security = DES_NOEIGHTS; // eliminate all weak keys
  if (balg->generate_key(prng,&keyblk,0,&kparam))
  {
   // log error
   ut_log0(0UL,UT_ACONTINUE,"Couldn't generate key");
   // insert your own error handling code here and stop processing
  }
 6.4,加密,解密,标记和检验
  6.4.1初始化一个session:bsapi_mode,bsapi_kset,prng_create()
  在一个加密session能够被启动之前,可靠的初始参数和一个伪随机数产生器必须已经准备好。
  信息被传输到session用到两个结构:bsapi_mode和bsapi_kset,bsapi_mode表示算法如何被使用;
  bsapi_mode:定义如下:
  typedef enum
  {
   BSAPI_ENCRYPT,BSAPI_DECRYPT,BSAPI_SIGN,BSAPI_VERIFY
  }bsapi_mode_op;
  typedef enum
  {
   BSAPI_ECB,BSAPI_CBC,BSAPI_CFB,BSAPI_OFB
  }bsapi_mode_mode;
  typedef enum
  {
   BSAPI_SINGLE,BSAPI_TRIPLE,BSAPI_CHAIN3
  }bsapi_mode_triple;
  typedef enum
  {
   BSAPI_KEY,BSAPI_SCHEDULE
  }bsapi_mode_key_type;
  typedef enum
  {
   BSAPI_ANSI,BSAPI_FAST
  }bsapi_mode_fast;
  typedef struct bsapi_mode_s
  {
   bsapi_mode_op     op;
   bsapi_mode_mode   mode;
   bsapi_mode_triple triple;
   bsapi_mode_key_type key_type;
   bsapi_mode_fast fast;
  }bsapi_mode;
  说明以上结构字段:
  op:指明一个session 将用来加密,解密,标记,检验。DES,Triple DES,RC2,RC4,BSA4和BSA5仅能用于加密和解密;
    RSA可用于所有的四种;DSA仅能用于标记和检验。
  mode:指示哪一个ANSI mode被使用:有下面四种:
    (1,BSAPI_ECB--Electronic Code Book;2,BSAPI_CBC--Cipher Block Chaining;3,BSAPI_CFB--Cipher Feedback;4,BSAPI_OFB--Output Feedback)
  triple:这个字段仅仅应用于DES和RC2,指示是否triple加密术被使用。
  key_type:指示key(s)是作为plain keys(BSAPI_KEY)支持还是作为precomputed subkeys(BSAPI_SCHEDULE)支持。
  fast:
  
  bsapi_kset:定义如下:
  typedef enum
  {
    BSAPI_KEY_TYPE_DEFAULT, BSAPI_SECRET, BSAPI_PUBLIC
  } bsapi_kset_key_type;
  #define BSAPI_PRIVATE BSAPI_SECRET
  typedef enum
  {
    BSAPI_DATA_TYPE_DEFAULT, BSAPI_DATA_TYPE_DATA, BSAPI_DATA_TYPE_HASH
  } bsapi_kset_data_type;
  typedef struct bsapi_kset_s
  {
    ut_mblk              *keys;
    ut_mblk              *shrdpub;
   #define   community     shrdpub
    u32                   effbits;   /* effective key-length RC2 only */
    ut_mblk              *iv;
    unsigned              feedback;  /* OFB and CFB only */
    const pad_alg        *padalg;
    pad_params           *padpar;
    const hash_alg       *hashalg;
    unsigned              hashbits;
    bsapi_kset_data_type  data_type; /* when signing/verifying, are we passed
                                    * the message text or its hash */
    ut_mblk              *pnonce;    /* private nonce */
   #define    k_values     pnonce
    FILE                 *pnfprnt;   /* footprint database for private nonces */
    bsapi_kset_key_type   key_type;  /* deprecated; use pad_params */
  } bsapi_kset;

  好的习惯是先这样:
  bsapi_kset bkeys = {0};它可以确保一些默认的设置被使用。
  
  6.4.2,一个session例子:加密
   所有的CST加密和解密操作使用三个主要的函数:
   bsapi_start_ALG():初始化一个session;
   bsapi_append_ALG():传递数据给session,开始处理;
   bsapi_finish_ALG():结束这个session.
   下面的例子说明了上面三个函数:
   int descrypt(u8 *in,size_t inlen,u8 **out, size_t *outlen, ut_mblk *key)
   {
    bsapi_mode md = {BSAPI_ENCRYPT, BSAPI_ECB, BSAPI_SINGLE, BSAPI_KEY, BSAPI_ANSI};
    bsapi_kset keys = {0};
    bsapi_id mach;
    prng_inst *prng;
    ut_mblk_list cyph;
    ut_mblk_list tmp;
    // set parameters
    keys.keys = key;
    keys.padalg = &pad_pkcs5; // standard padding for DES
    prng = prng_create_r48(0); // default parameters
    // encrypt
    mach = bsapi_start_des(&md, prng, &keys);
    bsapi_append_des(in, inlen, mach);
    bsapi_finish_des(mach, &cyph);
    // get lengthh of output.the output is in cyph, a ut_mblk_list.
    // the final item in a list produced by bsapi_finish_ALG() can be identified by
    // (item)->next = 0.we add the lengths of the individual output blocks until this confition is true.
    *outlen = 0;
    for (tmp = cyph;tmp;tmp = tmp->next)
     *outlen += tmp->block.used;
    // allocate memory for output and copy it over
    *out = ut_new_mem(*outlen);
    *outlen = 0;
    for (tmp = cyph; tmp; tmp = tmp->next)
    {
     memcpy(*out + *outlen, tmp->block.data, tmp->block.used);
     *outlen += tmp->block.used;
    }
    // free the memory from the list and close down the random number generator
    ut_dispose_list(cyph);
    prng->destroy(prng);
    // return successfully
    return 0;
   }
   
  6.4.3,一个比较长的session:解密
  int longdescrypt (FILE *in, FILE *out, ut_mblk *key)
  {
    bsapi_mode    md = {BSAPI_DECRYPT, BSAPI_ECB, BSAPI_SINGLE, BSAPI_KEY, BSAPI_ANSI};
    bsapi_kset    keys = {0};
    bsapi_id      mach;
    prng_inst    *prng;
    ut_mblk_list  cyph;
    u8            buf[BUFSIZ];
    size_t        readlen;       /* amount read from file */
    /* set parameters */
    keys.keys = key;
    keys.padalg = &pad_pkcs5;    /* standard padding for DES */
    prng = prng_create_r48 (0);   /* default parameters */
    /* start encryption session */
    mach = bsapi_start_des (&md, prng, &keys);
    /* read data from the input file, pass it to the session, and write
     * the output from the session to the output file.
     * the ut_mblk_list which is produced by bsapi_readmost_des will only*/
  
    while (readlen = fread (buf, sizeof (u8), BUFSIZ, in))
    {
      bsapi_append_des (buf, readlen, mach);
      cyph = bsapi_readmost_des (mach);
      for (tmp=cyph; tmp; tmp = tmp->next)
        fwrite (tmp->block.data, sizeof (u8), tmp->block.used,out);
      ut_dispose_list (cyph);
    }
    bsapi_finish_des (mach, &cyph);
   
    for (tmp = cyph; tmp; tmp = tmp->next)
      fwrite (tmp->block.data, sizeof (u8), tmp->block.used, out);
    /* free the memory from the list and close down the random number generator */
    ut_dispose_list (cyph);
    prng->destroy (prng);
    /* return successfully */
    return 0;
  }
  
  6.4.4,一个session例子:标记和检验
   int rsasign (u8 *msg, size_t msglen, ut_mblk *priv, ut_mblk *pub)
   {
     bsapi_mode    md = {0};
     bsapi_kset    keys = {0};
     bsapi_id      mach;
     ut_mblk_list  cyph;
     ut_mblk_list  tmp;
     prng_inst    *prng;
     int           rval = 0;      /* default return value is failure */
     /* set up signing parameters */
     md.op = BSAPI_SIGN;
     keys.keys = priv;            /* use private key to generate signatures */
     keys.padalg = &pad_pkcs1;    /* standard for RSA signing */
     keys.hashalg = &hash_sha;    /* use SHA-1 as hash algorithm */
     prng = prng_create_r48 (0);
     /* sign */
     mach = bsapi_start_rsa (&md, prng, &keys);
     bsapi_append_rsa (msg, msglen, mach);
     bsapi_finish_rsa (mach, &cyph);
     /* cyph contains a single ut_mblk; cyph->block.data is the signature
      * data, cyph->block.used is the length of the signature data. For now,
      * we simply pass it back to the verification session. */
     /* set up verification parameters */
     md.op = BSAPI_VERIFY;
     keys.keys = pub;             /* use public key to verify signatures */
     keys.padalg = &pad_ pkcs1;   /* standard for RSA signing */
     keys.hashalg = &hash_sha;    /* use SHA-1 as hash algorithm */
     /* verify. Note that the message that was signed is passed to
      * bsapi_append_rsa(), while the signature itself is passed to
      * bsapi_finish_rsa(). The return value from bsapi_finish_rsa() tells us
      * whether the signature was good, the signature was bad, or there was an
      * internal failure in the verification session */
     mach = bsapi_start_rsa (&md, prng, &keys);
     bsapi_append_rsa (msg, msglen, mach);
     switch (bsapi_finish_rsa (mach, &cyph))
     {
       case 0:
         printf("validated sig OK./n");
         rval = 1;
         break;
       case 1:
       case 2:
         printf("Bad Sig!/n");
         break;
       case -1:
         ut_log0 (0UL, UT_ACONTINUE, "internal error in bsapi_finish_rsa()");
         /* insert your own error handling code here and stop processing */
         break;
       default:
         printf("Unexpected return value from bsapi_finish_rsa()/n");
     }
     /* Tidy up and shutdown */
     ut_dispose_list (cyph);
     prng->destroy (prng);
     return rval;
   }

 6.5,增强特性:bsapi_alg结构

你可能感兴趣的:(加密技术)