m2u-upass-core / src / my / com / upass / tac / TacCrypto.java @ 74:214028f5d496
History | View | Annotate | Download (6.22 KB)
1 |
package my.com.upass.tac; |
---|---|
2 |
|
3 |
import java.io.UnsupportedEncodingException; |
4 |
import java.lang.String; |
5 |
import java.text.DecimalFormat; |
6 |
import java.util.Date; |
7 |
|
8 |
import java.security.MessageDigest; |
9 |
import java.security.NoSuchAlgorithmException; |
10 |
import java.security.SecureRandom; |
11 |
import my.com.upass.pojo.TacBean; |
12 |
|
13 |
public class TacCrypto { |
14 |
|
15 |
private long userID; |
16 |
private String Tac; |
17 |
private String CipherText; |
18 |
private static boolean isValid = false; |
19 |
private static String StatusCode; |
20 |
private Date timeStamp; |
21 |
private String nonce; |
22 |
|
23 |
private static final int defaultTimeout = 3600; // 1hr |
24 |
|
25 |
// /////////////////////////////////////////////////////////////////////
|
26 |
// Constructors
|
27 |
// /////////////////////////////////////////////////////////////////////
|
28 |
public TacCrypto(TacBean tacBeanObject) {
|
29 |
this.userID = tacBeanObject.getUserID();
|
30 |
this.nonce = tacBeanObject.getNonce();
|
31 |
Tac = Generate(); |
32 |
CipherText = getOffset(userID, Tac); |
33 |
} |
34 |
|
35 |
public TacCrypto(TacBean tb, String Tac, int nTimeout) { |
36 |
this.userID = tb.getUserID();
|
37 |
this.nonce = tb.getNonce();
|
38 |
this.Tac = Tac;
|
39 |
this.CipherText = tb.getCipherText();
|
40 |
isValid = Verify(userID, Tac, tb.getCipherText(), nTimeout); |
41 |
} |
42 |
|
43 |
public TacCrypto(TacBean tb, String Tac, String CipherText) { |
44 |
this.userID = tb.getUserID();
|
45 |
this.Tac = Tac;
|
46 |
this.CipherText = CipherText;
|
47 |
int nTimeout = defaultTimeout;
|
48 |
isValid = Verify(userID, Tac, CipherText, nTimeout); |
49 |
} |
50 |
|
51 |
// /////////////////////////////////////////////////////////////////////
|
52 |
// Public Method
|
53 |
// /////////////////////////////////////////////////////////////////////
|
54 |
public String getTac() { |
55 |
return Tac;
|
56 |
} |
57 |
|
58 |
public String getOffset() { |
59 |
return CipherText;
|
60 |
} |
61 |
|
62 |
public boolean getIsValid() { |
63 |
return isValid;
|
64 |
} |
65 |
|
66 |
public String getStatusCode() { |
67 |
return StatusCode;
|
68 |
} |
69 |
|
70 |
public Date getTimeStamp() { |
71 |
return timeStamp;
|
72 |
} |
73 |
|
74 |
// /////////////////////////////////////////////////////////////////////
|
75 |
// Convert byte to hex
|
76 |
// /////////////////////////////////////////////////////////////////////
|
77 |
private String convertToHex(byte[] data) { |
78 |
StringBuffer buf = new StringBuffer(); |
79 |
for (int i = 0; i < 8 /* Or data.length */; i++) { |
80 |
int halfbyte = (data[i] >>> 4) & 0x0F; |
81 |
int two_halfs = 0; |
82 |
do {
|
83 |
if ((0 <= halfbyte) && (halfbyte <= 9)) |
84 |
buf.append((char) ('0' + halfbyte)); |
85 |
else
|
86 |
buf.append((char) ('A' + (halfbyte - 10))); |
87 |
halfbyte = data[i] & 0x0F;
|
88 |
} while (two_halfs++ < 1); |
89 |
} |
90 |
return buf.toString();
|
91 |
} |
92 |
|
93 |
// /////////////////////////////////////////////////////////////////////
|
94 |
// convert long to byte []
|
95 |
// /////////////////////////////////////////////////////////////////////
|
96 |
private final byte[] longToByteArray(long value) { |
97 |
return new byte[] { |
98 |
(byte) (value >>> 56), |
99 |
(byte) (value >>> 48), |
100 |
(byte) (value >>> 40), |
101 |
(byte) (value >>> 32), |
102 |
(byte) (value >>> 24), |
103 |
(byte) (value >>> 16), |
104 |
(byte) (value >>> 8), |
105 |
(byte) value };
|
106 |
} |
107 |
|
108 |
// /////////////////////////////////////////////////////////////////////
|
109 |
// Public Generate TAC
|
110 |
// /////////////////////////////////////////////////////////////////////
|
111 |
private String GenerateUTC() { |
112 |
|
113 |
Date now = new Date(); |
114 |
// sTimeStamp = new String(Constants.defaultDateFormat.format(now));
|
115 |
timeStamp = now; |
116 |
|
117 |
long UTC = now.getTime();
|
118 |
byte[] bUTC = longToByteArray(UTC); |
119 |
return convertToHex(bUTC);
|
120 |
} |
121 |
|
122 |
private int CompareUTC(String s) { |
123 |
long l = Long.parseLong(s, 16); |
124 |
Date now = new Date(); |
125 |
long UTC = now.getTime();
|
126 |
return (int) (UTC - l); |
127 |
|
128 |
} |
129 |
|
130 |
// /////////////////////////////////////////////////////////////////////
|
131 |
// Generate 40-byte SHA-2
|
132 |
// /////////////////////////////////////////////////////////////////////
|
133 |
public String SHA2(long userID, String Tac, String nonce) { |
134 |
try {
|
135 |
String strID = Long.toString(userID); |
136 |
if (nonce != null) { |
137 |
strID = strID + nonce; // add additional nonce if provided
|
138 |
} |
139 |
MessageDigest md;
|
140 |
md = MessageDigest.getInstance("SHA-256"); |
141 |
byte[] sha2hash = new byte[40]; |
142 |
md.update(Tac.getBytes("iso-8859-1"), 0, Tac.length()); |
143 |
md.update(strID.getBytes("iso-8859-1"), 0, strID.length()); |
144 |
sha2hash = md.digest(); |
145 |
return convertToHex(sha2hash);
|
146 |
} catch (NoSuchAlgorithmException e) { |
147 |
e.printStackTrace(); |
148 |
} catch (UnsupportedEncodingException e) { |
149 |
e.printStackTrace(); |
150 |
} |
151 |
return new String("******"); |
152 |
} |
153 |
|
154 |
// /////////////////////////////////////////////////////////////////////
|
155 |
// Generate 6-digit random number from standard Java SecureRandam
|
156 |
// /////////////////////////////////////////////////////////////////////
|
157 |
private String getRandom6d() { |
158 |
try {
|
159 |
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); |
160 |
byte[] seed = sr.getSeed(8); |
161 |
sr.setSeed(seed); |
162 |
int r = sr.nextInt(999999 + 1); |
163 |
DecimalFormat df = new DecimalFormat("000000"); |
164 |
return new String(df.format(r)); |
165 |
|
166 |
} catch (NoSuchAlgorithmException e) { |
167 |
e.printStackTrace(); |
168 |
} |
169 |
|
170 |
return new String("******"); |
171 |
} |
172 |
|
173 |
// /////////////////////////////////////////////////////////////////////
|
174 |
// Public Generate TAC
|
175 |
// /////////////////////////////////////////////////////////////////////
|
176 |
private String Generate() { |
177 |
return getRandom6d();
|
178 |
} |
179 |
|
180 |
// /////////////////////////////////////////////////////////////////////
|
181 |
// Public Generate TAC offset
|
182 |
// /////////////////////////////////////////////////////////////////////
|
183 |
private String getOffset0(long userID, String Tac) { |
184 |
return SHA2(userID, Tac, this.nonce); |
185 |
} |
186 |
|
187 |
private String getOffset(long userID, String Tac) { |
188 |
return SHA2(userID, Tac, this.nonce) + GenerateUTC(); |
189 |
} |
190 |
|
191 |
// /////////////////////////////////////////////////////////////////////
|
192 |
// Verify TAC
|
193 |
// /////////////////////////////////////////////////////////////////////
|
194 |
private boolean Verify(long userID, String Tac, String TacOffset, int nTimeout) { |
195 |
String TacOffset0 = TacOffset.substring(0, 16); |
196 |
String TacOffset1 = TacOffset.substring(16); |
197 |
boolean isTac = TacOffset0.equals(getOffset0(userID, Tac));
|
198 |
boolean isNotExpired = (CompareUTC(TacOffset1) < (nTimeout * 1000)); |
199 |
StatusCode = ((isTac) ? "0" : "1") + ((isNotExpired) ? "0" : "1"); |
200 |
return (isTac && isNotExpired);
|
201 |
} |
202 |
|
203 |
} // end class TacCrypto
|
204 |
|