Source code
Description: source: package: org.apache.commons.codec.digest, class: Crypt

    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      https://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.codec.digest;
    018
    019import java.nio.charset.StandardCharsets;
    020import java.security.NoSuchAlgorithmException;
    021import java.security.SecureRandom;
    022
    023/**
    024 * GNU libc crypt(3) compatible hash method.
    025 * <p>
    026 * See {@link #crypt(String, String)} for further details.
    027 * </p>
    028 * <p>
    029 * This class is immutable and thread-safe.
    030 * </p>
    031 *
    032 * @since 1.7
    033 */
    034public class Crypt {
    035
    036    /**
    037     * Encrypts a password in a crypt(3) compatible way.
    038     * <p>
    039     * A random salt and the default algorithm (currently SHA-512) are used. See {@link #crypt(String, String)} for details.
    040     * </p>
    041     * <p>
    042     * A salt is generated for you using {@link SecureRandom}.
    043     * </p>
    044     *
    045     * @param keyBytes The plaintext password.
    046     * @return The hash value.
    047     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught.
    048     */
    049    public static String crypt(final byte[] keyBytes) {
    050        return crypt(keyBytes, null);
    051    }
    052
    053    /**
    054     * Encrypts a password in a crypt(3) compatible way.
    055     * <p>
    056     * If no salt is provided, a random salt and the default algorithm (currently SHA-512) will be used. See {@link #crypt(String, String)} for details.
    057     * </p>
    058     *
    059     * @param keyBytes The plaintext password.
    060     * @param salt     The salt, which is used to select the algorithm, see {@link #crypt(String, String)} The salt may be null, in which case the method
    061     *                 delegates to {@link Sha2Crypt#sha512Crypt(byte[])}.
    062     * @return hash value.
    063     * @throws IllegalArgumentException Thrown if the salt does not match the allowed pattern.
    064     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught.
    065     */
    066    public static String crypt(final byte[] keyBytes, final String salt) {
    067        if (salt == null) {
    068            return Sha2Crypt.sha512Crypt(keyBytes);
    069        }
    070        if (salt.startsWith(Sha2Crypt.SHA512_PREFIX)) {
    071            return Sha2Crypt.sha512Crypt(keyBytes, salt);
    072        }
    073        if (salt.startsWith(Sha2Crypt.SHA256_PREFIX)) {
    074            return Sha2Crypt.sha256Crypt(keyBytes, salt);
    075        }
    076        if (salt.startsWith(Md5Crypt.MD5_PREFIX)) {
    077            return Md5Crypt.md5Crypt(keyBytes, salt);
    078        }
    079        return UnixCrypt.crypt(keyBytes, salt);
    080    }
    081
    082    /**
    083     * Calculates the digest using the strongest crypt(3) algorithm.
    084     * <p>
    085     * A random salt and the default algorithm (currently SHA-512) are used.
    086     * </p>
    087     * <p>
    088     * A salt is generated for you using {@link SecureRandom}.
    089     * </p>
    090     *
    091     * @see #crypt(String, String)
    092     * @param key The plaintext password.
    093     * @return The hash value.
    094     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught.
    095     */
    096    public static String crypt(final String key) {
    097        return crypt(key, null);
    098    }
    099
    100    /**
    101     * Encrypts a password in a crypt(3) compatible way.
    102     * <p>
    103     * The exact algorithm depends on the format of the salt string:
    104     * </p>
    105     * <ul>
    106     * <li>SHA-512 salts start with {@code $6$} and are up to 16 chars long.</li>
    107     * <li>SHA-256 salts start with {@code $5$} and are up to 16 chars long</li>
    108     * <li>MD5 salts start with {@code $1$} and are up to 8 chars long</li>
    109     * <li>DES, the traditional UnixCrypt algorithm is used with only 2 chars</li>
    110     * <li>Only the first 8 chars of the passwords are used in the DES algorithm!</li>
    111     * </ul>
    112     * <p>
    113     * The magic strings {@code "$apr1$"} and {@code "$2a$"} are not recognized by this method as its output should be identical with that of the libc
    114     * implementation.
    115     * </p>
    116     * <p>
    117     * The rest of the salt string is drawn from the set {@code [a-zA-Z0-9./]} and is cut at the maximum length or if a {@code "$"} sign is encountered. It is
    118     * therefore valid to enter a complete hash value as salt to for example verify a password with:
    119     * </p>
    120     *
    121     * <pre>
    122     * storedPwd.equals(crypt(enteredPwd, storedPwd))
    123     * </pre>
    124     * <p>
    125     * The resulting string starts with the marker string ({@code $n$}), where n is the same as the input salt. The salt is then appended, followed by a
    126     * {@code "$"} sign. This is followed by the actual hash value. For DES the string only contains the salt and actual hash. The total length is dependent on
    127     * the algorithm used:
    128     * </p>
    129     * <ul>
    130     * <li>SHA-512: 106 chars</li>
    131     * <li>SHA-256: 63 chars</li>
    132     * <li>MD5: 34 chars</li>
    133     * <li>DES: 13 chars</li>
    134     * </ul>
    135     * <p>
    136     * Example:
    137     * </p>
    138     *
    139     * <pre>
    140     *      crypt("secret", "$1$xxxx") =&gt; "$1$xxxx$aMkevjfEIpa35Bh3G4bAc."
    141     *      crypt("secret", "xx") =&gt; "xxWAum7tHdIUw"
    142     * </pre>
    143     * <p>
    144     * This method comes in a variation that accepts a byte[] array to support input strings that are not encoded in UTF-8 but for example in ISO-8859-1 where
    145     * equal characters result in different byte values.
    146     * </p>
    147     *
    148     * @see "The man page of the libc crypt (3) function."
    149     * @param key  The plaintext password as entered by the used.
    150     * @param salt The real salt value without prefix or "rounds=". The salt may be null, in which case a salt is generated for you using {@link SecureRandom}.
    151     * @return The hash value, that is, the encrypted password including the salt string.
    152     * @throws IllegalArgumentException Thrown if the salt does not match the allowed pattern.
    153     * @throws IllegalArgumentException Thrown if a {@link NoSuchAlgorithmException} is caught.
    154     */
    155    public static String crypt(final String key, final String salt) {
    156        return crypt(key.getBytes(StandardCharsets.UTF_8), salt);
    157    }
    158
    159    /**
    160     * TODO Make private in 2.0.
    161     *
    162     * @deprecated TODO Make private in 2.0.
    163     */
    164    @Deprecated
    165    public Crypt() {
    166        // empty
    167    }
    168}