1 /* 2 * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.security; 27 28 import java.util.*; 29 import java.lang.*; 30 import java.io.IOException; 31 import java.io.ByteArrayOutputStream; 32 import java.io.PrintStream; 33 import java.io.InputStream; 34 import java.io.ByteArrayInputStream; 35 36 import java.nio.ByteBuffer; 37 38 /** 39 * This MessageDigest class provides applications the functionality of a 40 * message digest algorithm, such as SHA-1 or SHA-256. 41 * Message digests are secure one-way hash functions that take arbitrary-sized 42 * data and output a fixed-length hash value. 43 * 44 * <p>A MessageDigest object starts out initialized. The data is 45 * processed through it using the {@link #update(byte) update} 46 * methods. At any point {@link #reset() reset} can be called 47 * to reset the digest. Once all the data to be updated has been 48 * updated, one of the {@link #digest() digest} methods should 49 * be called to complete the hash computation. 50 * 51 * <p>The <code>digest</code> method can be called once for a given number 52 * of updates. After <code>digest</code> has been called, the MessageDigest 53 * object is reset to its initialized state. 54 * 55 * <p>Implementations are free to implement the Cloneable interface. 56 * Client applications can test cloneability by attempting cloning 57 * and catching the CloneNotSupportedException: <p> 58 * 59 * <pre> 60 * MessageDigest md = MessageDigest.getInstance("SHA"); 61 * 62 * try { 63 * md.update(toChapter1); 64 * MessageDigest tc1 = md.clone(); 65 * byte[] toChapter1Digest = tc1.digest(); 66 * md.update(toChapter2); 67 * ...etc. 68 * } catch (CloneNotSupportedException cnse) { 69 * throw new DigestException("couldn't make digest of partial content"); 70 * } 71 * </pre> 72 * 73 * <p>Note that if a given implementation is not cloneable, it is 74 * still possible to compute intermediate digests by instantiating 75 * several instances, if the number of digests is known in advance. 76 * 77 * <p>Note that this class is abstract and extends from 78 * <code>MessageDigestSpi</code> for historical reasons. 79 * Application developers should only take notice of the methods defined in 80 * this <code>MessageDigest</code> class; all the methods in 81 * the superclass are intended for cryptographic service providers who wish to 82 * supply their own implementations of message digest algorithms. 83 * 84 * <p> Android provides the following <code>MessageDigest</code> algorithms: 85 * <table> 86 * <thead> 87 * <tr> 88 * <th>Name</th> 89 * <th>Supported (API Levels)</th> 90 * </tr> 91 * </thead> 92 * <tbody> 93 * <tr> 94 * <td>MD5</td> 95 * <td>1+</td> 96 * </tr> 97 * <tr> 98 * <td>SHA-1</td> 99 * <td>1+</td> 100 * </tr> 101 * <tr> 102 * <td>SHA-224</td> 103 * <td>1–8,22+</td> 104 * </tr> 105 * <tr> 106 * <td>SHA-256</td> 107 * <td>1+</td> 108 * </tr> 109 * <tr> 110 * <td>SHA-384</td> 111 * <td>1+</td> 112 * </tr> 113 * <tr> 114 * <td>SHA-512</td> 115 * <td>1+</td> 116 * </tr> 117 * </tbody> 118 * </table> 119 * 120 * These algorithms are described in the <a href= 121 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest"> 122 * MessageDigest section</a> of the 123 * Java Cryptography Architecture Standard Algorithm Name Documentation. 124 * 125 * @author Benjamin Renaud 126 * 127 * @see DigestInputStream 128 * @see DigestOutputStream 129 */ 130 131 public abstract class MessageDigest extends MessageDigestSpi { 132 133 private String algorithm; 134 135 // The state of this digest 136 private static final int INITIAL = 0; 137 private static final int IN_PROGRESS = 1; 138 private int state = INITIAL; 139 140 // The provider 141 private Provider provider; 142 143 /** 144 * Creates a message digest with the specified algorithm name. 145 * 146 * @param algorithm the standard name of the digest algorithm. 147 * See the MessageDigest section in the <a href= 148 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest"> 149 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 150 * for information about standard algorithm names. 151 */ MessageDigest(String algorithm)152 protected MessageDigest(String algorithm) { 153 this.algorithm = algorithm; 154 } 155 156 /** 157 * Returns a MessageDigest object that implements the specified digest 158 * algorithm. 159 * 160 * <p> This method traverses the list of registered security Providers, 161 * starting with the most preferred Provider. 162 * A new MessageDigest object encapsulating the 163 * MessageDigestSpi implementation from the first 164 * Provider that supports the specified algorithm is returned. 165 * 166 * <p> Note that the list of registered providers may be retrieved via 167 * the {@link Security#getProviders() Security.getProviders()} method. 168 * 169 * @param algorithm the name of the algorithm requested. 170 * See the MessageDigest section in the <a href= 171 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest"> 172 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 173 * for information about standard algorithm names. 174 * 175 * @return a Message Digest object that implements the specified algorithm. 176 * 177 * @exception NoSuchAlgorithmException if no Provider supports a 178 * MessageDigestSpi implementation for the 179 * specified algorithm. 180 * 181 * @see Provider 182 */ getInstance(String algorithm)183 public static MessageDigest getInstance(String algorithm) 184 throws NoSuchAlgorithmException { 185 try { 186 Object[] objs = Security.getImpl(algorithm, "MessageDigest", 187 (String)null); 188 if (objs[0] instanceof MessageDigest) { 189 MessageDigest md = (MessageDigest)objs[0]; 190 md.provider = (Provider)objs[1]; 191 return md; 192 } else { 193 MessageDigest delegate = 194 new Delegate((MessageDigestSpi)objs[0], algorithm); 195 delegate.provider = (Provider)objs[1]; 196 return delegate; 197 } 198 } catch(NoSuchProviderException e) { 199 throw new NoSuchAlgorithmException(algorithm + " not found"); 200 } 201 } 202 203 /** 204 * Returns a MessageDigest object that implements the specified digest 205 * algorithm. 206 * 207 * <p> A new MessageDigest object encapsulating the 208 * MessageDigestSpi implementation from the specified provider 209 * is returned. The specified provider must be registered 210 * in the security provider list. 211 * 212 * <p> Note that the list of registered providers may be retrieved via 213 * the {@link Security#getProviders() Security.getProviders()} method. 214 * 215 * @param algorithm the name of the algorithm requested. 216 * See the MessageDigest section in the <a href= 217 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest"> 218 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 219 * for information about standard algorithm names. 220 * 221 * @param provider the name of the provider. 222 * 223 * @return a MessageDigest object that implements the specified algorithm. 224 * 225 * @exception NoSuchAlgorithmException if a MessageDigestSpi 226 * implementation for the specified algorithm is not 227 * available from the specified provider. 228 * 229 * @exception NoSuchProviderException if the specified provider is not 230 * registered in the security provider list. 231 * 232 * @exception IllegalArgumentException if the provider name is null 233 * or empty. 234 * 235 * @see Provider 236 */ getInstance(String algorithm, String provider)237 public static MessageDigest getInstance(String algorithm, String provider) 238 throws NoSuchAlgorithmException, NoSuchProviderException 239 { 240 if (provider == null || provider.length() == 0) 241 throw new IllegalArgumentException("missing provider"); 242 Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider); 243 if (objs[0] instanceof MessageDigest) { 244 MessageDigest md = (MessageDigest)objs[0]; 245 md.provider = (Provider)objs[1]; 246 return md; 247 } else { 248 MessageDigest delegate = 249 new Delegate((MessageDigestSpi)objs[0], algorithm); 250 delegate.provider = (Provider)objs[1]; 251 return delegate; 252 } 253 } 254 255 /** 256 * Returns a MessageDigest object that implements the specified digest 257 * algorithm. 258 * 259 * <p> A new MessageDigest object encapsulating the 260 * MessageDigestSpi implementation from the specified Provider 261 * object is returned. Note that the specified Provider object 262 * does not have to be registered in the provider list. 263 * 264 * @param algorithm the name of the algorithm requested. 265 * See the MessageDigest section in the <a href= 266 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest"> 267 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 268 * for information about standard algorithm names. 269 * 270 * @param provider the provider. 271 * 272 * @return a MessageDigest object that implements the specified algorithm. 273 * 274 * @exception NoSuchAlgorithmException if a MessageDigestSpi 275 * implementation for the specified algorithm is not available 276 * from the specified Provider object. 277 * 278 * @exception IllegalArgumentException if the specified provider is null. 279 * 280 * @see Provider 281 * 282 * @since 1.4 283 */ getInstance(String algorithm, Provider provider)284 public static MessageDigest getInstance(String algorithm, 285 Provider provider) 286 throws NoSuchAlgorithmException 287 { 288 if (provider == null) 289 throw new IllegalArgumentException("missing provider"); 290 Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider); 291 if (objs[0] instanceof MessageDigest) { 292 MessageDigest md = (MessageDigest)objs[0]; 293 md.provider = (Provider)objs[1]; 294 return md; 295 } else { 296 MessageDigest delegate = 297 new Delegate((MessageDigestSpi)objs[0], algorithm); 298 delegate.provider = (Provider)objs[1]; 299 return delegate; 300 } 301 } 302 303 /** 304 * Returns the provider of this message digest object. 305 * 306 * @return the provider of this message digest object 307 */ getProvider()308 public final Provider getProvider() { 309 return this.provider; 310 } 311 312 /** 313 * Updates the digest using the specified byte. 314 * 315 * @param input the byte with which to update the digest. 316 */ update(byte input)317 public void update(byte input) { 318 engineUpdate(input); 319 state = IN_PROGRESS; 320 } 321 322 /** 323 * Updates the digest using the specified array of bytes, starting 324 * at the specified offset. 325 * 326 * @param input the array of bytes. 327 * 328 * @param offset the offset to start from in the array of bytes. 329 * 330 * @param len the number of bytes to use, starting at 331 * <code>offset</code>. 332 */ update(byte[] input, int offset, int len)333 public void update(byte[] input, int offset, int len) { 334 if (input == null) { 335 throw new IllegalArgumentException("No input buffer given"); 336 } 337 if (input.length - offset < len) { 338 throw new IllegalArgumentException("Input buffer too short"); 339 } 340 engineUpdate(input, offset, len); 341 state = IN_PROGRESS; 342 } 343 344 /** 345 * Updates the digest using the specified array of bytes. 346 * 347 * @param input the array of bytes. 348 */ update(byte[] input)349 public void update(byte[] input) { 350 engineUpdate(input, 0, input.length); 351 state = IN_PROGRESS; 352 } 353 354 /** 355 * Update the digest using the specified ByteBuffer. The digest is 356 * updated using the <code>input.remaining()</code> bytes starting 357 * at <code>input.position()</code>. 358 * Upon return, the buffer's position will be equal to its limit; 359 * its limit will not have changed. 360 * 361 * @param input the ByteBuffer 362 * @since 1.5 363 */ update(ByteBuffer input)364 public final void update(ByteBuffer input) { 365 if (input == null) { 366 throw new NullPointerException(); 367 } 368 engineUpdate(input); 369 state = IN_PROGRESS; 370 } 371 372 /** 373 * Completes the hash computation by performing final operations 374 * such as padding. The digest is reset after this call is made. 375 * 376 * @return the array of bytes for the resulting hash value. 377 */ digest()378 public byte[] digest() { 379 /* Resetting is the responsibility of implementors. */ 380 byte[] result = engineDigest(); 381 state = INITIAL; 382 return result; 383 } 384 385 /** 386 * Completes the hash computation by performing final operations 387 * such as padding. The digest is reset after this call is made. 388 * 389 * @param buf output buffer for the computed digest 390 * 391 * @param offset offset into the output buffer to begin storing the digest 392 * 393 * @param len number of bytes within buf allotted for the digest 394 * 395 * @return the number of bytes placed into <code>buf</code> 396 * 397 * @exception DigestException if an error occurs. 398 */ digest(byte[] buf, int offset, int len)399 public int digest(byte[] buf, int offset, int len) throws DigestException { 400 if (buf == null) { 401 throw new IllegalArgumentException("No output buffer given"); 402 } 403 if (buf.length - offset < len) { 404 throw new IllegalArgumentException 405 ("Output buffer too small for specified offset and length"); 406 } 407 int numBytes = engineDigest(buf, offset, len); 408 state = INITIAL; 409 return numBytes; 410 } 411 412 /** 413 * Performs a final update on the digest using the specified array 414 * of bytes, then completes the digest computation. That is, this 415 * method first calls {@link #update(byte[]) update(input)}, 416 * passing the <i>input</i> array to the <code>update</code> method, 417 * then calls {@link #digest() digest()}. 418 * 419 * @param input the input to be updated before the digest is 420 * completed. 421 * 422 * @return the array of bytes for the resulting hash value. 423 */ digest(byte[] input)424 public byte[] digest(byte[] input) { 425 update(input); 426 return digest(); 427 } 428 429 /** 430 * Returns a string representation of this message digest object. 431 */ toString()432 public String toString() { 433 StringBuilder builder = new StringBuilder(); 434 builder.append(algorithm); 435 builder.append(" Message Digest from "); 436 builder.append(provider.getName()); 437 builder.append(", "); 438 439 switch (state) { 440 case INITIAL: 441 builder.append("<initialized>"); 442 break; 443 case IN_PROGRESS: 444 builder.append("<in progress>"); 445 break; 446 } 447 448 return builder.toString(); 449 } 450 451 /** 452 * Compares two digests for equality. Does a simple byte compare. 453 * 454 * @param digesta one of the digests to compare. 455 * 456 * @param digestb the other digest to compare. 457 * 458 * @return true if the digests are equal, false otherwise. 459 */ isEqual(byte[] digesta, byte[] digestb)460 public static boolean isEqual(byte[] digesta, byte[] digestb) { 461 if (digesta.length != digestb.length) { 462 return false; 463 } 464 465 int result = 0; 466 // time-constant comparison 467 for (int i = 0; i < digesta.length; i++) { 468 result |= digesta[i] ^ digestb[i]; 469 } 470 return result == 0; 471 } 472 473 /** 474 * Resets the digest for further use. 475 */ reset()476 public void reset() { 477 engineReset(); 478 state = INITIAL; 479 } 480 481 /** 482 * Returns a string that identifies the algorithm, independent of 483 * implementation details. The name should be a standard 484 * Java Security name (such as "SHA", "MD5", and so on). 485 * See the MessageDigest section in the <a href= 486 * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest"> 487 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 488 * for information about standard algorithm names. 489 * 490 * @return the name of the algorithm 491 */ getAlgorithm()492 public final String getAlgorithm() { 493 return this.algorithm; 494 } 495 496 /** 497 * Returns the length of the digest in bytes, or 0 if this operation is 498 * not supported by the provider and the implementation is not cloneable. 499 * 500 * @return the digest length in bytes, or 0 if this operation is not 501 * supported by the provider and the implementation is not cloneable. 502 * 503 * @since 1.2 504 */ getDigestLength()505 public final int getDigestLength() { 506 int digestLen = engineGetDigestLength(); 507 if (digestLen == 0) { 508 try { 509 MessageDigest md = (MessageDigest)clone(); 510 byte[] digest = md.digest(); 511 return digest.length; 512 } catch (CloneNotSupportedException e) { 513 return digestLen; 514 } 515 } 516 return digestLen; 517 } 518 519 /** 520 * Returns a clone if the implementation is cloneable. 521 * 522 * @return a clone if the implementation is cloneable. 523 * 524 * @exception CloneNotSupportedException if this is called on an 525 * implementation that does not support <code>Cloneable</code>. 526 */ clone()527 public Object clone() throws CloneNotSupportedException { 528 if (this instanceof Cloneable) { 529 return super.clone(); 530 } else { 531 throw new CloneNotSupportedException(); 532 } 533 } 534 535 536 537 538 /* 539 * The following class allows providers to extend from MessageDigestSpi 540 * rather than from MessageDigest. It represents a MessageDigest with an 541 * encapsulated, provider-supplied SPI object (of type MessageDigestSpi). 542 * If the provider implementation is an instance of MessageDigestSpi, 543 * the getInstance() methods above return an instance of this class, with 544 * the SPI object encapsulated. 545 * 546 * Note: All SPI methods from the original MessageDigest class have been 547 * moved up the hierarchy into a new class (MessageDigestSpi), which has 548 * been interposed in the hierarchy between the API (MessageDigest) 549 * and its original parent (Object). 550 */ 551 552 static class Delegate extends MessageDigest { 553 554 // The provider implementation (delegate) 555 private MessageDigestSpi digestSpi; 556 557 // constructor Delegate(MessageDigestSpi digestSpi, String algorithm)558 public Delegate(MessageDigestSpi digestSpi, String algorithm) { 559 super(algorithm); 560 this.digestSpi = digestSpi; 561 } 562 563 /** 564 * Returns a clone if the delegate is cloneable. 565 * 566 * @return a clone if the delegate is cloneable. 567 * 568 * @exception CloneNotSupportedException if this is called on a 569 * delegate that does not support <code>Cloneable</code>. 570 */ clone()571 public Object clone() throws CloneNotSupportedException { 572 if (digestSpi instanceof Cloneable) { 573 MessageDigestSpi digestSpiClone = 574 (MessageDigestSpi)digestSpi.clone(); 575 // Because 'algorithm', 'provider', and 'state' are private 576 // members of our supertype, we must perform a cast to 577 // access them. 578 MessageDigest that = 579 new Delegate(digestSpiClone, 580 ((MessageDigest)this).algorithm); 581 that.provider = ((MessageDigest)this).provider; 582 that.state = ((MessageDigest)this).state; 583 return that; 584 } else { 585 throw new CloneNotSupportedException(); 586 } 587 } 588 engineGetDigestLength()589 protected int engineGetDigestLength() { 590 return digestSpi.engineGetDigestLength(); 591 } 592 engineUpdate(byte input)593 protected void engineUpdate(byte input) { 594 digestSpi.engineUpdate(input); 595 } 596 engineUpdate(byte[] input, int offset, int len)597 protected void engineUpdate(byte[] input, int offset, int len) { 598 digestSpi.engineUpdate(input, offset, len); 599 } 600 engineUpdate(ByteBuffer input)601 protected void engineUpdate(ByteBuffer input) { 602 digestSpi.engineUpdate(input); 603 } 604 engineDigest()605 protected byte[] engineDigest() { 606 return digestSpi.engineDigest(); 607 } 608 engineDigest(byte[] buf, int offset, int len)609 protected int engineDigest(byte[] buf, int offset, int len) 610 throws DigestException { 611 return digestSpi.engineDigest(buf, offset, len); 612 } 613 engineReset()614 protected void engineReset() { 615 digestSpi.engineReset(); 616 } 617 } 618 } 619