2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Copyright (C) 2017 Amdocs
8 * ================================================================================
9 * Modifications Copyright (C) 2019 Ericsson
10 * =============================================================================
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
23 * ============LICENSE_END=========================================================
26 package org.onap.tlv.sdc.security;
28 import java.math.BigInteger;
29 import java.security.MessageDigest;
30 import java.security.NoSuchAlgorithmException;
31 import java.security.SecureRandom;
32 import java.util.Arrays;
33 import java.util.Random;
34 import javax.xml.bind.DatatypeConverter;
35 import com.att.eelf.configuration.EELFLogger;
36 import com.att.eelf.configuration.EELFManager;
39 * A copy from the org.onap.sdc:security-utils artifact that works with java 7.
41 public class Passwords {
43 private static final Random RANDOM = new SecureRandom();
44 private static final int SALT = 0;
45 private static final int HASH = 1;
46 private static final String HASH_ALGORITHM = "SHA-256";
47 private static final EELFLogger log = EELFManager.getInstance().getLogger(Passwords.class);
50 * static utility class
56 * the method calculates a hash with a generated salt for the given password
59 * @return a "salt:hash" value
61 public static String hashPassword(String password) {
62 if (password != null) {
63 byte[] salt = getNextSalt();
64 byte byteData[] = hash(salt, password.getBytes());
65 return DatatypeConverter.printHexBinary(salt) + ":" + DatatypeConverter.printHexBinary(byteData);
72 * the method checks if the given password matches the calculated hash
78 public static boolean isExpectedPassword(String password, String expectedHash) {
79 String[] params = expectedHash.split(":");
80 return isExpectedPassword(password, params[SALT], params[HASH]);
84 * the method checks if the given password matches the calculated hash
89 * the hash generated using the salt
90 * @return true if the password matched the hash
92 public static boolean isExpectedPassword(String password, String salt, String hash) {
93 byte[] saltBytes = DatatypeConverter.parseHexBinary(salt);
94 byte[] hashBytes = DatatypeConverter.parseHexBinary(hash);
95 if (password != null) {
96 byte byteData[] = hash(saltBytes, password.getBytes());
97 return Arrays.equals(byteData, hashBytes);
102 public static void main(String[] args) {
103 if (args.length > 0) {
104 log.info("[" + hashPassword(args[0]) + "]");
106 log.info("no password passed");
112 * Returns a random salt to be used to hash a password.
114 * @return a 16 bytes random salt
116 private static byte[] getNextSalt() {
117 byte[] salt = new byte[16];
118 RANDOM.nextBytes(salt);
123 * hase's the salt and value using the chosen algorithm
127 * @return an array of bytes resulting from the hash
129 private static byte[] hash(byte[] salt, byte[] password) {
131 byte[] byteData = null;
133 md = MessageDigest.getInstance(HASH_ALGORITHM);
136 byteData = md.digest();
137 } catch (NoSuchAlgorithmException e) {
138 log.info("invalid algorithm name", e);
144 * Converts a string of hexadecimal characters into a byte array.
148 * @return the hex string decoded into a byte array
150 /*private static byte[] fromHex(String hex) {
151 byte[] binary = new byte[hex.length() / 2];
152 for (int i = 0; i < binary.length; i++) {
153 binary[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
159 * Converts a byte array into a hexadecimal string.
162 * the byte array to convert
163 * @return a length*2 character string encoding the byte array
165 /* private static String toHex(byte[] array) {
166 BigInteger bi = new BigInteger(1, array);
167 String hex = bi.toString(16);
168 int paddingLength = (array.length * 2) - hex.length();
169 if (paddingLength > 0)
170 return String.format("%0" + paddingLength + "d", 0) + hex;