📄 api.tex
字号:
\noindent\type{void} \function{update}(\type{const byte} \arg{input}[], \type{u32bit}\arg{length})\noindent\type{void} \function{update}(\type{byte} \arg{input})\noindent\type{void} \function{update}(\type{const std::string \&} \arg{input})Updates the hash/mac calculation with \arg{input}.\noindent\type{void} \function{final}(\type{byte} \arg{out}[OUTPUT\_LENGTH])\noindent\type{SecureVector<byte>} \function{final}():Complete the hash/MAC calculation and place the result into \arg{out}.OUTPUT\_LENGTH is a public constant in each object that gives the length of thehash in bytes. After you call \function{final}, the hash function is reset toit's initial state, so it may be reused immediately.The second method of using final is to call it with no arguments at all, asshown in the second prototype. It will return the hash/mac value in a memorybuffer, which will have size OUTPUT\_LENGTH.There are also a pair of functions called \function{process}. They areessentially a combination of a single \function{update}, and \function{final}.Both version return the final value, rather than placing it an array. Calling\function{process} with a single byte value isn't available, mostly because itwould rarely be useful.A MAC can be viewed (in most cases) as simply a keyed hash function, so classeswhich are derived from \type{MessageAuthenticationCode} have \function{update}and \function{final} classes just like a \type{HashFunction} (and like a\type{HashFunction}, after \function{final} is called, it can be used to make anew MAC right away; the key is kept around).A MAC has the \type{SymmetricAlgorithm} interface in addition to the\type{BufferedComputation} interface.\pagebreak\section{Public Key Cryptography}Public key algorithms were added in Botan 0.8.0. The major base classes can befound in \filename{pubkey.h}.\subsection{Creating PK Algorithm Key Objects}The library has interfaces for encryption, signatures, etc that do not requireknowing the exact algorithm in use (for example RSA and Rabin-Williamssignatures are handled by the exact same code path).One place where we \emph{do} need to know exactly what kind of algorithm is inuse is when we are creating a key (support for ASN.1 will remove this lateron). There are (currently) two kinds of public key algorithms in Botan: onesbased on integer factorization (RSA and Rabin-Williams), and ones based on thediscrete logarithm problem (DSA, Diffie-Hellman, Nyberg-Rueppel, andElGamal). Since discrete logarithm parameters (primes and generators) can beshared among many keys, there is the notion of these being a combined type(called \type{DL\_Group}).There are two was to create a DL private key (such as\type{DSA\_PrivateKey}). One is to pass in just a \type{DL\_Group} object -- anew key will automatically be generated. The other involves passing in a groupto use, along with both the public and private values (private value first).Since in integer factorization algorithms, the modulus used isn't shared byother keys, we don't use this notion. You can create a new key by passing in a\type{u32bit} telling how long (in bits) the key should be, or you can copy anpre-existing key by passing in the appropriate parameters (primes, exponents,etc). For RSA and Rabin-Williams (the two IF schemes in Botan), the parametersare all \type{BigInt}s: prime 1, prime 2, encryption exponent, decryptionexponent, modulus. The last two are optional, since they can easily be derivedfrom the first three.\subsubsection{Creating a DL\_Group}There are quite a few ways to get a \type{DL\_Group} object. The best is to usethe function \function{get\_dl\_group}, which takes a string naming a group; itwill either return that group, if it knows about it, or throw anexception. Names it knows about include ``IETF-n'' where n is 768, 1024, 1536,2048, 3072, or 4096, and ``DSA-n'', where n is 512, 768, or 1024. The IETFgroups are the ones specified for use with IPSec, and the DSA ones are thedefault DSA parameters specified by Java's JCE. For DSA and Nyberg-Rueppel, usethe ``DSA-n'' groups, and for Diffie-Hellman and ElGamal, use the ``IETF-n''groups.You can also generate a new random group. This is not recommend, because it isvery slow, particularly for ``safe'' primes, which are needed forDiffie-Hellman and ElGamal.You can register a new DL group with \function{add\_dl\_group} with a stringnaming the group and the \type{DL\_Group}. Future lookups on that name willreturn the group. There is no need (or reason) to register the group if youdo decide to use a distinct DL group for each key.If you pass the wrong group type (for example a DSA-style group to aDiffie-Hellman key object), it will throw an exception.\subsection{Parameter Checking}Most public key algorithms have limitations or restrictions on theirparameters. For example RSA requires an odd exponent, and algorithms based onthe discrete logarithm problem need a generator $> 1$.Each low-level public key type has a function named\function{check\_params}. This function returns a boolean value that declareswhether or not the key is valid (from an algorithmic standpoint). For example,it will check to make sure that the prime parameters of a DSA key are, in fact,prime. It does not have anything to do with the validity of the key for anyparticular use, nor does it have anything to do with certificates which link akey (which, after all, is just some numbers) with a user or other entity.Checks which can be done quickly tend to be done in the constructors (anexception will be thrown if an argument is checked in a constructor and foundto be invalid). Checking for primality, and a few other expensive things, aresaved for \function{check\_params}.If the keys you use are already authenticated in some way (for example storedin a user's encrypted key file, or signed by a CA), doing this is a needlesswaste of CPU time. So, essentially, make sure you call \function{check\_params}if you have any suspicions that the key might not be a valid one (and check thereturn value, naturally).\pagebreak\subsection{Getting a PK algorithm object}The key types, like \type{RSA\_PrivateKey}, do not implement any kind ofpadding or encoding (which is generally necessary for security). To get anobject like this, the easiest thing to do is call the functions found in\filename{look\_pk.h}. Generally these take a key, followed by a string thatspecified what hashing and encoding method(s) to use. Examples of such stringsare ``EME1(SHA-1)'' for OAEP encryption and ``EMSA4(SHA-1)'' for PSS signatures(where the message is hashed using SHA-1).Here are some basic examples (using an RSA key) to give you a feel for thepossibilities. These examples assume \type{rsakey} is an\type{RSA\_PrivateKey}, since otherwise we would not be able to create andecryption or signature object with it (you can create encryption or signatureverification objects with public keys, naturally). Remember to delete theseobjects when you're done with them.\begin{verbatim} // PKCS #1 v2.0 / IEEE 1363 compatible encryption PK_Encryptor* rsa_enc1 = get_pk_encryptor(rsakey, ``EME1(RIPEMD-160)''); // PKCS #1 v1.5 compatible encryption PK_Encryptor* rsa_enc2 = get_pk_encryptor(rsakey, ``PKCS1v15''); // Raw encryption: no padding, input is directly encrypted by the key // Don't use this unless you know what you're doing PK_Encryptor* rsa_enc3 = get_pk_encryptor(rsakey, ``Raw''); // This object can decrypt things encrypted by rsa_enc1 PK_Decryptor* rsa_dec1 = get_pk_decryptor(rsakey, ``EME1(RIPEMD-160)''); // PKCS #1 v1.5 compatible signatures PK_Signer* rsa_sig = get_pk_signer(rsakey, ``EMSA3(MD5)''); PK_Verifier* rsa_verify = get_pk_verifier(rsakey, ``EMSA3(MD5)''); // PKCS #1 v2.1 compatible signatures PK_Signer* rsa_sig2 = get_pk_signer(rsakey, ``EMSA4(SHA-1)''); PK_Verifier* rsa_verify2 = get_pk_verifier(rsakey, ``EMSA4(SHA-1)''); // Hash input with SHA-1, but don't pad the input in any way PK_Signer* rsa_sig = get_pk_signer(rsakey, ``EMSA1(SHA-1)'');\end{verbatim}Alternately, you can create the objects directly, like so:\begin{verbatim} PK_Signer rsa_pss_sig(rsakey, ``EMSA4(SHA-1)'');\end{verbatim}This works for everything except the signature verification algorithms. That'sbecause they come in two categories: those with message recovery (RSA,Rabin-Williams, Nyberg-Rueppel), and those without (DSA). \type{PK\_Verifier}is an abstract class, unlike the other PK interface adapters. It is subclassedby \type{PK\_Verifier\_wo\_MR} and \type{PK\_Verifier\_with\_MR}. So if youwant to create a verifier object without going through the\function{get\_pk\_X} functions, you need to know what kind of key you'reusing:\begin{verbatim} PK_Verifier_with_MR rsa_sig1(rsakey, ``EMSA1(SHA-1)''); // type mismatch, compile time error: PK_Verifier_with_MR dsa_sig1(dsakey, ``EMSA1(SHA-1)''); // this one will work PK_Verifier_wo_MR dsa_sig2(dsakey, ``EMSA1(SHA-1)'');\end{verbatim}\pagebreak\subsection{Encryption}The \type{PK\_Encryptor} and \type{PK\_Decryptor} classes are the interface forencryption and decryption, respectively.Calling \function{encrypt} with a \type{byte} array and a length parameter willreturn the input encrypted with whatever scheme is being used. Calling thesimilar \function{decrypt} will perform the inverse operation. You can also dothese operations with \type{SecureVector<byte>}s. In all cases, the output isreturned via a \type{SecureVector<byte>}.If you attempt an operation with a larger size than the key can support (thislimit varies based on the algorithm, the key size, and the padding method used(if any)), an exception will be throw. Alternately, you can call\function{maximum\_input\_size}, which will return the maximum size you cansafely encrypt. In fact, you can often encrypt an object that is one bytelonger, but only if enough of the high bits of the leading byte are set tozero.Available public key encryption algorithms in Botan are RSA and ElGamal. Theencoding methods are EME1, denoted by ``EME1(HASHNAME)'', PKCS \#1 v1.5,called ``PKCS1v15'' or ``EME-PKCS1-v1\_5'', and raw encoding (``Raw'').For compatibility reasons, PKCS \#1 v1.5 is recommend for use with ElGamal(most other implementations of ElGamal do not support any other encodingformat). RSA can also be used with PKCS encoding, but because of variouspossible attacks, EME1 is the preferred encoding. EME1 requires the use of ahash function: unless a competent applied cryptographer tells you otherwise,you should use SHA-1.Don't use ``Raw'' encoding unless you need it for backwards compatibility withold protocols. There are many possible attacks against both ElGamal and RSAwhen they are used this way.\subsection{Signatures}The signature algorithms look quite a bit like the hash functions. You canrepeatedly call \function{update}, giving more and more of a message you wishto sign, and then call \function{signature}, which will return a signature forthat message. If you want to do it all in one shot, call\function{sign\_message}, which will just call update with it's argument andthen return whatever \function{signature} returns.You can validate a signature by updating the verifier class, and finally seeingthe if the value returned from \function{valid\_signature} is true (you passthe supposed signature to the \function{valid\_signature} function as a bytearray and a length). There is another function, \function{verify\_message},which takes a pair of byte array/length pairs, the first of which is themessage, the second being the (supposed) signature. It returns true if thesignature is valid and false otherwise.Available public key signature algorithms in Botan are RSA, DSA,Nyberg-Rueppel, and Rabin-Williams. Signature encoding methods include EMSA1,EMSA2, EMSA3, EMSA4, and Raw. All of them, except Raw, take a parameter naminga message digest function to hash the message with. Raw actually signs theinput directly; if the message is too big, the signing operation will fail. Rawis not useful except in specialized applications.There are various interactions which make certain encoding schemes and signingalgorithms more or less useful.EMSA2 is the usual method for encoding Rabin-William signatures, so forcompatibility with other implementations you may have to use that. EMSA4 (alsocalled PSS), also works with Rabin-Williams. EMSA1 and EMSA3 do \emph{not} workwith Rabin-Williams.RSA can be used with any of the available encoding methods. EMSA4 is by far themost secure, but is not (as of now) widely implemented. EMSA3 (also called``EMSA-PKCS1-v1\_5'') is commonly used with RSA (for example in SSL). EMSA1signs the message digest directly, without any extra padding or encoding. Thismay be useful, but is not as secure as either EMSA3 or EMSA4. EMSA2 may be usedbut is not recommended.For DSA and Nyberg-Rueppel, you should use EMSA1. None of the other encodingmethods are particularly useful for these algorithms.\subsection{Key Agreement}You can get ahold of a \type{PK\_Key\_Agreement\_Scheme} object by calling\function{get\_pk\_kas} with a key that is of a type that supports keyagreement (such as a Diffie-Hellman key stored in a \type{DH\_PrivateKey}object), and the name of a key derivation function. This can be ``Raw'',meaning the output of the primitive itself is returned as the key, or
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -