39d809352f17d39253dce85a71e1e1d8609b283b
[appc.git] / appc-asdc-listener / appc-asdc-listener-bundle / src / main / java / org / openecomp / tlv / sdc / security / Passwords.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : APP-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                                              reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.openecomp.tlv.sdc.security;
23
24 import java.math.BigInteger;
25 import java.security.MessageDigest;
26 import java.security.NoSuchAlgorithmException;
27 import java.security.SecureRandom;
28 import java.util.Arrays;
29 import java.util.Random;
30
31 /**
32  * A copy from the org.openecomp.sdc:security-utils artifact that works with java 7.
33  */
34 public class Passwords {
35
36     private static final Random RANDOM = new SecureRandom();
37     private static final int SALT = 0;
38     private static final int HASH = 1;
39     private static final String HASH_ALGORITHM = "SHA-256";
40
41     /**
42      * static utility class
43      */
44     private Passwords() {
45     }
46
47     /**
48      * the method calculates a hash with a generated salt for the given password
49      * 
50      * @param password
51      * @return a "salt:hash" value
52      */
53     public static String hashPassword(String password) {
54         byte[] salt = getNextSalt();
55         byte byteData[] = hash(salt, password.getBytes());
56         if (byteData != null) {
57             return toHex(salt) + ":" + toHex(byteData);
58         }
59         return null;
60
61     }
62
63     /**
64      * the method checks if the given password matches the calculated hash
65      * 
66      * @param password
67      * @param expectedHash
68      * @return
69      */
70     public static boolean isExpectedPassword(String password, String expectedHash) {
71         String[] params = expectedHash.split(":");
72         return isExpectedPassword(password, params[SALT], params[HASH]);
73     }
74
75     /**
76      * the method checks if the given password matches the calculated hash
77      * 
78      * @param password
79      * @param salt
80      * @param hash
81      *            the hash generated using the salt
82      * @return true if the password matched the hash
83      */
84     public static boolean isExpectedPassword(String password, String salt, String hash) {
85         byte[] saltBytes = fromHex(salt);
86         byte[] hashBytes = fromHex(hash);
87
88         byte byteData[] = hash(saltBytes, password.getBytes());
89         if (byteData != null) {
90             return Arrays.equals(byteData, hashBytes);
91         }
92         return false;
93     }
94
95     public static void main(String[] args) {
96         if (args.length > 1 || args.length > 0) {
97             System.out.println("[" + hashPassword(args[0]) + "]");
98         } else {
99             System.out.println("no passward passed.");
100         }
101
102     }
103
104     /**
105      * Returns a random salt to be used to hash a password.
106      * 
107      * @return a 16 bytes random salt
108      */
109     private static byte[] getNextSalt() {
110         byte[] salt = new byte[16];
111         RANDOM.nextBytes(salt);
112         return salt;
113     }
114
115     /**
116      * hase's the salt and value using the chosen algorithm
117      * 
118      * @param salt
119      * @param password
120      * @return an array of bytes resulting from the hash
121      */
122     private static byte[] hash(byte[] salt, byte[] password) {
123         MessageDigest md;
124         byte[] byteData = null;
125         try {
126             md = MessageDigest.getInstance(HASH_ALGORITHM);
127             md.update(salt);
128             md.update(password);
129             byteData = md.digest();
130         } catch (NoSuchAlgorithmException e) {
131             System.out.println("in vlide algorithem name");
132         }
133         return byteData;
134     }
135
136     /**
137      * Converts a string of hexadecimal characters into a byte array.
138      *
139      * @param hex
140      *            the hex string
141      * @return the hex string decoded into a byte array
142      */
143     private static byte[] fromHex(String hex) {
144         byte[] binary = new byte[hex.length() / 2];
145         for (int i = 0; i < binary.length; i++) {
146             binary[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
147         }
148         return binary;
149     }
150
151     /**
152      * Converts a byte array into a hexadecimal string.
153      *
154      * @param array
155      *            the byte array to convert
156      * @return a length*2 character string encoding the byte array
157      */
158     private static String toHex(byte[] array) {
159         BigInteger bi = new BigInteger(1, array);
160         String hex = bi.toString(16);
161         int paddingLength = (array.length * 2) - hex.length();
162         if (paddingLength > 0)
163             return String.format("%0" + paddingLength + "d", 0) + hex;
164         else
165             return hex;
166     }
167 }