1 package org.openkilda.security;
3 import java.lang.reflect.UndeclaredThrowableException;
4 import java.math.BigInteger;
5 import java.nio.charset.StandardCharsets;
6 import java.security.GeneralSecurityException;
7 import java.security.SecureRandom;
8 import java.text.DateFormat;
9 import java.text.SimpleDateFormat;
10 import java.util.TimeZone;
12 import javax.crypto.Mac;
13 import javax.crypto.spec.SecretKeySpec;
15 import org.apache.commons.codec.binary.Base32;
16 import org.apache.commons.codec.binary.Base64;
17 import org.apache.commons.logging.Log;
18 import org.apache.commons.logging.LogFactory;
23 private static final int[] DIGITS_POWER
25 = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
28 SecureRandom random =
new SecureRandom();
29 byte bytes[] =
new byte[20];
30 random.nextBytes(bytes);
31 Base32 base32 =
new Base32();
32 String base32String = base32.encodeAsString(bytes);
34 logger.debug(
" getBase32EncryptedKey method response " + base32String);
40 logger.debug(
"[generateEncryptedKey] param : base32String " + base32String);
41 String generatedKey = null;
44 byte[] key = Base64.encodeBase64(rsaString.getBytes());
45 generatedKey =
new String(key);
46 }
catch (Exception e) {
47 logger.error(
"[generateEncryptedKey] Exception :" + e);
51 logger.debug(
"[generateEncryptedKey] response " + generatedKey);
56 public static String
decryptKey(
final String secretKey)
throws Exception {
57 logger.debug(
"[decryptKey] param : secretKey " + secretKey);
58 byte[] decodedArray = Base64.decodeBase64(secretKey.getBytes());
59 String decodeValue =
new String(decodedArray, StandardCharsets.UTF_8);
62 logger.debug(
"[decryptKey] response " +
decryptKey);
67 logger.debug(
"[validateOtp] param : ,decryptKey : " +
decryptKey);
68 boolean otpValid =
false;
69 Base32 base32 =
new Base32();
71 String byteToHex = bytesToHex(decoded);
72 String seed = byteToHex;
75 String codelength =
"6";
76 long z = System.currentTimeMillis() / 1000;
78 long testTime[] = {z};
80 DateFormat df =
new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
81 df.setTimeZone(TimeZone.getTimeZone(
"UTC"));
84 for (
int i = 0;
i < testTime.length;
i++) {
85 long T = (testTime[
i] - T0) / X;
86 steps = Long.toHexString(T).toUpperCase();
87 while (steps.length() < 16) {
90 otpVal =
generateTOTP(seed, steps, codelength,
"HmacSHA1");
92 }
catch (Exception e) {
93 logger.error(
"[validateOtp] Exception :" + e);
96 if (otp.equals(otpVal)) {
100 logger.debug(
"[validateOtp] response " + otpValid);
105 public static String
generateTOTP(
final String key,
final String time,
final String returnDigits) {
106 logger.debug(
"[generateTOTP] param : key " + key +
",returnDigits : " + returnDigits);
107 return generateTOTP(key, time, returnDigits,
"HmacSHA1");
122 final String returnDigits,
final String crypto) {
123 logger.debug(
"[generateTOTP] param : key " + key +
",time : " + time +
",returnDigits: " 124 + returnDigits +
", crypto :" + crypto);
125 int codeDigits = Integer.decode(returnDigits).intValue();
131 String updatedTime = time;
132 while (updatedTime.length() < 16) {
133 updatedTime =
"0" + updatedTime;
137 byte[] msg = hexStr2Bytes(updatedTime);
138 byte[] k = hexStr2Bytes(key);
140 byte[] hash = hmac_sha(crypto, k, msg);
143 int offset = hash[hash.length - 1] & 0xf;
144 int binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16)
145 | ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff);
146 int otp = binary % DIGITS_POWER[codeDigits];
148 result = Integer.toString(otp);
149 while (
result.length() < codeDigits) {
155 private static byte[] hexStr2Bytes(
final String hex) {
156 logger.debug(
"[hexStr2Bytes] param : key " + hex);
159 byte[] bArray =
new BigInteger(
"10" + hex, 16).toByteArray();
162 byte[] ret =
new byte[bArray.length - 1];
163 for (
int i = 0;
i < ret.length;
i++) {
164 ret[
i] = bArray[
i + 1];
167 logger.debug(
"[hexStr2Bytes] response " + ret);
171 private static byte[] hmac_sha(
final String crypto,
final byte[] keyBytes,
final byte[] text) {
172 logger.debug(
"[hmac_sha] param : keyBytes " + keyBytes +
",text : " + text +
", crypto :" 177 hmac = Mac.getInstance(crypto);
178 SecretKeySpec macKey =
new SecretKeySpec(keyBytes,
"RAW");
181 return hmac.doFinal(text);
182 }
catch (GeneralSecurityException gse) {
183 logger.error(
"[hmac_sha] Exception :" + gse);
184 throw new UndeclaredThrowableException(gse);
188 private static String bytesToHex(
final byte[] bytes) {
189 logger.debug(
"[bytesToHex] param : bytes " + bytes);
190 final char[] hexArray =
"0123456789ABCDEF".toCharArray();
191 char[] hexChars =
new char[bytes.length * 2];
192 for (
int j = 0; j < bytes.length; j++) {
193 int v = bytes[j] & 0xFF;
194 hexChars[j * 2] = hexArray[v >>> 4];
195 hexChars[j * 2 + 1] = hexArray[v & 0x0F];
197 logger.debug(
"[bytesToHex] response " +
new String(hexChars));
198 return new String(hexChars);
static boolean validateOtp(final String otp, final String decryptKey)
static String generateEncryptedKey(final String base32String)
static String getBase32EncryptedKey()
static String rsaDecrypt(final String text, final String file_des)
static String generateTOTP(final String key, final String time, final String returnDigits)
static String decryptKey(final String secretKey)
static String generateTOTP(final String key, final String time, final String returnDigits, final String crypto)
static String rsaEncrypt(final byte[] text, final String file_des)