001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    package org.apache.shiro.authc.credential;
020    
021    import org.apache.shiro.crypto.hash.Hash;
022    import org.apache.shiro.util.ByteSource;
023    
024    /**
025     * A {@code HashingPasswordService} is a {@link PasswordService} that performs password encryption and comparisons
026     * based on cryptographic {@link Hash}es.
027     *
028     * @since 1.2
029     */
030    public interface HashingPasswordService extends PasswordService {
031    
032        /**
033         * Hashes the specified plaintext password using internal hashing configuration settings pertinent to password
034         * hashing.
035         * <p/>
036         * Note
037         * that this method is only likely to be used in more complex environments that wish to format and/or save the
038         * returned {@code Hash} object in a custom manner.  Most applications will find the
039         * {@link #encryptPassword(Object) encryptPassword} method suitable enough for safety
040         * and ease-of-use.
041         * <h3>Usage</h3>
042         * The input argument type can be any 'byte backed' {@code Object} - almost always either a
043         * String or character array representing passwords (character arrays are often a safer way to represent passwords
044         * as they can be cleared/nulled-out after use.  Any argument type supported by
045         * {@link ByteSource.Util#isCompatible(Object)} is valid.
046         * <p/>
047         * Regardless of your choice of using Strings or character arrays to represent submitted passwords, you can wrap
048         * either as a {@code ByteSource} by using {@link ByteSource.Util}, for example, when the passwords are captured as
049         * Strings:
050         * <pre>
051         * ByteSource passwordBytes = ByteSource.Util.bytes(submittedPasswordString);
052         * Hash hashedPassword = hashingPasswordService.hashPassword(passwordBytes);
053         * </pre>
054         * or, identically, when captured as a character array:
055         * <pre>
056         * ByteSource passwordBytes = ByteSource.Util.bytes(submittedPasswordCharacterArray);
057         * Hash hashedPassword = hashingPasswordService.hashPassword(passwordBytes);
058         * </pre>
059         *
060         * @param plaintext the raw password as 'byte-backed' object (String, character array, {@link ByteSource},
061         *                  etc) usually acquired from your application's 'new user' or 'password reset' workflow.
062         * @return the hashed password.
063         * @throws IllegalArgumentException if the argument cannot be easily converted to bytes as defined by
064         *                                  {@link ByteSource.Util#isCompatible(Object)}.
065         * @see ByteSource.Util#isCompatible(Object)
066         * @see #encryptPassword(Object)
067         */
068        Hash hashPassword(Object plaintext) throws IllegalArgumentException;
069    
070        /**
071         * Returns {@code true} if the {@code submittedPlaintext} password matches the existing {@code savedPasswordHash},
072         * {@code false} otherwise.  Note that this method is only likely to be used in more complex environments that
073         * save hashes in a custom manner.  Most applications will find the
074         * {@link #passwordsMatch(Object, String) passwordsMatch(plaintext,string)} method
075         * sufficient if {@link #encryptPassword(Object) encrypting passwords as Strings}.
076         * <h3>Usage</h3>
077         * The {@code submittedPlaintext} argument type can be any 'byte backed' {@code Object} - almost always either a
078         * String or character array representing passwords (character arrays are often a safer way to represent passwords
079         * as they can be cleared/nulled-out after use.  Any argument type supported by
080         * {@link ByteSource.Util#isCompatible(Object)} is valid.
081         *
082         * @param plaintext a raw/plaintext password submitted by an end user/Subject.
083         * @param savedPasswordHash  the previously hashed password known to be associated with an account.
084         *                           This value is expected to have been previously generated from the
085         *                           {@link #hashPassword(Object) hashPassword} method (typically
086         *                           when the account is created or the account's password is reset).
087         * @return {@code true} if the {@code plaintext} password matches the existing {@code savedPasswordHash},
088         *         {@code false} otherwise.
089         */
090        boolean passwordsMatch(Object plaintext, Hash savedPasswordHash);
091    }