|
5 | 5 | * Enterprise Security API (ESAPI) project. For details, please see |
6 | 6 | * <a href="http://www.owasp.org/index.php/ESAPI">http://www.owasp.org/index.php/ESAPI</a>. |
7 | 7 | * |
8 | | - * Copyright (c) 2009 - The OWASP Foundation |
| 8 | + * Copyright © 2009 - The OWASP Foundation |
9 | 9 | */ |
10 | 10 | package org.owasp.esapi; |
11 | 11 |
|
12 | 12 | import java.io.Serializable; |
13 | 13 |
|
14 | | -// DISCUSS: Do we want to treat this as if it should be replaceable too??? |
| 14 | +import javax.crypto.SecretKey; |
| 15 | + |
| 16 | +// DISCUSS: Do we want to treat this as if it should be replaceable too? I.e., |
| 17 | +// to allow ESAPI users to replace the reference model DefaultCipherText. |
15 | 18 | // If so, perhaps we need to define the service provider side and define |
16 | 19 | // some appropriate 'setters'. More details in DefaultCipherText. |
17 | 20 | // Also, check the method names to see if they make sense / are intuitive. |
| 21 | +// However, I did not do this so it would take some additional work. -kww |
18 | 22 |
|
19 | 23 | /** |
20 | 24 | * A {@code Serializable} interface representing the result of encrypting |
21 | 25 | * plaintext and some additional information about the encryption algorithm, |
22 | | - * the IV (if pertinent), and an optional Message Integrity Code (MIC). |
| 26 | + * the IV (if pertinent), and an optional Message Authentication Code (MAC). |
23 | 27 | * <p> |
24 | | - * Copyright (c) 2009 - The OWASP Foundation |
| 28 | + * Copyright © 2009 - The OWASP Foundation |
25 | 29 | * </p> |
26 | 30 | * @author kevin.w.wall@gmail.com |
| 31 | + * @see PlainText |
27 | 32 | * @since 2.0 |
28 | 33 | */ |
29 | 34 | public interface CipherText extends Serializable { |
@@ -104,15 +109,17 @@ public interface CipherText extends Serializable { |
104 | 109 | public byte[] getIV(); |
105 | 110 |
|
106 | 111 | /** |
107 | | - * Return true if the cipher mode used requires an IV. |
| 112 | + * Return true if the cipher mode used requires an IV. Usually this will |
| 113 | + * be true unless ECB mode (which should be avoided whenever possible) is |
| 114 | + * used. |
108 | 115 | */ |
109 | 116 | public boolean requiresIV(); |
110 | 117 |
|
111 | 118 | /** |
112 | | - * Get the raw ciphertext byte array associated with encrypting some |
| 119 | + * Get the raw ciphertext byte array resulting from encrypting some |
113 | 120 | * plaintext. |
114 | 121 | * |
115 | | - * @return The raw ciphertext. |
| 122 | + * @return The raw ciphertext as a byte array. |
116 | 123 | */ |
117 | 124 | public byte[] getRawCipherText(); |
118 | 125 |
|
@@ -147,48 +154,73 @@ public interface CipherText extends Serializable { |
147 | 154 | public String getEncodedIVCipherText(); |
148 | 155 |
|
149 | 156 | /** |
150 | | - * Compute and store the Message Integrity Code (MIC) if the ESAPI property |
151 | | - * {@code Encryptor.CipherText.useMIC} is set to {@code true}. If it |
152 | | - * is, the MIC is calculated as: |
| 157 | + * Compute and store the Message Authentication Code (MAC) if the ESAPI property |
| 158 | + * {@code Encryptor.CipherText.useMAC} is set to {@code true}. If it |
| 159 | + * is, the MAC is conceptually calculated as: |
153 | 160 | * <pre> |
154 | | - * HMAC-SHA1(nonce, IV + secret_key) |
| 161 | + * authKey = DerivedKey(secret_key, "authenticate") |
| 162 | + * HMAC-SHA1(authKey, IV + secret_key) |
155 | 163 | * </pre> |
156 | | - * </p><p> |
157 | | - * As a side-effect, may set a nonce if it has not yet been calculated. |
| 164 | + * where derived key is an HMacSHA1, possibly repeated multiple times. |
| 165 | + * (See {@link org.owasp.esapi.util.CryptoHelper#computeDerivedKey(SecretKey, int, String)} |
| 166 | + * for details.) |
158 | 167 | * </p><p> |
159 | 168 | * <b>Perceived Benefits</b>: There are certain cases where if an attacker |
160 | | - * is able to change the IV |
| 169 | + * is able to change the IV. When one uses a authenticity key that is |
| 170 | + * derived from the "master" key, it also makes it possible to know when |
| 171 | + * the incorrect key was attempted to be used to decrypt the ciphertext. |
161 | 172 | * </p><p> |
162 | | - * <b>CAVEAT</b>: Even though an HMAC is used to compute this, since the HMAC |
163 | | - * key (the nonce) is contained in this {@code CipherText}, this is really a |
164 | | - * MIC and not an MAC. If there is some strange cryptographic attack that |
165 | | - * doing this permits (I am not aware of any, but that doesn't mean one |
166 | | - * doesn't exist; check with your own cryptography experts), then you might |
167 | | - * decide that the benefits don't outweigh the risks. Using a digital |
168 | | - * signature for this would be more secure, but is also much more computationally |
169 | | - * expensive. |
| 173 | + * <b>NOTE:</b> The purpose of this MAC (which is always computed by the |
| 174 | + * ESAPI reference model implementing {@code Encryptor}) is to ensure the |
| 175 | + * authenticity of the IV and ciphertext. Among other things, this prevents |
| 176 | + * an adversary from substituting the IV with one of their own choosing. |
| 177 | + * Because we don't know whether or not the recipient of this {@code CipherText} |
| 178 | + * object will want to validate the authenticity or not, the reference |
| 179 | + * implementation of {@code Encryptor} always computes it and includes it. |
| 180 | + * The recipient of the ciphertext can then choose whether or not to validate |
| 181 | + * it. |
170 | 182 | * |
171 | | - * @param secret_key The secret key with which the plaintext is encrypted. |
172 | | - */ // DISCUSS - Should this be secret_key or plaintext or neither? Have |
173 | | - // post out to two former colleagues with more crypto knowledge. |
174 | | - // May post to sci.crypt.research or elsewhere if no response. |
175 | | - // Secret key would be preferable since we can test MIC via |
176 | | - // validateMIC() even when decryption fails and results in |
177 | | - // BadPaddingException. If we definitely decide its safe to |
178 | | - // use the secret key, recommend changing arg for this method |
179 | | - // and validateMIC() to use SecretKey rather than the encoded |
180 | | - // secret key bytes. |
181 | | - public void computeAndStoreMIC(byte[] secret_key); |
| 183 | + * @param authKey The secret key that is used for proving authenticity of |
| 184 | + * the IV and ciphertext. This key should be derived from |
| 185 | + * the {@code SecretKey} passed to the |
| 186 | + * {@link Encryptor#encrypt(javax.crypto.SecretKey, PlainText)} |
| 187 | + * and |
| 188 | + * {@link Encryptor#decrypt(javax.crypto.SecretKey, CipherText)} |
| 189 | + * methods or the "master" key when those corresponding |
| 190 | + * encrypt / decrypt methods are used. This authenticity key |
| 191 | + * should be the same length and for the same cipher algorithm |
| 192 | + * as this {@code SecretKey}. The method |
| 193 | + * {@link org.owasp.esapi.util.CryptoHelper#computeDerivedKey(SecretKey, int, String)} |
| 194 | + * is a secure way to produce this derived key. |
| 195 | + */ // DISCUSS - Cryptographers David Wagner, Ian Grigg, and others suggest |
| 196 | + // computing authenticity using derived key and HmacSHA1 of IV + ciphertext. |
| 197 | + // However they also argue that what should be returned and treated as |
| 198 | + // (i.e., stored as) ciphertext would be something like this: |
| 199 | + // len_of_raw_ciphertext + IV + raw_ciphertext + MAC |
| 200 | + // I don't really think all that's necessary. If they want the equivalent, |
| 201 | + // then let then serialize this object. |
| 202 | + public void computeAndStoreMAC(SecretKey authKey); |
182 | 203 |
|
183 | 204 | /** |
184 | | - * Validate the message integrity code (MIC) associated with the ciphertext. |
| 205 | + * Validate the message authentication code (MAC) associated with the ciphertext. |
185 | 206 | * This is mostly meant to ensure that an attacker has not replaced the IV |
186 | 207 | * or raw ciphertext with something arbitrary. Note however that it will |
187 | 208 | * <i>not</i> detect the case where an attacker simply substitutes one |
188 | 209 | * valid ciphertext with another ciphertext. |
189 | 210 | * |
190 | | - * @param secretKey The raw bytes of the secret encryption key. |
| 211 | + * @param authKey The secret key that is used for proving authenticity of |
| 212 | + * the IV and ciphertext. This key should be derived from |
| 213 | + * the {@code SecretKey} passed to the |
| 214 | + * {@link Encryptor#encrypt(javax.crypto.SecretKey, PlainText)} |
| 215 | + * and |
| 216 | + * {@link Encryptor#decrypt(javax.crypto.SecretKey, CipherText)} |
| 217 | + * methods or the "master" key when those corresponding |
| 218 | + * encrypt / decrypt methods are used. This authenticity key |
| 219 | + * should be the same length and for the same cipher algorithm |
| 220 | + * as this {@code SecretKey}. The method |
| 221 | + * {@link org.owasp.esapi.util.CryptoHelper#computeDerivedKey(SecretKey, int, String)} |
| 222 | + * is a secure way to produce this derived key. |
191 | 223 | * @return True if the ciphertext has not be tampered with, and false otherwise. |
192 | 224 | */ |
193 | | - public boolean validateMIC(byte[] secretKey); // DISCUSS: See above discussion. |
| 225 | + public boolean validateMAC(SecretKey authKey); |
194 | 226 | } |
0 commit comments