001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.common.text; 017 018import java.security.NoSuchAlgorithmException; 019import org.modeshape.common.util.Base64; 020import org.modeshape.common.util.CheckArg; 021import org.modeshape.common.util.SecureHash; 022import org.modeshape.common.util.SecureHash.Algorithm; 023 024/** 025 * A text encoder that performs a secure hash of the input text and returns that hash as the encoded text. This encoder can be 026 * configured to use different secure hash algorithms and to return a fixed number of characters from the hash. 027 */ 028public class SecureHashTextEncoder implements TextEncoder { 029 030 private final Algorithm algorithm; 031 private final int maxLength; 032 033 /** 034 * Create an encoder that uses the supplied algorithm and returns only the supplied number of characters in the hash. 035 * 036 * @param algorithm the algorithm that should be used 037 * @throws IllegalArgumentException if the algorithm is null 038 */ 039 public SecureHashTextEncoder( Algorithm algorithm ) { 040 this(algorithm, Integer.MAX_VALUE); 041 } 042 043 /** 044 * Create an encoder that uses the supplied algorithm and returns only the supplied number of characters in the hash. 045 * 046 * @param algorithm the algorithm that should be used 047 * @param maxLength the maximumLength, or a non-positive number (or {@link Integer#MAX_VALUE}) if the full hash should be used 048 * @throws IllegalArgumentException if the algorithm is null 049 */ 050 public SecureHashTextEncoder( Algorithm algorithm, 051 int maxLength ) { 052 CheckArg.isNotNull(algorithm, "algorithm"); 053 this.algorithm = algorithm; 054 this.maxLength = maxLength < 1 ? Integer.MAX_VALUE : maxLength; 055 } 056 057 /** 058 * Get the maximum length of the encoded string, or {@link Integer#MAX_VALUE} if there is no maximum. 059 * 060 * @return the maximum encoded string length; always positive 061 */ 062 public int getMaxLength() { 063 return maxLength; 064 } 065 066 /** 067 * Return the secure hash algorithm used by this encoder. 068 * 069 * @return the algorithm; never null 070 */ 071 public Algorithm getAlgorithm() { 072 return algorithm; 073 } 074 075 /** 076 * {@inheritDoc} 077 * 078 * @see org.modeshape.common.text.TextEncoder#encode(java.lang.String) 079 */ 080 @Override 081 public String encode( String text ) { 082 try { 083 byte[] hash = SecureHash.getHash(algorithm, text.getBytes()); 084 String result = Base64.encodeBytes(hash); 085 return result.length() < maxLength ? result : result.substring(0, maxLength); 086 } catch (NoSuchAlgorithmException e) { 087 return text; 088 } 089 } 090 091}