⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crypt.tex

📁 最新版本的加密解密算法库
💻 TEX
📖 第 1 页 / 共 5 页
字号:
appropriately.\chapter{One-Way Cryptographic Hash Functions}\section{Core Functions}Like the ciphers there are hash core functions and a universal data type to hold the hash state called ``hash\_state''.  To initialize hash XXX (where XXX is the name) call:\index{Hash Functions}\begin{verbatim}void XXX_init(hash_state *md);\end{verbatim}This simply sets up the hash to the default state governed by the specifications of the hash.  To add data to the message being hashed call:\begin{verbatim}int XXX_process(hash_state *md, const unsigned char *in, unsigned long len);\end{verbatim}Essentially all hash messages are virtually infinitely\footnote{Most hashes are limited to $2^{64}$ bits or 2,305,843,009,213,693,952 bytes.} long message which are buffered.  The data can be passed in any sized chunks as long as the order of the bytes are the same the message digest(hash output) will be the same.  For example, this means that:\begin{verbatim}md5_process(&md, "hello ", 6);md5_process(&md, "world", 5);\end{verbatim}Will produce the same message digest as the single call:\index{Message Digest}\begin{verbatim}md5_process(&md, "hello world", 11);\end{verbatim}To finally get the message digest (the hash) call:\begin{verbatim}int XXX_done(hash_state *md,               unsigned char *out);\end{verbatim}This function will finish up the hash and store the result in the ``out'' array.  You must ensure that ``out'' is longenough for the hash in question.  Often hashes are used to get keys for symmetric ciphers so the ``XXX\_done()'' functionswill wipe the ``md'' variable before returning automatically.To test a hash function call:\begin{verbatim}int XXX_test(void);\end{verbatim}This will return {\bf CRYPTO\_OK} if the hash matches the test vectors, otherwise it returns an error code.  Anexample snippet that hashes a message with md5 is given below.\begin{small}\begin{verbatim}#include <mycrypt.h>int main(void){    hash_state md;    unsigned char *in = "hello world", out[16];    /* setup the hash */    md5_init(&md);    /* add the message */    md5_process(&md, in, strlen(in));    /* get the hash in out[0..15] */    md5_done(&md, out);    return 0;}\end{verbatim}\end{small}\section{Hash Descriptors}Like the set of ciphers the set of hashes have descriptors too.  They are stored in an array called ``hash\_descriptor'' andare defined by:\begin{verbatim}struct _hash_descriptor {    char *name;    unsigned long hashsize;    /* digest output size in bytes  */    unsigned long blocksize;   /* the block size the hash uses */    void (*init)   (hash_state *);    int  (*process)(hash_state *, const unsigned char *, unsigned long);    int  (*done)   (hash_state *, unsigned char *);    int  (*test)   (void);};\end{verbatim}Similarly ``name'' is the name of the hash function in ASCII (all lowercase).  ``hashsize'' is the size of the digest outputin bytes.  The remaining fields are pointers to the functions that do the respective tasks.  There is a function tosearch the array as well called ``int find\_hash(char *name)''.  It returns -1 if the hash is not found, otherwise theposition in the descriptor table of the hash.You can use the table to indirectly call a hash function that is chosen at runtime.  For example:\begin{small}\begin{verbatim}#include <mycrypt.h>int main(void){   unsigned char buffer[100], hash[MAXBLOCKSIZE];   int idx, x;   hash_state md;   /* register hashes .... */   if (register_hash(&md5_desc) == -1) {      printf("Error registering MD5.\n");      return -1;   }   /* register other hashes ... */   /* prompt for name and strip newline */   printf("Enter hash name: \n");   fgets(buffer, sizeof(buffer), stdin);   buffer[strlen(buffer) - 1] = 0;   /* get hash index */   idx = find_hash(buffer);   if (idx == -1) {      printf("Invalid hash name!\n");      return -1;   }   /* hash input until blank line */   hash_descriptor[idx].init(&md);   while (fgets(buffer, sizeof(buffer), stdin) != NULL)         hash_descriptor[idx].process(&md, buffer, strlen(buffer));   hash_descriptor[idx].done(&md, hash);   /* dump to screen */   for (x = 0; x < hash_descriptor[idx].hashsize; x++)       printf("%02x ", hash[x]);   printf("\n");   return 0;}\end{verbatim}\end{small}Note the usage of ``MAXBLOCKSIZE''.  In Libtomcrypt no symmetric block, key or hash digest is larger than MAXBLOCKSIZE inlength.  This provides a simple size you can set your automatic arrays to that will not get overrun.There are three helper functions as well:\index{hash\_memory()} \index{hash\_file()}\begin{verbatim}int hash_memory(int hash, const unsigned char *data,                 unsigned long len, unsigned char *dst,                unsigned long *outlen);int hash_file(int hash, const char *fname,               unsigned char *dst,              unsigned long *outlen);int hash_filehandle(int hash, FILE *in,                     unsigned char *dst, unsigned long *outlen);\end{verbatim}The ``hash'' parameter is the location in the descriptor table of the hash (\textit{e.g. the return of find\_hash()}).  The ``*outlen'' variable is used to keep track of the output size.  Youmust set it to the size of your output buffer before calling the functions.  When they complete succesfully they storethe length of the message digest back in it.  The functions are otherwise straightforward.  The ``hash\_filehandle'' function assumes that ``in'' is an file handle opened in binary mode.  It will hash to the end of file and not resetthe file position when finished.To perform the above hash with md5 the following code could be used:\begin{small}\begin{verbatim}#include <mycrypt.h>int main(void){   int idx, err;   unsigned long len;   unsigned char out[MAXBLOCKSIZE];   /* register the hash */   if (register_hash(&md5_desc) == -1) {      printf("Error registering MD5.\n");      return -1;   }   /* get the index of the hash  */   idx = find_hash("md5");   /* call the hash */   len = sizeof(out);   if ((err = hash_memory(idx, "hello world", 11, out, &len)) != CRYPT_OK) {      printf("Error hashing data: %s\n", error_to_string(err));      return -1;   }   return 0;}\end{verbatim}\end{small}The following hashes are provided as of this release:\index{Hash descriptor table}\begin{center}\begin{tabular}{|c|c|c|}      \hline Name & Descriptor Name & Size of Message Digest (bytes) \\      \hline WHIRLPOOL & whirlpool\_desc & 64 \\      \hline SHA-512 & sha512\_desc & 64 \\      \hline SHA-384 & sha384\_desc & 48 \\      \hline SHA-256 & sha256\_desc & 32 \\      \hline SHA-224 & sha224\_desc & 28 \\      \hline TIGER-192 & tiger\_desc & 24 \\      \hline SHA-1 & sha1\_desc & 20 \\      \hline RIPEMD-160 & rmd160\_desc & 20 \\      \hline RIPEMD-128 & rmd128\_desc & 16 \\      \hline MD5 & md5\_desc & 16 \\      \hline MD4 & md4\_desc & 16 \\      \hline MD2 & md2\_desc & 16 \\      \hline\end{tabular}\end{center}Similar to the cipher descriptor table you must register your hash algorithms before you can use them.  These functionswork exactly like those of the cipher registration code.  The functions are:\index{register\_hash()} \index{unregister\_hash()}\begin{verbatim}int register_hash(const struct _hash_descriptor *hash);int unregister_hash(const struct _hash_descriptor *hash);\end{verbatim}\subsection{Notice}It is highly recommended that you \textbf{not} use the MD4 or MD5 hashes for the purposes of digital signatures or authentication codes.  These hashes are provided for completeness and they still can be used for the purposes of password hashing or one-way accumulators(e.g. Yarrow).The other hashes such as the SHA-1, SHA-2 (that includes SHA-512, SHA-384 and SHA-256) and TIGER-192 are still considered securefor all purposes you would normally use a hash for.\chapter{Message Authentication Codes}\section{HMAC Protocol}Thanks to Dobes Vandermeer the library now includes support for hash based message authenication codes or HMAC for short.  An HMACof a message is a keyed authenication code that only the owner of a private symmetric key will be able to verify.  The purpose isto allow an owner of a private symmetric key to produce an HMAC on a message then later verify if it is correct.  Any impostor oreavesdropper will not be able to verify the authenticity of a message.  The HMAC support works much like the normal hash functions except that the initialization routine requires you to pass a key and its length.  The key is much like a key you would pass to a cipher.  That is, it is simply an array of octets stored inchars.  The initialization routine is:\index{hmac\_init()}\begin{verbatim}int hmac_init(hmac_state *hmac, int hash,               const unsigned char *key, unsigned long keylen);\end{verbatim}The ``hmac'' parameter is the state for the HMAC code.  ``hash'' is the index into the descriptor table of the hash you wantto use to authenticate the message.  ``key'' is the pointer to the array of chars that make up the key.  ``keylen'' is thelength (in octets) of the key you want to use to authenticate the message.  To send octets of a message through the HMAC system you must use the following function:\index{hmac\_process()}\begin{verbatim}int hmac_process(hmac_state *hmac, const unsigned char *buf,                  unsigned long len);\end{verbatim}``hmac'' is the HMAC state you are working with. ``buf'' is the array of octets to send into the HMAC process.  ``len'' is thenumber of octets to process.  Like the hash process routines you can send the data in arbitrarly sized chunks. When you are finished with the HMAC process you must call the following function to get the HMAC code:\index{hmac\_done()}\begin{verbatim}int hmac_done(hmac_state *hmac, unsigned char *hashOut,              unsigned long *outlen);\end{verbatim}``hmac'' is the HMAC state you are working with.  ``hashOut'' is the array of octets where the HMAC code should be stored.  You mustset ``outlen'' to the size of the destination buffer before calling this function.  It is updated with the length of the HMAC codeproduced (depending on which hash was picked).  If ``outlen'' is less than the size of the message digest (and ultimatelythe HMAC code) then the HMAC code is truncated as per FIPS-198 specifications (e.g. take the first ``outlen'' bytes).There are two  utility functions provided to make using HMACs easier todo.  They accept the key and information about themessage (file pointer, address in memory) and produce the HMAC result in one shot.  These are useful if you want to avoidcalling the three step process yourself.\index{hmac\_memory()}\begin{verbatim}int hmac_memory(int hash, const unsigned char *key, unsigned long keylen,                const unsigned char *data, unsigned long len,                 unsigned char *dst, unsigned long *dstlen);\end{verbatim}This will produce an HMAC code for the array of octets in ``data'' of length ``len''.  The index into the hash descriptor table must be provided in ``hash''.  It uses the key from ``key'' with a key length of ``keylen''.  The result is stored in the array of octets ``dst'' and the length in ``dstlen''.  The value of ``dstlen'' must be setto the size of the destination buffer before calling this function.  Similarly for files there is the  following function:\index{hmac\_file()}\begin{verbatim}int hmac_file(int hash, const char *fname, const unsigned char *key,              unsigned long keylen,               unsigned char

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -