2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Copyright (C) 2017 Amdocs
8 * =============================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
21 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 * ============LICENSE_END=========================================================
25 package org.openecomp.tlv.sdc.security;
27 import java.math.BigInteger;
28 import java.security.MessageDigest;
29 import java.security.NoSuchAlgorithmException;
30 import java.security.SecureRandom;
31 import java.util.Arrays;
32 import java.util.Random;
35 * A copy from the org.openecomp.sdc:security-utils artifact that works with java 7.
37 public class Passwords {
39 private static final Random RANDOM = new SecureRandom();
40 private static final int SALT = 0;
41 private static final int HASH = 1;
42 private static final String HASH_ALGORITHM = "SHA-256";
45 * static utility class
51 * the method calculates a hash with a generated salt for the given password
54 * @return a "salt:hash" value
56 public static String hashPassword(String password) {
57 byte[] salt = getNextSalt();
58 byte byteData[] = hash(salt, password.getBytes());
59 if (byteData != null) {
60 return toHex(salt) + ":" + toHex(byteData);
67 * the method checks if the given password matches the calculated hash
73 public static boolean isExpectedPassword(String password, String expectedHash) {
74 String[] params = expectedHash.split(":");
75 return isExpectedPassword(password, params[SALT], params[HASH]);
79 * the method checks if the given password matches the calculated hash
84 * the hash generated using the salt
85 * @return true if the password matched the hash
87 public static boolean isExpectedPassword(String password, String salt, String hash) {
88 byte[] saltBytes = fromHex(salt);
89 byte[] hashBytes = fromHex(hash);
91 byte byteData[] = hash(saltBytes, password.getBytes());
92 if (byteData != null) {
93 return Arrays.equals(byteData, hashBytes);
98 public static void main(String[] args) {
99 if (args.length > 1 || args.length > 0) {
100 System.out.println("[" + hashPassword(args[0]) + "]");
102 System.out.println("no passward passed.");
108 * Returns a random salt to be used to hash a password.
110 * @return a 16 bytes random salt
112 private static byte[] getNextSalt() {
113 byte[] salt = new byte[16];
114 RANDOM.nextBytes(salt);
119 * hase's the salt and value using the chosen algorithm
123 * @return an array of bytes resulting from the hash
125 private static byte[] hash(byte[] salt, byte[] password) {
127 byte[] byteData = null;
129 md = MessageDigest.getInstance(HASH_ALGORITHM);
132 byteData = md.digest();
133 } catch (NoSuchAlgorithmException e) {
134 System.out.println("in vlide algorithem name");
140 * Converts a string of hexadecimal characters into a byte array.
144 * @return the hex string decoded into a byte array
146 private static byte[] fromHex(String hex) {
147 byte[] binary = new byte[hex.length() / 2];
148 for (int i = 0; i < binary.length; i++) {
149 binary[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
155 * Converts a byte array into a hexadecimal string.
158 * the byte array to convert
159 * @return a length*2 character string encoding the byte array
161 private static String toHex(byte[] array) {
162 BigInteger bi = new BigInteger(1, array);
163 String hex = bi.toString(16);
164 int paddingLength = (array.length * 2) - hex.length();
165 if (paddingLength > 0)
166 return String.format("%0" + paddingLength + "d", 0) + hex;