标签:
1 /* 2 * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. 3 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 * 18 * 19 * 20 * 21 * 22 * 23 * 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> Every implementation of the Java platform is required to support 85 * the following standard <code>MessageDigest</code> algorithms: 86 * <ul> 87 * <li><tt>MD5</tt></li> 88 * <li><tt>SHA-1</tt></li> 89 * <li><tt>SHA-256</tt></li> 90 * </ul> 91 * These algorithms are described in the <a href= 92 * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest"> 93 * MessageDigest section</a> of the 94 * Java Cryptography Architecture Standard Algorithm Name Documentation. 95 * Consult the release documentation for your implementation to see if any 96 * other algorithms are supported. 97 * 98 * @author Benjamin Renaud 99 * 100 * @see DigestInputStream 101 * @see DigestOutputStream 102 */ 103 104 public abstract class MessageDigest extends MessageDigestSpi { 105 106 private String algorithm; 107 108 // The state of this digest 109 private static final int INITIAL = 0; 110 private static final int IN_PROGRESS = 1; 111 private int state = INITIAL; 112 113 // The provider 114 private Provider provider; 115 116 /** 117 * Creates a message digest with the specified algorithm name. 118 * 119 * @param algorithm the standard name of the digest algorithm. 120 * See the MessageDigest section in the <a href= 121 * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest"> 122 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 123 * for information about standard algorithm names. 124 */ 125 protected MessageDigest(String algorithm) { 126 this.algorithm = algorithm; 127 } 128 129 /** 130 * Returns a MessageDigest object that implements the specified digest 131 * algorithm. 132 * 133 * <p> This method traverses the list of registered security Providers, 134 * starting with the most preferred Provider. 135 * A new MessageDigest object encapsulating the 136 * MessageDigestSpi implementation from the first 137 * Provider that supports the specified algorithm is returned. 138 * 139 * <p> Note that the list of registered providers may be retrieved via 140 * the {@link Security#getProviders() Security.getProviders()} method. 141 * 142 * @param algorithm the name of the algorithm requested. 143 * See the MessageDigest section in the <a href= 144 * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest"> 145 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 146 * for information about standard algorithm names. 147 * 148 * @return a Message Digest object that implements the specified algorithm. 149 * 150 * @exception NoSuchAlgorithmException if no Provider supports a 151 * MessageDigestSpi implementation for the 152 * specified algorithm. 153 * 154 * @see Provider 155 */ 156 public static MessageDigest getInstance(String algorithm) 157 throws NoSuchAlgorithmException { 158 try { 159 Object[] objs = Security.getImpl(algorithm, "MessageDigest", 160 (String)null); 161 if (objs[0] instanceof MessageDigest) { 162 MessageDigest md = (MessageDigest)objs[0]; 163 md.provider = (Provider)objs[1]; 164 return md; 165 } else { 166 MessageDigest delegate = 167 new Delegate((MessageDigestSpi)objs[0], algorithm); 168 delegate.provider = (Provider)objs[1]; 169 return delegate; 170 } 171 } catch(NoSuchProviderException e) { 172 throw new NoSuchAlgorithmException(algorithm + " not found"); 173 } 174 } 175 176 /** 177 * Returns a MessageDigest object that implements the specified digest 178 * algorithm. 179 * 180 * <p> A new MessageDigest object encapsulating the 181 * MessageDigestSpi implementation from the specified provider 182 * is returned. The specified provider must be registered 183 * in the security provider list. 184 * 185 * <p> Note that the list of registered providers may be retrieved via 186 * the {@link Security#getProviders() Security.getProviders()} method. 187 * 188 * @param algorithm the name of the algorithm requested. 189 * See the MessageDigest section in the <a href= 190 * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest"> 191 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 192 * for information about standard algorithm names. 193 * 194 * @param provider the name of the provider. 195 * 196 * @return a MessageDigest object that implements the specified algorithm. 197 * 198 * @exception NoSuchAlgorithmException if a MessageDigestSpi 199 * implementation for the specified algorithm is not 200 * available from the specified provider. 201 * 202 * @exception NoSuchProviderException if the specified provider is not 203 * registered in the security provider list. 204 * 205 * @exception IllegalArgumentException if the provider name is null 206 * or empty. 207 * 208 * @see Provider 209 */ 210 public static MessageDigest getInstance(String algorithm, String provider) 211 throws NoSuchAlgorithmException, NoSuchProviderException 212 { 213 if (provider == null || provider.length() == 0) 214 throw new IllegalArgumentException("missing provider"); 215 Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider); 216 if (objs[0] instanceof MessageDigest) { 217 MessageDigest md = (MessageDigest)objs[0]; 218 md.provider = (Provider)objs[1]; 219 return md; 220 } else { 221 MessageDigest delegate = 222 new Delegate((MessageDigestSpi)objs[0], algorithm); 223 delegate.provider = (Provider)objs[1]; 224 return delegate; 225 } 226 } 227 228 /** 229 * Returns a MessageDigest object that implements the specified digest 230 * algorithm. 231 * 232 * <p> A new MessageDigest object encapsulating the 233 * MessageDigestSpi implementation from the specified Provider 234 * object is returned. Note that the specified Provider object 235 * does not have to be registered in the provider list. 236 * 237 * @param algorithm the name of the algorithm requested. 238 * See the MessageDigest section in the <a href= 239 * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest"> 240 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 241 * for information about standard algorithm names. 242 * 243 * @param provider the provider. 244 * 245 * @return a MessageDigest object that implements the specified algorithm. 246 * 247 * @exception NoSuchAlgorithmException if a MessageDigestSpi 248 * implementation for the specified algorithm is not available 249 * from the specified Provider object. 250 * 251 * @exception IllegalArgumentException if the specified provider is null. 252 * 253 * @see Provider 254 * 255 * @since 1.4 256 */ 257 public static MessageDigest getInstance(String algorithm, 258 Provider provider) 259 throws NoSuchAlgorithmException 260 { 261 if (provider == null) 262 throw new IllegalArgumentException("missing provider"); 263 Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider); 264 if (objs[0] instanceof MessageDigest) { 265 MessageDigest md = (MessageDigest)objs[0]; 266 md.provider = (Provider)objs[1]; 267 return md; 268 } else { 269 MessageDigest delegate = 270 new Delegate((MessageDigestSpi)objs[0], algorithm); 271 delegate.provider = (Provider)objs[1]; 272 return delegate; 273 } 274 } 275 276 /** 277 * Returns the provider of this message digest object. 278 * 279 * @return the provider of this message digest object 280 */ 281 public final Provider getProvider() { 282 return this.provider; 283 } 284 285 /** 286 * Updates the digest using the specified byte. 287 * 288 * @param input the byte with which to update the digest. 289 */ 290 public void update(byte input) { 291 engineUpdate(input); 292 state = IN_PROGRESS; 293 } 294 295 /** 296 * Updates the digest using the specified array of bytes, starting 297 * at the specified offset. 298 * 299 * @param input the array of bytes. 300 * 301 * @param offset the offset to start from in the array of bytes. 302 * 303 * @param len the number of bytes to use, starting at 304 * <code>offset</code>. 305 */ 306 public void update(byte[] input, int offset, int len) { 307 if (input == null) { 308 throw new IllegalArgumentException("No input buffer given"); 309 } 310 if (input.length - offset < len) { 311 throw new IllegalArgumentException("Input buffer too short"); 312 } 313 engineUpdate(input, offset, len); 314 state = IN_PROGRESS; 315 } 316 317 /** 318 * Updates the digest using the specified array of bytes. 319 * 320 * @param input the array of bytes. 321 */ 322 public void update(byte[] input) { 323 engineUpdate(input, 0, input.length); 324 state = IN_PROGRESS; 325 } 326 327 /** 328 * Update the digest using the specified ByteBuffer. The digest is 329 * updated using the <code>input.remaining()</code> bytes starting 330 * at <code>input.position()</code>. 331 * Upon return, the buffer‘s position will be equal to its limit; 332 * its limit will not have changed. 333 * 334 * @param input the ByteBuffer 335 * @since 1.5 336 */ 337 public final void update(ByteBuffer input) { 338 if (input == null) { 339 throw new NullPointerException(); 340 } 341 engineUpdate(input); 342 state = IN_PROGRESS; 343 } 344 345 /** 346 * Completes the hash computation by performing final operations 347 * such as padding. The digest is reset after this call is made. 348 * 349 * @return the array of bytes for the resulting hash value. 350 */ 351 public byte[] digest() { 352 /* Resetting is the responsibility of implementors. */ 353 byte[] result = engineDigest(); 354 state = INITIAL; 355 return result; 356 } 357 358 /** 359 * Completes the hash computation by performing final operations 360 * such as padding. The digest is reset after this call is made. 361 * 362 * @param buf output buffer for the computed digest 363 * 364 * @param offset offset into the output buffer to begin storing the digest 365 * 366 * @param len number of bytes within buf allotted for the digest 367 * 368 * @return the number of bytes placed into <code>buf</code> 369 * 370 * @exception DigestException if an error occurs. 371 */ 372 public int digest(byte[] buf, int offset, int len) throws DigestException { 373 if (buf == null) { 374 throw new IllegalArgumentException("No output buffer given"); 375 } 376 if (buf.length - offset < len) { 377 throw new IllegalArgumentException 378 ("Output buffer too small for specified offset and length"); 379 } 380 int numBytes = engineDigest(buf, offset, len); 381 state = INITIAL; 382 return numBytes; 383 } 384 385 /** 386 * Performs a final update on the digest using the specified array 387 * of bytes, then completes the digest computation. That is, this 388 * method first calls {@link #update(byte[]) update(input)}, 389 * passing the <i>input</i> array to the <code>update</code> method, 390 * then calls {@link #digest() digest()}. 391 * 392 * @param input the input to be updated before the digest is 393 * completed. 394 * 395 * @return the array of bytes for the resulting hash value. 396 */ 397 public byte[] digest(byte[] input) { 398 update(input); 399 return digest(); 400 } 401 402 /** 403 * Returns a string representation of this message digest object. 404 */ 405 public String toString() { 406 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 407 PrintStream p = new PrintStream(baos); 408 p.print(algorithm+" Message Digest from "+provider.getName()+", "); 409 switch (state) { 410 case INITIAL: 411 p.print("<initialized>"); 412 break; 413 case IN_PROGRESS: 414 p.print("<in progress>"); 415 break; 416 } 417 p.println(); 418 return (baos.toString()); 419 } 420 421 /** 422 * Compares two digests for equality. Does a simple byte compare. 423 * 424 * @param digesta one of the digests to compare. 425 * 426 * @param digestb the other digest to compare. 427 * 428 * @return true if the digests are equal, false otherwise. 429 */ 430 public static boolean isEqual(byte[] digesta, byte[] digestb) { 431 if (digesta.length != digestb.length) { 432 return false; 433 } 434 435 int result = 0; 436 // time-constant comparison 437 for (int i = 0; i < digesta.length; i++) { 438 result |= digesta[i] ^ digestb[i]; 439 } 440 return result == 0; 441 } 442 443 /** 444 * Resets the digest for further use. 445 */ 446 public void reset() { 447 engineReset(); 448 state = INITIAL; 449 } 450 451 /** 452 * Returns a string that identifies the algorithm, independent of 453 * implementation details. The name should be a standard 454 * Java Security name (such as "SHA", "MD5", and so on). 455 * See the MessageDigest section in the <a href= 456 * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest"> 457 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 458 * for information about standard algorithm names. 459 * 460 * @return the name of the algorithm 461 */ 462 public final String getAlgorithm() { 463 return this.algorithm; 464 } 465 466 /** 467 * Returns the length of the digest in bytes, or 0 if this operation is 468 * not supported by the provider and the implementation is not cloneable. 469 * 470 * @return the digest length in bytes, or 0 if this operation is not 471 * supported by the provider and the implementation is not cloneable. 472 * 473 * @since 1.2 474 */ 475 public final int getDigestLength() { 476 int digestLen = engineGetDigestLength(); 477 if (digestLen == 0) { 478 try { 479 MessageDigest md = (MessageDigest)clone(); 480 byte[] digest = md.digest(); 481 return digest.length; 482 } catch (CloneNotSupportedException e) { 483 return digestLen; 484 } 485 } 486 return digestLen; 487 } 488 489 /** 490 * Returns a clone if the implementation is cloneable. 491 * 492 * @return a clone if the implementation is cloneable. 493 * 494 * @exception CloneNotSupportedException if this is called on an 495 * implementation that does not support <code>Cloneable</code>. 496 */ 497 public Object clone() throws CloneNotSupportedException { 498 if (this instanceof Cloneable) { 499 return super.clone(); 500 } else { 501 throw new CloneNotSupportedException(); 502 } 503 } 504 505 506 507 508 /* 509 * The following class allows providers to extend from MessageDigestSpi 510 * rather than from MessageDigest. It represents a MessageDigest with an 511 * encapsulated, provider-supplied SPI object (of type MessageDigestSpi). 512 * If the provider implementation is an instance of MessageDigestSpi, 513 * the getInstance() methods above return an instance of this class, with 514 * the SPI object encapsulated. 515 * 516 * Note: All SPI methods from the original MessageDigest class have been 517 * moved up the hierarchy into a new class (MessageDigestSpi), which has 518 * been interposed in the hierarchy between the API (MessageDigest) 519 * and its original parent (Object). 520 */ 521 522 static class Delegate extends MessageDigest { 523 524 // The provider implementation (delegate) 525 private MessageDigestSpi digestSpi; 526 527 // constructor 528 public Delegate(MessageDigestSpi digestSpi, String algorithm) { 529 super(algorithm); 530 this.digestSpi = digestSpi; 531 } 532 533 /** 534 * Returns a clone if the delegate is cloneable. 535 * 536 * @return a clone if the delegate is cloneable. 537 * 538 * @exception CloneNotSupportedException if this is called on a 539 * delegate that does not support <code>Cloneable</code>. 540 */ 541 public Object clone() throws CloneNotSupportedException { 542 if (digestSpi instanceof Cloneable) { 543 MessageDigestSpi digestSpiClone = 544 (MessageDigestSpi)digestSpi.clone(); 545 // Because ‘algorithm‘, ‘provider‘, and ‘state‘ are private 546 // members of our supertype, we must perform a cast to 547 // access them. 548 MessageDigest that = 549 new Delegate(digestSpiClone, 550 ((MessageDigest)this).algorithm); 551 that.provider = ((MessageDigest)this).provider; 552 that.state = ((MessageDigest)this).state; 553 return that; 554 } else { 555 throw new CloneNotSupportedException(); 556 } 557 } 558 559 protected int engineGetDigestLength() { 560 return digestSpi.engineGetDigestLength(); 561 } 562 563 protected void engineUpdate(byte input) { 564 digestSpi.engineUpdate(input); 565 } 566 567 protected void engineUpdate(byte[] input, int offset, int len) { 568 digestSpi.engineUpdate(input, offset, len); 569 } 570 571 protected void engineUpdate(ByteBuffer input) { 572 digestSpi.engineUpdate(input); 573 } 574 575 protected byte[] engineDigest() { 576 return digestSpi.engineDigest(); 577 } 578 579 protected int engineDigest(byte[] buf, int offset, int len) 580 throws DigestException { 581 return digestSpi.engineDigest(buf, offset, len); 582 } 583 584 protected void engineReset() { 585 digestSpi.engineReset(); 586 } 587 } 588 }
标签:
原文地址:http://www.cnblogs.com/LideAiYaner-1wn/p/5781099.html