changed to unmaintained
[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 /**
29  * 
30  * 
31  * @author Jonathan
32  *
33  */
34 public class Hash {
35     private static char hexDigit[] = "0123456789abcdef".toCharArray();
36
37 /////////////////////////////////
38 // MD5
39 /////////////////////////////////
40     /**
41      * Encrypt MD5 from Byte Array to Byte Array
42      * @param input
43      * @return
44      * @throws NoSuchAlgorithmException
45      */
46     public static byte[] hashMD5 (byte[] input) throws NoSuchAlgorithmException {
47         // Note: Protect against Multi-thread issues with new MessageDigest
48         MessageDigest md = MessageDigest.getInstance("MD5");
49         md.update(input);
50         return md.digest();
51     }
52
53     /**
54      * Encrypt MD5 from Byte Array to Byte Array
55      * @param input
56      * @return
57      * @throws NoSuchAlgorithmException
58      */
59     public static byte[] hashMD5 (byte[] input, int offset, int length) throws NoSuchAlgorithmException {
60         // Note: Protect against Multi-thread issues with new MessageDigest
61         MessageDigest md = MessageDigest.getInstance("MD5");
62         md.update(input,offset,length);
63         return md.digest();
64     }
65
66
67
68     /**
69      * Convenience Function: Encrypt MD5 from String to String Hex representation
70      *
71      * @param input
72      * @return
73      * @throws NoSuchAlgorithmException
74      */
75     public static String hashMD5asStringHex(String input) throws NoSuchAlgorithmException {
76         byte[] output = hashMD5(input.getBytes());
77         StringBuilder sb = new StringBuilder("0x");
78          for (byte b : output) {
79             sb.append(hexDigit[(b >> 4) & 0x0f]);
80             sb.append(hexDigit[b & 0x0f]);
81          }
82          return sb.toString();
83     }
84
85 /////////////////////////////////
86 // SHA256
87 /////////////////////////////////
88     /**
89      * SHA256 Hashing
90      */
91     public static byte[] hashSHA256(byte[] input) throws NoSuchAlgorithmException {
92         // Note: Protect against Multi-thread issues with new MessageDigest
93         MessageDigest md = MessageDigest.getInstance("SHA-256");
94         md.update(input);
95         return md.digest();
96     }
97
98     /**
99      * SHA256 Hashing
100      */
101     public static byte[] hashSHA256(byte[] input, int offset, int length) throws NoSuchAlgorithmException {
102         // Note: Protect against Multi-thread issues with new MessageDigest
103         MessageDigest md = MessageDigest.getInstance("SHA-256");
104         md.update(input,offset,length);
105         return md.digest();
106     }
107
108     /**
109      * Convenience Function: Hash from String to String Hex representation
110      *
111      * @param input
112      * @return
113      * @throws NoSuchAlgorithmException
114      */
115     public static String hashSHA256asStringHex(String input) throws NoSuchAlgorithmException {
116         return toHex(hashSHA256(input.getBytes()));
117     }
118
119     /**
120      * Convenience Function: Hash from String to String Hex representation
121      *
122      * @param input
123      * @return
124      * @throws NoSuchAlgorithmException
125      */
126     public static String hashSHA256asStringHex(String input, int salt) throws NoSuchAlgorithmException {
127         byte[] in = input.getBytes();
128         ByteBuffer bb = ByteBuffer.allocate(Integer.SIZE + in.length);
129         bb.putInt(salt);
130         bb.put(input.getBytes());
131         return toHex(Hash.hashSHA256(bb.array()));
132     }
133
134     /**
135      * Compare two byte arrays for equivalency
136      * @param ba1
137      * @param ba2
138      * @return
139      */
140     public static boolean isEqual(byte ba1[], byte ba2[]) {
141         if (ba1.length!=ba2.length)return false;
142         for (int i = 0;i<ba1.length; ++i) {
143             if (ba1[i]!=ba2[i])return false;
144         }
145         return true;
146     }
147
148     public static int compareTo(byte[] a, byte[] b) {
149         int end = Math.min(a.length, b.length);
150         int compare = 0;
151         for (int i=0;compare == 0 && i<end;++i) {
152             compare = a[i]-b[i];
153         }
154         if (compare==0)compare=a.length-b.length;
155         return compare;
156     }
157
158     /**
159      * @param ba
160      * @return
161      */
162     public static String toHexNo0x(byte[] ba) {
163         StringBuilder sb = new StringBuilder();
164          for (byte b : ba) {
165             sb.append(hexDigit[(b >> 4) & 0x0f]);
166             sb.append(hexDigit[b & 0x0f]);
167          }
168          return sb.toString();
169     }
170
171     /**
172      * @param ba
173      * @return
174      */
175     public static String toHex(byte[] ba) {
176         StringBuilder sb = new StringBuilder("0x");
177          for (byte b : ba) {
178             sb.append(hexDigit[(b >> 4) & 0x0f]);
179             sb.append(hexDigit[b & 0x0f]);
180          }
181          return sb.toString();
182     }
183
184     public static String toHex(byte[] ba, int start, int length) {
185         StringBuilder sb = new StringBuilder("0x");
186          for (int i=start;i<length;++i) {
187             sb.append(hexDigit[(ba[i] >> 4) & 0x0f]);
188             sb.append(hexDigit[ba[i] & 0x0f]);
189          }
190          return sb.toString();
191     }
192
193
194     public static byte[] fromHex(String s) {
195         if(!s.startsWith("0x")) {
196                 return fromHexNo0x(s);
197         }
198         byte b;
199         int c;
200         byte[] ba;
201         int extra = s.length()%2; // odd requires extra
202         ba = new byte[(s.length()-2)/2 + extra];
203         boolean high = extra==0;
204         
205         int idx;
206         for (int i=2;i<s.length();++i) {
207             c = s.charAt(i);
208             if (c>=0x30 && c<=0x39) {
209                 b=(byte)(c-0x30);
210             } else if (c>=0x61 && c<=0x66) {
211                 b=(byte)(c-0x57);  // account for "A"
212             } else if (c>=0x41 && c<=0x46) {
213                 b=(byte)(c-0x37);
214             } else {
215                 return null;
216             }
217             idx = (i-2+extra)/2;
218             if (high) {
219                 ba[idx]=(byte)(b<<4);
220                 high = false;
221             } else {
222                 ba[idx]|=b;
223                 high = true;
224             }
225         }
226         return ba;
227     }
228     
229     /**
230      * Does not expect to start with "0x"
231      * if Any Character doesn't match, it returns null;
232      *
233      * @param s
234      * @return
235      */
236     public static byte[] fromHexNo0x(String s) {
237         byte b;
238         int c;
239         byte[] ba;
240         int extra = s.length()%2; // odd requires extra byte to store
241         ba = new byte[(s.length())/2 + extra];
242         boolean high = extra==0;
243         
244         int idx;
245         for (int i=0;i<s.length();++i) {
246             c = s.charAt(i);
247             if (c>=0x30 && c<=0x39) {
248                 b=(byte)(c-0x30);
249             } else if (c>=0x61 && c<=0x66) {
250                 b=(byte)(c-0x57);  // account for "A"
251             } else if (c>=0x41 && c<=0x46) {
252                 b=(byte)(c-0x37);
253             } else {
254                 return null;
255             }
256             idx = (i+extra)/2;
257             if (high) {
258                 ba[idx]=(byte)(b<<4);
259                 high = false;
260             } else {
261                 ba[idx]|=b;
262                 high = true;
263             }
264         }
265         return ba;
266     }
267 }