Path: blob/master/src/java.base/share/classes/java/security/MessageDigest.java
41152 views
/*1* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.security;2627import java.util.*;28import java.io.ByteArrayOutputStream;29import java.io.PrintStream;30import java.nio.ByteBuffer;3132import sun.security.jca.GetInstance;33import sun.security.util.Debug;34import sun.security.util.MessageDigestSpi2;3536import javax.crypto.SecretKey;3738/**39* This MessageDigest class provides applications the functionality of a40* message digest algorithm, such as SHA-1 or SHA-256.41* Message digests are secure one-way hash functions that take arbitrary-sized42* data and output a fixed-length hash value.43*44* <p>A MessageDigest object starts out initialized. The data is45* processed through it using the {@link #update(byte) update}46* methods. At any point {@link #reset() reset} can be called47* to reset the digest. Once all the data to be updated has been48* updated, one of the {@link #digest() digest} methods should49* be called to complete the hash computation.50*51* <p>The {@code digest} method can be called once for a given number52* of updates. After {@code digest} has been called, the MessageDigest53* 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 cloning57* and catching the CloneNotSupportedException:58*59* <pre>{@code60* MessageDigest md = MessageDigest.getInstance("SHA-256");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 is74* still possible to compute intermediate digests by instantiating75* several instances, if the number of digests is known in advance.76*77* <p>Note that this class is abstract and extends from78* {@code MessageDigestSpi} for historical reasons.79* Application developers should only take notice of the methods defined in80* this {@code MessageDigest} class; all the methods in81* the superclass are intended for cryptographic service providers who wish to82* supply their own implementations of message digest algorithms.83*84* <p> Every implementation of the Java platform is required to support85* the following standard {@code MessageDigest} algorithms:86* <ul>87* <li>{@code SHA-1}</li>88* <li>{@code SHA-256}</li>89* </ul>90* These algorithms are described in the <a href=91* "{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms">92* MessageDigest section</a> of the93* Java Security Standard Algorithm Names Specification.94* Consult the release documentation for your implementation to see if any95* other algorithms are supported.96*97* @author Benjamin Renaud98* @since 1.199*100* @see DigestInputStream101* @see DigestOutputStream102*/103104public abstract class MessageDigest extends MessageDigestSpi {105106private static final Debug pdebug =107Debug.getInstance("provider", "Provider");108private static final boolean skipDebug =109Debug.isOn("engine=") && !Debug.isOn("messagedigest");110111private String algorithm;112113// The state of this digest114private static final int INITIAL = 0;115private static final int IN_PROGRESS = 1;116private int state = INITIAL;117118// The provider119private Provider provider;120121/**122* Creates a message digest with the specified algorithm name.123*124* @param algorithm the standard name of the digest algorithm.125* See the MessageDigest section in the <a href=126* "{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms">127* Java Security Standard Algorithm Names Specification</a>128* for information about standard algorithm names.129*/130protected MessageDigest(String algorithm) {131this.algorithm = algorithm;132}133134// private constructor used only by Delegate class135private MessageDigest(String algorithm, Provider p) {136this.algorithm = algorithm;137this.provider = p;138}139140/**141* Returns a MessageDigest object that implements the specified digest142* algorithm.143*144* <p> This method traverses the list of registered security Providers,145* starting with the most preferred Provider.146* A new MessageDigest object encapsulating the147* MessageDigestSpi implementation from the first148* Provider that supports the specified algorithm is returned.149*150* <p> Note that the list of registered providers may be retrieved via151* the {@link Security#getProviders() Security.getProviders()} method.152*153* @implNote154* The JDK Reference Implementation additionally uses the155* {@code jdk.security.provider.preferred}156* {@link Security#getProperty(String) Security} property to determine157* the preferred provider order for the specified algorithm. This158* may be different than the order of providers returned by159* {@link Security#getProviders() Security.getProviders()}.160*161* @param algorithm the name of the algorithm requested.162* See the MessageDigest section in the <a href=163* "{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms">164* Java Security Standard Algorithm Names Specification</a>165* for information about standard algorithm names.166*167* @return a {@code MessageDigest} object that implements the168* specified algorithm169*170* @throws NoSuchAlgorithmException if no {@code Provider} supports a171* {@code MessageDigestSpi} implementation for the172* specified algorithm173*174* @throws NullPointerException if {@code algorithm} is {@code null}175*176* @see Provider177*/178public static MessageDigest getInstance(String algorithm)179throws NoSuchAlgorithmException180{181Objects.requireNonNull(algorithm, "null algorithm name");182MessageDigest md;183184GetInstance.Instance instance = GetInstance.getInstance("MessageDigest",185MessageDigestSpi.class, algorithm);186if (instance.impl instanceof MessageDigest messageDigest) {187md = messageDigest;188md.provider = instance.provider;189} else {190md = Delegate.of((MessageDigestSpi)instance.impl, algorithm,191instance.provider);192}193194if (!skipDebug && pdebug != null) {195pdebug.println("MessageDigest." + algorithm +196" algorithm from: " + md.provider.getName());197}198199return md;200}201202/**203* Returns a MessageDigest object that implements the specified digest204* algorithm.205*206* <p> A new MessageDigest object encapsulating the207* MessageDigestSpi implementation from the specified provider208* is returned. The specified provider must be registered209* in the security provider list.210*211* <p> Note that the list of registered providers may be retrieved via212* the {@link Security#getProviders() Security.getProviders()} method.213*214* @param algorithm the name of the algorithm requested.215* See the MessageDigest section in the <a href=216* "{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms">217* Java Security Standard Algorithm Names Specification</a>218* for information about standard algorithm names.219*220* @param provider the name of the provider.221*222* @return a {@code MessageDigest} object that implements the223* specified algorithm224*225* @throws IllegalArgumentException if the provider name is {@code null}226* or empty227*228* @throws NoSuchAlgorithmException if a {@code MessageDigestSpi}229* implementation for the specified algorithm is not230* available from the specified provider231*232* @throws NoSuchProviderException if the specified provider is not233* registered in the security provider list234*235* @throws NullPointerException if {@code algorithm} is {@code null}236*237* @see Provider238*/239public static MessageDigest getInstance(String algorithm, String provider)240throws NoSuchAlgorithmException, NoSuchProviderException241{242Objects.requireNonNull(algorithm, "null algorithm name");243if (provider == null || provider.isEmpty())244throw new IllegalArgumentException("missing provider");245246MessageDigest md;247GetInstance.Instance instance = GetInstance.getInstance("MessageDigest",248MessageDigestSpi.class, algorithm, provider);249if (instance.impl instanceof MessageDigest messageDigest) {250md = messageDigest;251md.provider = instance.provider;252} else {253md = Delegate.of((MessageDigestSpi)instance.impl, algorithm,254instance.provider);255}256return md;257}258259/**260* Returns a MessageDigest object that implements the specified digest261* algorithm.262*263* <p> A new MessageDigest object encapsulating the264* MessageDigestSpi implementation from the specified Provider265* object is returned. Note that the specified Provider object266* does not have to be registered in the provider list.267*268* @param algorithm the name of the algorithm requested.269* See the MessageDigest section in the <a href=270* "{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms">271* Java Security Standard Algorithm Names Specification</a>272* for information about standard algorithm names.273*274* @param provider the provider.275*276* @return a {@code MessageDigest} object that implements the277* specified algorithm278*279* @throws IllegalArgumentException if the specified provider is280* {@code null}281*282* @throws NoSuchAlgorithmException if a {@code MessageDigestSpi}283* implementation for the specified algorithm is not available284* from the specified {@code Provider} object285*286* @throws NullPointerException if {@code algorithm} is {@code null}287*288* @see Provider289*290* @since 1.4291*/292public static MessageDigest getInstance(String algorithm,293Provider provider)294throws NoSuchAlgorithmException295{296Objects.requireNonNull(algorithm, "null algorithm name");297if (provider == null)298throw new IllegalArgumentException("missing provider");299Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider);300if (objs[0] instanceof MessageDigest md) {301md.provider = (Provider)objs[1];302return md;303} else {304MessageDigest delegate =305Delegate.of((MessageDigestSpi)objs[0], algorithm,306(Provider)objs[1]);307return delegate;308}309}310311/**312* Returns the provider of this message digest object.313*314* @return the provider of this message digest object315*/316public final Provider getProvider() {317return this.provider;318}319320/**321* Updates the digest using the specified byte.322*323* @param input the byte with which to update the digest.324*/325public void update(byte input) {326engineUpdate(input);327state = IN_PROGRESS;328}329330/**331* Updates the digest using the specified array of bytes, starting332* at the specified offset.333*334* @param input the array of bytes.335*336* @param offset the offset to start from in the array of bytes.337*338* @param len the number of bytes to use, starting at339* {@code offset}.340*/341public void update(byte[] input, int offset, int len) {342if (input == null) {343throw new IllegalArgumentException("No input buffer given");344}345if (input.length - offset < len) {346throw new IllegalArgumentException("Input buffer too short");347}348engineUpdate(input, offset, len);349state = IN_PROGRESS;350}351352/**353* Updates the digest using the specified array of bytes.354*355* @param input the array of bytes.356*/357public void update(byte[] input) {358engineUpdate(input, 0, input.length);359state = IN_PROGRESS;360}361362/**363* Update the digest using the specified ByteBuffer. The digest is364* updated using the {@code input.remaining()} bytes starting365* at {@code input.position()}.366* Upon return, the buffer's position will be equal to its limit;367* its limit will not have changed.368*369* @param input the ByteBuffer370* @since 1.5371*/372public final void update(ByteBuffer input) {373if (input == null) {374throw new NullPointerException();375}376engineUpdate(input);377state = IN_PROGRESS;378}379380/**381* Completes the hash computation by performing final operations382* such as padding. The digest is reset after this call is made.383*384* @return the array of bytes for the resulting hash value.385*/386public byte[] digest() {387/* Resetting is the responsibility of implementors. */388byte[] result = engineDigest();389state = INITIAL;390return result;391}392393/**394* Completes the hash computation by performing final operations395* such as padding. The digest is reset after this call is made.396*397* @param buf output buffer for the computed digest398*399* @param offset offset into the output buffer to begin storing the digest400*401* @param len number of bytes within buf allotted for the digest402*403* @return the number of bytes placed into {@code buf}404*405* @throws DigestException if an error occurs.406*/407public int digest(byte[] buf, int offset, int len) throws DigestException {408if (buf == null) {409throw new IllegalArgumentException("No output buffer given");410}411if (buf.length - offset < len) {412throw new IllegalArgumentException413("Output buffer too small for specified offset and length");414}415int numBytes = engineDigest(buf, offset, len);416state = INITIAL;417return numBytes;418}419420/**421* Performs a final update on the digest using the specified array422* of bytes, then completes the digest computation. That is, this423* method first calls {@link #update(byte[]) update(input)},424* passing the <i>input</i> array to the {@code update} method,425* then calls {@link #digest() digest()}.426*427* @param input the input to be updated before the digest is428* completed.429*430* @return the array of bytes for the resulting hash value.431*/432public byte[] digest(byte[] input) {433update(input);434return digest();435}436437private String getProviderName() {438return (provider == null) ? "(no provider)" : provider.getName();439}440441/**442* Returns a string representation of this message digest object.443*/444public String toString() {445ByteArrayOutputStream baos = new ByteArrayOutputStream();446PrintStream p = new PrintStream(baos);447p.print(algorithm+" Message Digest from "+getProviderName()+", ");448switch (state) {449case INITIAL:450p.print("<initialized>");451break;452case IN_PROGRESS:453p.print("<in progress>");454break;455}456p.println();457return (baos.toString());458}459460/**461* Compares two digests for equality. Two digests are equal if they have462* the same length and all bytes at corresponding positions are equal.463*464* @implNote465* All bytes in {@code digesta} are examined to determine equality.466* The calculation time depends only on the length of {@code digesta}.467* It does not depend on the length of {@code digestb} or the contents468* of {@code digesta} and {@code digestb}.469*470* @param digesta one of the digests to compare.471*472* @param digestb the other digest to compare.473*474* @return true if the digests are equal, false otherwise.475*/476public static boolean isEqual(byte[] digesta, byte[] digestb) {477if (digesta == digestb) return true;478if (digesta == null || digestb == null) {479return false;480}481482int lenA = digesta.length;483int lenB = digestb.length;484485if (lenB == 0) {486return lenA == 0;487}488489int result = 0;490result |= lenA - lenB;491492// time-constant comparison493for (int i = 0; i < lenA; i++) {494// If i >= lenB, indexB is 0; otherwise, i.495int indexB = ((i - lenB) >>> 31) * i;496result |= digesta[i] ^ digestb[indexB];497}498return result == 0;499}500501/**502* Resets the digest for further use.503*/504public void reset() {505engineReset();506state = INITIAL;507}508509/**510* Returns a string that identifies the algorithm, independent of511* implementation details. The name should be a standard512* Java Security name (such as "SHA-256").513* See the MessageDigest section in the <a href=514* "{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms">515* Java Security Standard Algorithm Names Specification</a>516* for information about standard algorithm names.517*518* @return the name of the algorithm519*/520public final String getAlgorithm() {521return this.algorithm;522}523524/**525* Returns the length of the digest in bytes, or 0 if this operation is526* not supported by the provider and the implementation is not cloneable.527*528* @return the digest length in bytes, or 0 if this operation is not529* supported by the provider and the implementation is not cloneable.530*531* @since 1.2532*/533public final int getDigestLength() {534int digestLen = engineGetDigestLength();535if (digestLen == 0) {536try {537MessageDigest md = (MessageDigest)clone();538byte[] digest = md.digest();539return digest.length;540} catch (CloneNotSupportedException e) {541return digestLen;542}543}544return digestLen;545}546547/**548* Returns a clone if the implementation is cloneable.549*550* @return a clone if the implementation is cloneable.551*552* @throws CloneNotSupportedException if this is called on an553* implementation that does not support {@code Cloneable}.554*/555public Object clone() throws CloneNotSupportedException {556if (this instanceof Cloneable) {557return super.clone();558} else {559throw new CloneNotSupportedException();560}561}562563564/*565* The following class allows providers to extend from MessageDigestSpi566* rather than from MessageDigest. It represents a MessageDigest with an567* encapsulated, provider-supplied SPI object (of type MessageDigestSpi).568* If the provider implementation is an instance of MessageDigestSpi,569* the getInstance() methods above return an instance of this class, with570* the SPI object encapsulated.571*572* Note: All SPI methods from the original MessageDigest class have been573* moved up the hierarchy into a new class (MessageDigestSpi), which has574* been interposed in the hierarchy between the API (MessageDigest)575* and its original parent (Object).576*/577578private static class Delegate extends MessageDigest579implements MessageDigestSpi2 {580// use this class for spi objects which implements Cloneable581private static final class CloneableDelegate extends Delegate582implements Cloneable {583584private CloneableDelegate(MessageDigestSpi digestSpi,585String algorithm, Provider p) {586super(digestSpi, algorithm, p);587}588}589590// The provider implementation (delegate)591private final MessageDigestSpi digestSpi;592593// factory method used by MessageDigest class to create Delegate objs594static Delegate of(MessageDigestSpi digestSpi, String algo,595Provider p) {596Objects.requireNonNull(digestSpi);597boolean isCloneable = (digestSpi instanceof Cloneable);598// Spi impls from SunPKCS11 provider implement Cloneable but their599// clone() may throw CloneNotSupportException600if (isCloneable && p.getName().startsWith("SunPKCS11") &&601p.getClass().getModule().getName().equals602("jdk.crypto.cryptoki")) {603try {604digestSpi.clone();605} catch (CloneNotSupportedException cnse) {606isCloneable = false;607}608}609return (isCloneable? new CloneableDelegate(digestSpi, algo, p) :610new Delegate(digestSpi, algo, p));611}612613// private constructor614private Delegate(MessageDigestSpi digestSpi, String algorithm,615Provider p) {616super(algorithm, p);617this.digestSpi = digestSpi;618}619620/**621* Returns a clone if the delegate is cloneable.622*623* @return a clone if the delegate is cloneable.624*625* @throws CloneNotSupportedException if this is called on a626* delegate that does not support {@code Cloneable}.627*/628@Override629public Object clone() throws CloneNotSupportedException {630if (this instanceof Cloneable) {631// Because 'algorithm', 'provider', and 'state' are private632// members of our supertype, we must perform a cast to633// access them.634MessageDigest that = new CloneableDelegate(635(MessageDigestSpi)digestSpi.clone(),636((MessageDigest)this).algorithm,637((MessageDigest)this).provider);638that.state = ((MessageDigest)this).state;639return that;640} else {641throw new CloneNotSupportedException();642}643}644645@Override646protected int engineGetDigestLength() {647return digestSpi.engineGetDigestLength();648}649650@Override651protected void engineUpdate(byte input) {652digestSpi.engineUpdate(input);653}654655@Override656protected void engineUpdate(byte[] input, int offset, int len) {657digestSpi.engineUpdate(input, offset, len);658}659660@Override661protected void engineUpdate(ByteBuffer input) {662digestSpi.engineUpdate(input);663}664665@Override666public void engineUpdate(SecretKey key) throws InvalidKeyException {667if (digestSpi instanceof MessageDigestSpi2) {668((MessageDigestSpi2)digestSpi).engineUpdate(key);669} else {670throw new UnsupportedOperationException671("Digest does not support update of SecretKey object");672}673}674675@Override676protected byte[] engineDigest() {677return digestSpi.engineDigest();678}679680@Override681protected int engineDigest(byte[] buf, int offset, int len)682throws DigestException {683return digestSpi.engineDigest(buf, offset, len);684}685686@Override687protected void engineReset() {688digestSpi.engineReset();689}690}691}692693694