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 020package org.apache.shiro.crypto.hash; 021 022import java.util.Random; 023import java.util.Set; 024 025/** 026 * Service Provider Interface for password hashing algorithms. 027 * 028 * <p>Apache Shiro will load algorithm implementations based on the method {@link #getImplementedAlgorithms()}. 029 * Loaded providers are expected to return a suitable hash implementation.</p> 030 * 031 * <p>Modern kdf-based hash implementations can extend the {@link AbstractCryptHash} class.</p> 032 * 033 * @since 2.0 034 */ 035public interface HashSpi { 036 037 /** 038 * A list of algorithms recognized by this implementation. 039 * 040 * <p>Example values are {@code argon2id} and {@code argon2i} for the Argon2 service provider and 041 * {@code 2y} and {@code 2a} for the BCrypt service provider.</p> 042 * 043 * @return a set of recognized algorithms. 044 */ 045 Set<String> getImplementedAlgorithms(); 046 047 /** 048 * Creates a Hash instance from the given format string recognized by this provider. 049 * 050 * <p>There is no global format which this provider must accept. Each provider can define their own 051 * format, but they are usually based on the {@code crypt(3)} formats used in {@code /etc/shadow} files.</p> 052 * 053 * <p>Implementations should overwrite this javadoc to add examples of the accepted formats.</p> 054 * 055 * @param format the format string to be parsed by this implementation. 056 * @return a class extending Hash. 057 */ 058 Hash fromString(String format); 059 060 /** 061 * A factory class for the hash of the type {@code <T>}. 062 * 063 * <p>Implementations are highly encouraged to use the given random parameter as 064 * source of random bytes (e.g. for seeds).</p> 065 * 066 * @param random a source of {@link Random}, usually {@code SecureRandom}. 067 * @return a factory class for creating instances of {@code <T>}. 068 */ 069 HashFactory newHashFactory(Random random); 070 071 interface HashFactory { 072 073 /** 074 * Generates a hash from the given hash request. 075 * 076 * <p>If the hash requests’ optional parameters are not set, the {@link HashFactory} implementation 077 * should use default parameters where applicable.</p> 078 * <p>If the hash requests’ salt is missing or empty, the implementation should create a salt 079 * with a default size.</p> 080 * 081 * @param hashRequest the request to build a Hash from. 082 * @return a generated Hash according to the specs. 083 * @throws IllegalArgumentException if any of the parameters is outside of valid boundaries (algorithm-specific) 084 * or if the given algorithm is not applicable for this {@link HashFactory}. 085 */ 086 Hash generate(HashRequest hashRequest); 087 } 088}