Update DCAE Startup Info
[aaf/authz.git] / cadi / core / src / main / java / org / onap / aaf / cadi / Hash.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  * ===========================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END====================================================
19  *
20  */
21
22 package org.onap.aaf.cadi;
23
24 import java.nio.ByteBuffer;
25 import java.security.MessageDigest;
26 import java.security.NoSuchAlgorithmException;
27
28 public class Hash {
29     private static char hexDigit[] = "0123456789abcdef".toCharArray();
30
31 /////////////////////////////////
32 // MD5
33 /////////////////////////////////
34     /**
35      * Encrypt MD5 from Byte Array to Byte Array
36      * @param input
37      * @return
38      * @throws NoSuchAlgorithmException
39      */
40     public static byte[] hashMD5 (byte[] input) throws NoSuchAlgorithmException {
41         // Note: Protect against Multi-thread issues with new MessageDigest
42         MessageDigest md = MessageDigest.getInstance("MD5");
43         md.update(input);
44         return md.digest();
45     }
46
47     /**
48      * Encrypt MD5 from Byte Array to Byte Array
49      * @param input
50      * @return
51      * @throws NoSuchAlgorithmException
52      */
53     public static byte[] hashMD5 (byte[] input, int offset, int length) throws NoSuchAlgorithmException {
54         // Note: Protect against Multi-thread issues with new MessageDigest
55         MessageDigest md = MessageDigest.getInstance("MD5");
56         md.update(input,offset,length);
57         return md.digest();
58     }
59
60
61
62     /**
63      * Convenience Function: Encrypt MD5 from String to String Hex representation
64      *
65      * @param input
66      * @return
67      * @throws NoSuchAlgorithmException
68      */
69     public static String hashMD5asStringHex(String input) throws NoSuchAlgorithmException {
70         byte[] output = hashMD5(input.getBytes());
71         StringBuilder sb = new StringBuilder("0x");
72          for (byte b : output) {
73             sb.append(hexDigit[(b >> 4) & 0x0f]);
74             sb.append(hexDigit[b & 0x0f]);
75          }
76          return sb.toString();
77     }
78
79 /////////////////////////////////
80 // SHA256
81 /////////////////////////////////
82     /**
83      * SHA256 Hashing
84      */
85     public static byte[] hashSHA256(byte[] input) throws NoSuchAlgorithmException {
86         // Note: Protect against Multi-thread issues with new MessageDigest
87         MessageDigest md = MessageDigest.getInstance("SHA-256");
88         md.update(input);
89         return md.digest();
90     }
91
92     /**
93      * SHA256 Hashing
94      */
95     public static byte[] hashSHA256(byte[] input, int offset, int length) throws NoSuchAlgorithmException {
96         // Note: Protect against Multi-thread issues with new MessageDigest
97         MessageDigest md = MessageDigest.getInstance("SHA-256");
98         md.update(input,offset,length);
99         return md.digest();
100     }
101
102     /**
103      * Convenience Function: Hash from String to String Hex representation
104      *
105      * @param input
106      * @return
107      * @throws NoSuchAlgorithmException
108      */
109     public static String hashSHA256asStringHex(String input) throws NoSuchAlgorithmException {
110         return toHex(hashSHA256(input.getBytes()));
111     }
112
113     /**
114      * Convenience Function: Hash from String to String Hex representation
115      *
116      * @param input
117      * @return
118      * @throws NoSuchAlgorithmException
119      */
120     public static String hashSHA256asStringHex(String input, int salt) throws NoSuchAlgorithmException {
121         byte[] in = input.getBytes();
122         ByteBuffer bb = ByteBuffer.allocate(Integer.SIZE + in.length);
123         bb.putInt(salt);
124         bb.put(input.getBytes());
125         return toHex(Hash.hashSHA256(bb.array()));
126     }
127
128     /**
129      * Compare two byte arrays for equivalency
130      * @param ba1
131      * @param ba2
132      * @return
133      */
134     public static boolean isEqual(byte ba1[], byte ba2[]) {
135         if (ba1.length!=ba2.length)return false;
136         for (int i = 0;i<ba1.length; ++i) {
137             if (ba1[i]!=ba2[i])return false;
138         }
139         return true;
140     }
141
142     public static int compareTo(byte[] a, byte[] b) {
143         int end = Math.min(a.length, b.length);
144         int compare = 0;
145         for (int i=0;compare == 0 && i<end;++i) {
146             compare = a[i]-b[i];
147         }
148         if (compare==0)compare=a.length-b.length;
149         return compare;
150     }
151
152     public static String toHexNo0x(byte[] ba) {
153         StringBuilder sb = new StringBuilder();
154          for (byte b : ba) {
155             sb.append(hexDigit[(b >> 4) & 0x0f]);
156             sb.append(hexDigit[b & 0x0f]);
157          }
158          return sb.toString();
159     }
160
161     public static String toHex(byte[] ba) {
162         StringBuilder sb = new StringBuilder("0x");
163          for (byte b : ba) {
164             sb.append(hexDigit[(b >> 4) & 0x0f]);
165             sb.append(hexDigit[b & 0x0f]);
166          }
167          return sb.toString();
168     }
169
170     public static String toHex(byte[] ba, int start, int length) {
171         StringBuilder sb = new StringBuilder("0x");
172          for (int i=start;i<length;++i) {
173             sb.append(hexDigit[(ba[i] >> 4) & 0x0f]);
174             sb.append(hexDigit[ba[i] & 0x0f]);
175          }
176          return sb.toString();
177     }
178
179
180     public static byte[] fromHex(String s)  throws CadiException{
181         if (!s.startsWith("0x")) {
182             throw new CadiException("HexString must start with \"0x\"");
183         }
184         boolean high = true;
185         int c;
186         byte b;
187         byte[] ba = new byte[(s.length()-2)/2];
188         int idx;
189         for (int i=2;i<s.length();++i) {
190             c = s.charAt(i);
191             if (c>=0x30 && c<=0x39) {
192                 b=(byte)(c-0x30);
193             } else if (c>=0x61 && c<=0x66) {
194                 b=(byte)(c-0x57);  // account for "A"
195             } else if (c>=0x41 && c<=0x46) {
196                 b=(byte)(c-0x37);
197             } else {
198                 throw new CadiException("Invalid char '" + c + "' in HexString");
199             }
200             idx = (i-2)/2;
201             if (high) {
202                 ba[idx]=(byte)(b<<4);
203                 high = false;
204             } else {
205                 ba[idx]|=b;
206                 high = true;
207             }
208         }
209         return ba;
210     }
211
212     /**
213      * Does not expect to start with "0x"
214      * if Any Character doesn't match, it returns null;
215      *
216      * @param s
217      * @return
218      */
219     public static byte[] fromHexNo0x(String s) {
220         int c;
221         byte b;
222         byte[] ba;
223         boolean high;
224         int start;
225         if (s.length()%2==0) {
226             ba = new byte[s.length()/2];
227             high=true;
228             start=0;
229         } else {
230             ba = new byte[(s.length()/2)+1];
231             high = false;
232             start=1;
233         }
234         int idx;
235         for (int i=start;i<s.length();++i) {
236             c = s.charAt((i-start));
237             if (c>=0x30 && c<=0x39) {
238                 b=(byte)(c-0x30);
239             } else if (c>=0x61 && c<=0x66) {
240                 b=(byte)(c-0x57);  // account for "A"
241             } else if (c>=0x41 && c<=0x46) {
242                 b=(byte)(c-0x37);
243             } else {
244                 return null;
245             }
246             idx = i/2;
247             if (high) {
248                 ba[idx]=(byte)(b<<4);
249                 high = false;
250             } else {
251                 ba[idx]|=b;
252                 high = true;
253             }
254         }
255         return ba;
256     }
257
258 }