crypt.tex
来自「文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2」· TEX 代码 · 共 1,456 行 · 第 1/5 页
TEX
1,456 行
\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:\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:\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:\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.\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:\begin{verbatim}int hmac_file(int hash, const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *dst, unsigned long *dstlen);\end{verbatim}``hash'' is the index into the hash descriptor table of the hash you want to use. ``fname'' is the filename to process. ``key'' is the array of octets to use as the key of length ``keylen''. ``dst'' is the array of octets where the result should be stored.To test if the HMAC code is working there is the following function:\begin{verbatim}int hmac_test(void);\end{verbatim}Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code. Some example code for using the HMAC system is given below.\begin{small}\begin{verbatim}#include <mycrypt.h>int main(void){ int idx, errno; hmac_state hmac; unsigned char key[16], dst[MAXBLOCKSIZE]; unsigned long dstlen; /* register SHA-1 */ if (register_hash(&sha1_desc) == -1) { printf("Error registering SHA1\n"); return -1; } /* get index of SHA1 in hash descriptor table */ idx = find_hash("sha1"); /* we would make up our symmetric key in "key[]" here */ /* start the HMAC */ if ((errno = hmac_init(&hmac, idx, key, 16)) != CRYPT_OK) { printf("Error setting up hmac: %s\n", error_to_string(errno)); return -1; } /* process a few octets */ if((errno = hmac_process(&hmac, "hello", 5) != CRYPT_OK) { printf("Error processing hmac: %s\n", error_to_string(errno)); return -1; } /* get result (presumably to use it somehow...) */ dstlen = sizeof(dst); if ((errno = hmac_done(&hmac, dst, &dstlen)) != CRYPT_OK) { printf("Error finishing hmac: %s\n", error_to_string(errno)); return -1; } printf("The hmac is %lu bytes long\n", dstlen); /* return */ return 0;}\end{verbatim}\end{small}\section{OMAC Support}OMAC\footnote{\url{http://crypt.cis.ibaraki.ac.jp/omac/omac.html}}, which stands for \textit{One-Key CBC MAC} is an algorithm which produces a Message Authentication Code (MAC) using only a block cipher such as AES. From an API standpoint the OMAC routines work much like the HMAC routines do. Instead in this case a cipher is used instead of a hash. To start an OMAC state you call\begin{verbatim}int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen);\end{verbatim}The ``omac'' variable is the state for the OMAC algorithm. ``cipher'' is the index into the cipher\_descriptor tableof the cipher\footnote{The cipher must have a 64 or 128 bit block size. Such as CAST5, Blowfish, DES, AES, Twofish, etc.} youwish to use. ``key'' and ``keylen'' are the keys used to authenticate the data.To send data through the algorithm call\begin{verbatim}int omac_process(omac_state *state, const unsigned char *buf, unsigned long len);\end{verbatim}This will send ``len'' bytes from ``buf'' through the active OMAC state ``state''. Returns \textbf{CRYPT\_OK} if the function succeeds. The function is not sensitive to the granularity of the data. For example,\begin{verbatim}omac_process(&mystate, "hello", 5);omac_process(&mystate, " world", 6);\end{verbatim}Would produce the same result as,\begin{verbatim}omac_process(&mystate, "hello world", 11);\end{verbatim}When you are done processing the message you can call the following to compute the message tag.\begin{verbatim}int omac_done(omac_state *state, unsigned char *out, unsigned long *outlen);\end{verbatim}Which will terminate the OMAC and output the \textit{tag} (MAC) to ``out''. Note that unlike the HMAC and other code ``outlen'' can be smaller than the default MAC size (for instance AES would make a 16-byte tag). Part of the OMAC specification states that the output may be truncated. So if you pass in $outlen = 5$ and use AES as your cipher thanthe output MAC code will only be five bytes long. If ``outlen'' is larger than the default size it is set to the defaultsize to show how many bytes were actually used.Similar to the HMAC code the file and memory functions are also provided. To OMAC a buffer of memory in one shot use the following function.\begin{verbatim}int omac_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *msg, unsigned long msglen, unsigned char *out, unsigned long *outlen);\end{verbatim}This will compute the OMAC of ``msglen'' bytes of ``msg'' using the key ``key'' of length ``keylen'' bytes and the cipherspecified by the ``cipher'''th entry in the cipher\_descriptor table. It will store the MAC in ``out'' with the samerules as omac\_done.To OMAC a file use\begin{verbatim}int omac_file(int cipher, const unsigned char *key, unsigned long keylen, const char *filename, unsigned char *out, unsigned long *outlen);\end{verbatim}Which will OMAC the entire contents of the file specified by ``filename'' using the key ``key'' of length ``keylen'' bytesand the cipher specified by the ``cipher'''th entry in the cipher\_descriptor table. It will store the MAC in ``out'' with the same rules as omac\_done.To test if the OMAC code is working there is the following function:\begin{verbatim}int omac_test(void);\end{verbatim}Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code. Some example code for using the OMAC system is given below.\begin{small}\begin{verbatim}#include <mycrypt.h>int main(void){ int idx, err; omac_state omac; unsigned char key[16], dst[MAXBLOCKSIZE]; unsigned long dstlen; /* register Rijndael */ if (register_cipher(&rijndael_desc) == -1) { printf("Error registering Rijndael\n"); return -1; } /* get index of Rijndael in cipher descriptor table */ idx = find_cipher("rijndael"); /* we would make up our symmetric key in "key[]" here */ /* start the OMAC */ if ((err = omac_init(&omac, idx, key, 16)) != CRYPT_OK) { printf("Error setting up omac: %s\n", error_to_string(err)); return -1; } /* process a few octets */ if((err = omac_process(&omac, "hello", 5) != CRYPT_OK) { printf("Error processing omac: %s\n", error_to_string(err)); return -1; } /* get result (presumably to use it somehow...) */ dstlen = sizeof(dst); if ((err = omac_done(&omac, dst, &dstlen)) != CRYPT_OK) { printf("Error finishing omac: %s\n", error_to_string(err)); return -1; } printf("The omac is %lu bytes long\n", dstlen); /* return */ return 0;}\end{verbatim}\end{small}\section{PMAC Support}The PMAC\footnote{J.Black, P.Rogaway, ``A Block--Cipher Mode of Operation for Parallelizable Message Authentication''} protocol is another MAC algorithm that relies solely on a symmetric-key block cipher. It uses essentially the sameAPI as the provided OMAC code. A PMAC state is initialized with the following.\begin{verbatim}int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen);\end{verbatim}Which initializes the ``pmac'' state with the given ``cipher'' and ``key'' of length ``keylen'' bytes. The chosen ciphermust have a 64 or 128 bit block size (e.x. AES).To MAC data simply send it through the process function.\begin{verbatim}int pmac_process(pmac_state *state, const unsigned char *buf, unsigned long len);\end{verbatim}This will process ``len'' bytes of ``buf'' in the given ``state''. The function is not sensitive to the granularity of thedata. For example,\begin{verbatim}pmac_process(&mystate, "hello", 5);pmac_process(&mystate, " world", 6);\end{verbatim}Would produce the same result as,\begin{verbatim}pmac_process(&mystate, "hello world", 11);\end{verbatim}When a complete message has been processed the following function can be called to compute the message tag.\begin{verbatim}int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen);\end{verbatim}This will store upto ``outlen'' bytes of the tag for the given ``state'' into ``out''. Note that if ``outlen'' is largerthan the size of the tag it is set to the amount of bytes stored in ``out''.Similar to the PMAC code the file and memory functions are also provided. To PM
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?