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 */ 019package org.apache.shiro.crypto.hash; 020 021/** 022 * A {@code HashService} hashes input sources utilizing a particular hashing strategy. 023 * <p/> 024 * A {@code HashService} sits at a higher architectural level than Shiro's simple {@link Hash} classes: it allows 025 * for salting and iteration-related strategies to be configured and internalized in a 026 * single component that can be re-used in multiple places in the application. 027 * <p/> 028 * For example, for the most secure hashes, it is highly recommended to use a randomly generated salt, potentially 029 * paired with an configuration-specific private salt, in addition to using multiple hash iterations. 030 * <p/> 031 * While one can do this easily enough using Shiro's {@link Hash} implementations directly, this direct approach could 032 * quickly lead to copy-and-paste behavior. For example, consider this logic which might need to repeated in an 033 * application: 034 * <pre> 035 * int numHashIterations = ... 036 * ByteSource privateSalt = ... 037 * ByteSource randomSalt = {@link org.apache.shiro.crypto.RandomNumberGenerator randomNumberGenerator}.nextBytes(); 038 * ByteSource combined = combine(privateSalt, randomSalt); 039 * Hash hash = Sha512Hash(source, combined, numHashIterations); 040 * save(hash); 041 * </pre> 042 * In this example, often only the input source will change during runtime, while the hashing strategy (how salts 043 * are generated or acquired, how many hash iterations will be performed, etc.) usually remain consistent. A HashService 044 * internalizes this logic so the above becomes simply this: 045 * <pre> 046 * HashRequest request = new HashRequest.Builder().source(source).build(); 047 * Hash result = hashService.hash(request); 048 * save(result); 049 * </pre> 050 * 051 * @since 1.2 052 */ 053public interface HashService { 054 055 /** 056 * Computes a hash based on the given request. 057 * 058 * <h3>Salt Notice</h3> 059 * <p> 060 * If a salt accompanies the return value 061 * (i.e. <code>returnedHash.{@link org.apache.shiro.crypto.hash.Hash#getSalt() getSalt()} != null</code>), this 062 * same exact salt <b><em>MUST</em></b> be presented back to the {@code HashService} if hash 063 * comparison/verification will be performed at a later time (for example, for password hash or file checksum 064 * comparison). 065 * <p/> 066 * For additional security, the {@code HashService}'s internal implementation may use more complex salting 067 * strategies than what would be achieved by computing a {@code Hash} manually. 068 * <p/> 069 * In summary, if a {@link HashService} returns a salt in a returned Hash, it is expected that the same salt 070 * will be provided to the same {@code HashService} instance. 071 * 072 * @param request the request to process 073 * @return the hashed data 074 * @see Hash#getSalt() 075 */ 076 Hash computeHash(HashRequest request); 077 078 /** 079 * @return Default algorithm name for this hash service 080 * @since 2.0 081 */ 082 String getDefaultAlgorithmName(); 083}