format

上级 48f0325f
......@@ -5,7 +5,7 @@ import org.maxkey.authn.support.rememberme.AbstractRemeberMeService;
import org.maxkey.config.ApplicationConfig;
import org.maxkey.constants.LOGINTYPE;
import org.maxkey.crypto.password.PasswordReciprocal;
import org.maxkey.crypto.password.opt.AbstractOTPAuthn;
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
import org.maxkey.domain.UserInfo;
import org.maxkey.web.WebConstants;
import org.maxkey.web.WebContext;
......@@ -37,8 +37,8 @@ public abstract class AbstractAuthenticationProvider {
protected AbstractAuthenticationRealm authenticationRealm;
@Autowired
@Qualifier("tfaOTPAuthn")
protected AbstractOTPAuthn tfaOptAuthn;
@Qualifier("tfaOptAuthn")
protected AbstractOptAuthn tfaOptAuthn;
@Autowired
@Qualifier("remeberMeService")
......
......@@ -3,19 +3,19 @@ package org.maxkey.crypto;
import org.apache.commons.codec.binary.Base32;
public class Base32Utils {
static Base32 base32=new Base32();
public static String encode(String simple){
return base32.encodeToString(simple.getBytes());
}
public static String encode(byte[] simple){
return base32.encodeToString(simple);
}
public static byte[] decode(String cipher){
return base32.decode(cipher);
}
static Base32 base32 = new Base32();
public static String encode(String simple) {
return base32.encodeToString(simple.getBytes());
}
public static String encode(byte[] simple) {
return base32.encodeToString(simple);
}
public static byte[] decode(String cipher) {
return base32.decode(cipher);
}
}
......@@ -3,121 +3,128 @@ package org.maxkey.crypto;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.commons.codec.binary.Base64;
/**
* Base64 Utils
* Base64 Utils.
*
* @author Crystal.Sea
*
*/
public final class Base64Utils {
public static String encodeBase64(byte[] simple) {
String cipher = BytesUtils.bytes2String(Base64.encodeBase64(simple));
return cipher;
}
public static byte[] decoderBase64(String cipher) {
byte[] simple = Base64.decodeBase64(cipher);
return simple;
}
public static String encode(String simple) {
return encodeBase64(simple.getBytes());
}
public static String encoder(byte[] simple) {
return encodeBase64(simple);
}
public static String decode(String cipher) {
return BytesUtils.bytes2String(decoderBase64(cipher));
}
public static byte[] decoder(String cipher) {
return decoderBase64(cipher);
}
/**
* encode file to base64 Code String
*
* @param fileName
* file path
* @return *
* @throws Exception
*/
public static String fileToBase64(String fileName) throws Exception {
File file = new File(fileName);
FileInputStream inputFile = new FileInputStream(file);
byte[] buffer = new byte[(int) file.length()];
inputFile.read(buffer);
inputFile.close();
return encodeBase64(buffer);
}
/**
* base64 Code decode String save to targetPath
*
* @param base64Code
* @param targetPath
* @throws Exception
*/
public static void decodeBase64ToFile(String base64Code, String targetPath)
throws Exception {
byte[] buffer = decoderBase64(base64Code);
FileOutputStream out = new FileOutputStream(targetPath);
out.write(buffer);
out.close();
}
/**
* base64 code save to file
*
* @param base64Code
* @param targetPath
* @throws Exception
*/
public static void base64ToFile(String base64Code, String targetPath)
throws Exception {
byte[] buffer = base64Code.getBytes();
FileOutputStream out = new FileOutputStream(targetPath);
out.write(buffer);
out.close();
}
public static String base64UrlEncode(byte[] simple) {
String s = new String(Base64.encodeBase64(simple)); // Regular base64
// encoder
s = s.split("=")[0]; // Remove any trailing '='s
s = s.replace('+', '-'); // 62nd char of encoding
s = s.replace('/', '_'); // 63rd char of encoding
return s;
}
public static byte[] base64UrlDecode(String cipher) {
String s = cipher;
s = s.replace('-', '+'); // 62nd char of encoding
s = s.replace('_', '/'); // 63rd char of encoding
switch (s.length() % 4) { // Pad with trailing '='s
case 0:
break; // No pad chars in this case
case 2:
s += "==";
break; // Two pad chars
case 3:
s += "=";
break; // One pad char
default:
System.err.println("Illegal base64url String!");
}
return Base64.decodeBase64(s); // Standard base64 decoder
}
public static String encodeBase64(byte[] simple) {
String cipher = BytesUtils.bytes2String(Base64.encodeBase64(simple));
return cipher;
}
public static byte[] decoderBase64(String cipher) {
byte[] simple = Base64.decodeBase64(cipher);
return simple;
}
public static String encode(String simple) {
return encodeBase64(simple.getBytes());
}
public static String encoder(byte[] simple) {
return encodeBase64(simple);
}
public static String decode(String cipher) {
return BytesUtils.bytes2String(decoderBase64(cipher));
}
public static byte[] decoder(String cipher) {
return decoderBase64(cipher);
}
/**
* encode file to base64 Code String.
*
* @param fileName file path
* @return *
* @throws Exception e
*/
public static String fileToBase64(String fileName) throws Exception {
File file = new File(fileName);
FileInputStream inputFile = new FileInputStream(file);
byte[] buffer = new byte[(int) file.length()];
inputFile.read(buffer);
inputFile.close();
return encodeBase64(buffer);
}
/**
* base64 Code decode String save to targetPath.
*
* @param base64Code String
* @param targetPath String
* @throws Exception e
*/
public static void decodeBase64ToFile(String base64Code, String targetPath) throws Exception {
byte[] buffer = decoderBase64(base64Code);
FileOutputStream out = new FileOutputStream(targetPath);
out.write(buffer);
out.close();
}
/**
* base64 code save to file.
*
* @param base64Code String
* @param targetPath String
* @throws Exception e
*/
public static void base64ToFile(String base64Code, String targetPath) throws Exception {
byte[] buffer = base64Code.getBytes();
FileOutputStream out = new FileOutputStream(targetPath);
out.write(buffer);
out.close();
}
/**
* base64UrlEncode.
* @param simple byte
* @return
*/
public static String base64UrlEncode(byte[] simple) {
// Regular base64
String s = new String(Base64.encodeBase64(simple));
// encoder
s = s.split("=")[0]; // Remove any trailing '='s
s = s.replace('+', '-'); // 62nd char of encoding
s = s.replace('/', '_'); // 63rd char of encoding
return s;
}
/**
* base64UrlDecode.
* @param cipher String
* @return
*/
public static byte[] base64UrlDecode(String cipher) {
String s = cipher;
s = s.replace('-', '+'); // 62nd char of encoding
s = s.replace('_', '/'); // 63rd char of encoding
switch (s.length() % 4) { // Pad with trailing '='s
case 0 :
break; // No pad chars in this case
case 2 :
s += "==";
break; // Two pad chars
case 3 :
s += "=";
break; // One pad char
default:
System.err.println("Illegal base64url String!");
}
return Base64.decodeBase64(s); // Standard base64 decoder
}
}
......@@ -3,51 +3,70 @@ package org.maxkey.crypto.password;
import java.util.Random;
/**
* PasswordGen.
* @author Crystal.Sea
*
*
*/
public class PasswordGen {
public static String CHAR_LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
public static String CHAR_UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static String CHAR_NUMBERS = "0123456789";
public static String CHAR_SPECIAL = "~@#^()[]*$-+?_&=!%{}/";
public static String CHAR_DEFAULT = CHAR_LOWERCASE + CHAR_NUMBERS + CHAR_UPPERCASE;
private Random random = new Random();
public static int DEFAULT_LENGTH = 8;
public PasswordGen() {
}
public String gen() {
return gen(DEFAULT_LENGTH);
}
public String gen(int length) {
return gen(CHAR_DEFAULT,length);
public static String CHAR_LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
public static String CHAR_UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static String CHAR_NUMBERS = "0123456789";
public static String CHAR_SPECIAL = "~@#^()[]*$-+?_&=!%{}/";
public static String CHAR_DEFAULT = CHAR_LOWERCASE + CHAR_NUMBERS + CHAR_UPPERCASE;
private Random random = new Random();
public static int DEFAULT_LENGTH = 8;
public PasswordGen() {
}
public String gen(int lowerCase,int upperCase,int numbers,int special) {
StringBuffer password=new StringBuffer("");
password.append(gen(CHAR_LOWERCASE,lowerCase));
password.append(gen(CHAR_NUMBERS,numbers));
password.append(gen(CHAR_UPPERCASE,upperCase));
password.append(gen(CHAR_SPECIAL,special));
return gen(password.toString(),password.length());//random generator String by sequence password
}
public String gen(final String charString, int length) {
if (length < 1) {return "";}
public String gen() {
return gen(DEFAULT_LENGTH);
}
public String gen(int length) {
return gen(CHAR_DEFAULT, length);
}
/**
* gen .
* @param lowerCase int
* @param upperCase int
* @param numbers int
* @param special int
* @return
*/
public String gen(int lowerCase, int upperCase, int numbers, int special) {
StringBuffer password = new StringBuffer("");
password.append(gen(CHAR_LOWERCASE, lowerCase));
password.append(gen(CHAR_NUMBERS, numbers));
password.append(gen(CHAR_UPPERCASE, upperCase));
password.append(gen(CHAR_SPECIAL, special));
// random generator String by sequence password
return gen(password.toString(), password.length());
}
/**
* gen.
* @param charString String
* @param length int
* @return
*/
public String gen(final String charString, int length) {
if (length < 1) {
return "";
}
int i = 0;
StringBuffer password=new StringBuffer("");
while(i < length) {
int randomPosition = random.nextInt(charString.length());
if(password.indexOf(charString.charAt(randomPosition)+"")<0){//duplicate check
password.append(charString.charAt(randomPosition));
i++;
}
StringBuffer password = new StringBuffer("");
while (i < length) {
int randomPosition = random.nextInt(charString.length());
// duplicate check
if (password.indexOf(charString.charAt(randomPosition) + "") < 0) {
password.append(charString.charAt(randomPosition));
i++;
}
}
return password.toString();
}
......
/**
*
*/
package org.maxkey.crypto.password;
import org.maxkey.crypto.ReciprocalUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* PasswordReciprocal.
* @author Crystal.Sea
*
*/
public class PasswordReciprocal implements PasswordEncoder{
public static PasswordReciprocal passwordReciprocal;
/**
*
*/
public PasswordReciprocal() {
}
public static PasswordReciprocal getInstance(){
if(passwordReciprocal==null){
passwordReciprocal=new PasswordReciprocal();
}
return passwordReciprocal;
}
public String rawPassword(String username,String password) {
return password+"@"+username;
}
public String encode(CharSequence rawPassword) {
return ReciprocalUtils.encode(rawPassword.toString());
}
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return ReciprocalUtils.encode(rawPassword.toString()).equals(encodedPassword);
}
public String decoder(CharSequence encodedPassword) {
return ReciprocalUtils.decoder(encodedPassword.toString());
}
public class PasswordReciprocal implements PasswordEncoder {
public static PasswordReciprocal passwordReciprocal;
public PasswordReciprocal() {
}
/**
* getInstance.
* @return
*/
public static PasswordReciprocal getInstance() {
if (passwordReciprocal == null) {
passwordReciprocal = new PasswordReciprocal();
}
return passwordReciprocal;
}
public String rawPassword(String username, String password) {
return password + "@" + username;
}
public String encode(CharSequence rawPassword) {
return ReciprocalUtils.encode(rawPassword.toString());
}
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return ReciprocalUtils.encode(rawPassword.toString()).equals(encodedPassword);
}
public String decoder(CharSequence encodedPassword) {
return ReciprocalUtils.decoder(encodedPassword.toString());
}
}
package org.maxkey.crypto.password.opt;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.format.DateTimeFormat;
import org.maxkey.constants.STATUS;
import org.maxkey.domain.UserInfo;
import org.maxkey.util.StringGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
public abstract class AbstractOTPAuthn {
private final static Logger logger = LoggerFactory.getLogger(AbstractOTPAuthn.class);
protected int interval = 30;
protected int digits = 6;
protected String crypto = "HmacSHA1";
StringGenerator stringGenerator;
private final JdbcTemplate jdbcTemplate;
public static class OPT_TYPES{
//手机
public static int MOBILE = 2;
//短信
public static int SMS = 3;
//邮箱
public static int EMAIL = 4;
public static int TIMEBASED_OPT = 5;
public static int COUNTERBASED_OPT = 6;
public static int HOTP_OPT = 7;
public static int RSA_OPT = 8;
}
private static final String DEFAULT_DEFAULT_INSERT_STATEMENT = "INSERT INTO ONE_TIME_PASSWORD(ID ,OPTTYPE,USERNAME,TOKEN,RECEIVER,CREATETIME,STATUS) VALUES(?,?,?,?,?,?,"+STATUS.ACTIVE+")";
private static final String DEFAULT_DEFAULT_SELECT_STATEMENT = "SELECT ID ,OPTTYPE,USERNAME,TOKEN,RECEIVER,CREATETIME FROM ONE_TIME_PASSWORD WHERE STATUS ="+STATUS.ACTIVE+" AND USERNAME = ? AND TOKEN = ? AND OPTTYPE = ?";
private static final String DEFAULT_DEFAULT_DELETE_STATEMENT = "UPDATE ONE_TIME_PASSWORD SET STATUS ="+STATUS.DELETE+" WHERE USERNAME = ? AND TOKEN = ? AND OPTTYPE = ?";
abstract public boolean produce(UserInfo userInfo);
abstract public boolean validate(UserInfo userInfo,String token);
protected String defaultProduce(UserInfo userInfo){
return genToken(userInfo);
}
public String genToken(UserInfo userInfo){
if(stringGenerator==null){
stringGenerator=new StringGenerator(StringGenerator.DEFAULT_CODE_NUMBER,digits);
}
return stringGenerator.randomGenerate();
}
public AbstractOTPAuthn(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
protected void insertDataBase(UserInfo userInfo,String token,String receiver,int type){
jdbcTemplate.update(DEFAULT_DEFAULT_INSERT_STATEMENT,
new Object[] {
java.util.UUID.randomUUID(),
type,
userInfo.getUsername(),
token,
receiver,
new Date()
},
new int[] {Types.VARCHAR,Types.INTEGER,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR, Types.TIMESTAMP}
);
}
public boolean validateDataBase(UserInfo userInfo,String token,int type){
OneTimePassword oneTimePassword=jdbcTemplate.queryForObject(
DEFAULT_DEFAULT_SELECT_STATEMENT,
new OneTimePasswordRowMapper(),
userInfo.getUsername(),
token,
type);
if(oneTimePassword!=null){
jdbcTemplate.update(DEFAULT_DEFAULT_DELETE_STATEMENT,
new Object[] {
userInfo.getUsername(),
token,
type},
new int[] {Types.VARCHAR,Types.VARCHAR, Types.INTEGER}
);
DateTime currentdateTime = new DateTime();
DateTime oneTimePwdData=DateTime.parse(oneTimePassword.getCreateTime(), DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"));
Duration duration = new Duration(oneTimePwdData, currentdateTime);
int intDuration=Integer.parseInt(duration.getStandardSeconds()+"");
logger.debug("validate duration "+intDuration);
logger.debug("validate result "+(intDuration<=interval));
if(intDuration<=interval){
return true;
}
}
return false;
}
/**
* @return the interval
*/
public int getInterval() {
return interval;
}
/**
* @param interval the interval to set
*/
public void setInterval(int interval) {
this.interval = interval;
}
/**
* @return the digits
*/
public int getDigits() {
return digits;
}
/**
* @param digits the digits to set
*/
public void setDigits(int digits) {
this.digits = digits;
}
/**
* @return the crypto
*/
public String getCrypto() {
return crypto;
}
/**
* @param crypto the crypto to set
*/
public void setCrypto(String crypto) {
this.crypto = crypto;
}
public class OneTimePasswordRowMapper implements RowMapper<OneTimePassword> {
public OneTimePassword mapRow(ResultSet rs, int rowNum) throws SQLException {
OneTimePassword oneTimePassword=new OneTimePassword();
oneTimePassword.setId(rs.getString("ID"));
oneTimePassword.setType(rs.getInt("OPTTYPE"));
oneTimePassword.setUsername(rs.getString("USERNAME"));
oneTimePassword.setToken(rs.getString("TOKEN"));
oneTimePassword.setUsername(rs.getString("USERNAME"));
oneTimePassword.setReceiver(rs.getString("RECEIVER"));
oneTimePassword.setCreateTime(rs.getString("CREATETIME"));
return oneTimePassword;
}
}
}
package org.maxkey.crypto.password.opt;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.format.DateTimeFormat;
import org.maxkey.constants.STATUS;
import org.maxkey.domain.UserInfo;
import org.maxkey.util.StringGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
/**
* AbstractOTPAuthn.
* @author Administrator
*
*/
public abstract class AbstractOptAuthn {
private static final Logger logger = LoggerFactory.getLogger(AbstractOptAuthn.class);
protected int interval = 30;
protected int digits = 6;
protected String crypto = "HmacSHA1";
StringGenerator stringGenerator;
private final JdbcTemplate jdbcTemplate;
public static final class OPT_TYPES {
// 手机
public static int MOBILE = 2;
// 短信
public static int SMS = 3;
// 邮箱
public static int EMAIL = 4;
public static int TIMEBASED_OPT = 5;
public static int COUNTERBASED_OPT = 6;
public static int HOTP_OPT = 7;
public static int RSA_OPT = 8;
}
private static final String DEFAULT_DEFAULT_INSERT_STATEMENT =
"INSERT INTO ONE_TIME_PASSWORD(ID ,OPTTYPE,USERNAME,TOKEN,RECEIVER,CREATETIME,STATUS)"
+ " VALUES(?,?,?,?,?,?," + STATUS.ACTIVE + ")";
private static final String DEFAULT_DEFAULT_SELECT_STATEMENT =
"SELECT ID ,OPTTYPE,USERNAME,TOKEN,RECEIVER,CREATETIME FROM ONE_TIME_PASSWORD"
+ " WHERE STATUS =" + STATUS.ACTIVE
+ " AND USERNAME = ? AND TOKEN = ? AND OPTTYPE = ?";
private static final String DEFAULT_DEFAULT_DELETE_STATEMENT =
"UPDATE ONE_TIME_PASSWORD SET STATUS ="
+ STATUS.DELETE + " WHERE USERNAME = ? AND TOKEN = ? AND OPTTYPE = ?";
public abstract boolean produce(UserInfo userInfo);
public abstract boolean validate(UserInfo userInfo, String token);
protected String defaultProduce(UserInfo userInfo) {
return genToken(userInfo);
}
/**
* genToken.
* @param userInfo UserInfo
* @return
*/
public String genToken(UserInfo userInfo) {
if (stringGenerator == null) {
stringGenerator = new StringGenerator(StringGenerator.DEFAULT_CODE_NUMBER, digits);
}
return stringGenerator.randomGenerate();
}
public AbstractOptAuthn(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
protected void insertDataBase(UserInfo userInfo, String token, String receiver, int type) {
jdbcTemplate.update(DEFAULT_DEFAULT_INSERT_STATEMENT,
new Object[] {
java.util.UUID.randomUUID(),
type,
userInfo.getUsername(),
token,
receiver,
new Date()
},
new int[] { Types.VARCHAR, Types.INTEGER,
Types.VARCHAR, Types.VARCHAR,
Types.VARCHAR,Types.TIMESTAMP
}
);
}
/**
* validateDataBase.
* @param userInfo UserInfo
* @param token String
* @param type int
* @return
*/
public boolean validateDataBase(UserInfo userInfo, String token, int type) {
OneTimePassword oneTimePassword = jdbcTemplate.queryForObject(
DEFAULT_DEFAULT_SELECT_STATEMENT,
new OneTimePasswordRowMapper(), userInfo.getUsername(), token, type);
if (oneTimePassword != null) {
jdbcTemplate.update(
DEFAULT_DEFAULT_DELETE_STATEMENT,
new Object[] { userInfo.getUsername(), token, type },
new int[] { Types.VARCHAR, Types.VARCHAR, Types.INTEGER }
);
DateTime currentdateTime = new DateTime();
DateTime oneTimePwdData = DateTime.parse(oneTimePassword.getCreateTime(),
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"));
Duration duration = new Duration(oneTimePwdData, currentdateTime);
int intDuration = Integer.parseInt(duration.getStandardSeconds() + "");
logger.debug("validate duration " + intDuration);
logger.debug("validate result " + (intDuration <= interval));
if (intDuration <= interval) {
return true;
}
}
return false;
}
/**
* the interval.
* @return the interval
*/
public int getInterval() {
return interval;
}
/**
* interval the interval to set.
* @param interval the interval to set
*/
public void setInterval(int interval) {
this.interval = interval;
}
/**
* digits.
* @return the digits
*/
public int getDigits() {
return digits;
}
/**
* digits the digits to set.
* @param digits the digits to set
*/
public void setDigits(int digits) {
this.digits = digits;
}
/**
* crypto.
* @return the crypto
*/
public String getCrypto() {
return crypto;
}
/**
* crypto the crypto to set.
* @param crypto the crypto to set
*/
public void setCrypto(String crypto) {
this.crypto = crypto;
}
public class OneTimePasswordRowMapper implements RowMapper<OneTimePassword> {
/**
*ResultSet.
*/
public OneTimePassword mapRow(ResultSet rs, int rowNum) throws SQLException {
OneTimePassword oneTimePassword = new OneTimePassword();
oneTimePassword.setId(rs.getString("ID"));
oneTimePassword.setType(rs.getInt("OPTTYPE"));
oneTimePassword.setUsername(rs.getString("USERNAME"));
oneTimePassword.setToken(rs.getString("TOKEN"));
oneTimePassword.setUsername(rs.getString("USERNAME"));
oneTimePassword.setReceiver(rs.getString("RECEIVER"));
oneTimePassword.setCreateTime(rs.getString("CREATETIME"));
return oneTimePassword;
}
}
}
package org.maxkey.crypto.password.opt;
public class OneTimePassword {
private String id;
private int type;
private String token;
private String username;
private String receiver;
private String createTime;
/**
* @return the id
*/
public String getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* @return the token
*/
public String getToken() {
return token;
}
/**
* @param token the token to set
*/
public void setToken(String token) {
this.token = token;
}
/**
* @return the username
*/
public String getUsername() {
return username;
}
/**
* @param username the username to set
*/
public void setUsername(String username) {
this.username = username;
}
/**
* @return the receiver
*/
public String getReceiver() {
return receiver;
}
/**
* @param receiver the receiver to set
*/
public void setReceiver(String receiver) {
this.receiver = receiver;
}
/**
* @return the createTime
*/
public String getCreateTime() {
return createTime;
}
/**
* @param createTime the createTime to set
*/
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
/**
*
*/
public OneTimePassword() {
private String id;
private int type;
private String token;
private String username;
private String receiver;
private String createTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("OneTimePassword [id=").append(id)
.append(", type=").append(type).append(", token=").append(token)
.append(", username=").append(username).append(", receiver=").append(receiver)
.append(", createTime=").append(createTime).append("]");
return builder.toString();
}
}
/**
* @return the type
*/
public int getType() {
return type;
}
/**
* @param type the type to set
*/
public void setType(int type) {
this.type = type;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "OneTimePassword [id=" + id + ", token=" + token + ", username="
+ username + ", receiver=" + receiver + ", createTime="
+ createTime + "]";
}
}
package org.maxkey.crypto.password.opt.algorithm;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
/**
* IETF RFC 4226 http://tools.ietf.org/html/rfc4226
* HOTP Include HmacOTP's implement
* same as HmacOTP's, when addChecksum = false & truncationOffset = -1
* IETF RFC 4226 http://tools.ietf.org/html/rfc4226 HOTP Include HmacOTP's
* implement same as HmacOTP's, when addChecksum = false & truncationOffset = -1
*
* @author Crystal.Sea
*
*/
public class HOTP {
// These are used to calculate the check-sum digits.
// 0 1 2 3 4 5 6 7 8 9
// These are used to calculate the check-sum digits.
// 0 1 2 3 4 5 6 7 8 9
private static final int[] doubleDigits = { 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 };
/**
* Calculates the checksum using the credit card algorithm.
* This algorithm has the advantage that it detects any single
* mistyped digit and any single transposition of
* adjacent digits.
* Calculates the checksum using the credit card algorithm. This algorithm has
* the advantage that it detects any single mistyped digit and any single
* transposition of adjacent digits.
*
* @param num the number to calculate the checksum for
* @param num the number to calculate the checksum for
* @param digits number of significant places in the number
*
* @return the checksum of num
*/
public static int calcChecksum(long num, int digits) {
boolean doubleDigit = true;
int total = 0;
int total = 0;
while (0 < digits--) {
int digit = (int) (num % 10);
num /= 10;
......@@ -48,124 +47,107 @@ public class HOTP {
}
/**
* This method uses the JCE to provide the HMAC-SHA-1
* * algorithm.
* HMAC computes a Hashed Message Authentication Code and
* in this case SHA1 is the hash algorithm used.
*
* @param keyBytes the bytes to use for the HMAC-SHA-1 key
* @param text the message or text to be authenticated.
*
* @throws NoSuchAlgorithmException if no provider makes
* either HmacSHA1 or HMAC-SHA-1
* digest algorithms available.
* @throws InvalidKeyException
* The secret provided was not a valid HMAC-SHA-1 key.
*
*/
public static byte[] hmac_sha1(byte[] keyBytes, byte[] text)
throws NoSuchAlgorithmException, InvalidKeyException
{
// try {
Mac hmacSha1;
try {
hmacSha1 = Mac.getInstance("HmacSHA1");
} catch (NoSuchAlgorithmException nsae) {
hmacSha1 = Mac.getInstance("HMAC-SHA-1");
}
SecretKeySpec macKey =
new SecretKeySpec(keyBytes, "RAW");
hmacSha1.init(macKey);
return hmacSha1.doFinal(text);
// } catch (GeneralSecurityException gse) {
// throw new UndeclaredThrowableException(gse);
// }
}
private static final int[] DIGITS_POWER
// 0 1 2 3 4 5 6 7 8
= {1,10,100,1000,10000,100000,1000000,10000000,100000000};
* This method uses the JCE to provide the HMAC-SHA-1 * algorithm. HMAC computes
* a Hashed Message Authentication Code and in this case SHA1 is the hash
* algorithm used.
*
* @param keyBytes the bytes to use for the HMAC-SHA-1 key
* @param text the message or text to be authenticated.
*
* @throws NoSuchAlgorithmException if no provider makes either HmacSHA1 or
* HMAC-SHA-1 digest algorithms available.
* @throws InvalidKeyException The secret provided was not a valid
* HMAC-SHA-1 key.
*
*/
/**
* This method generates an OTP value for the given
* set of parameters.
*
* @param secret the shared secret
* @param movingFactor the counter, time, or other value that
* changes on a per use basis.
* @param codeDigits the number of digits in the OTP, not
* including the checksum, if any.
* @param addChecksum a flag that indicates if a checksum digit
public static byte[] hmac_sha1(byte[]
keyBytes, byte[] text) throws NoSuchAlgorithmException, InvalidKeyException {
// try {
Mac hmacSha1;
try {
hmacSha1 = Mac.getInstance("HmacSHA1");
} catch (NoSuchAlgorithmException nsae) {
hmacSha1 = Mac.getInstance("HMAC-SHA-1");
}
SecretKeySpec macKey = new SecretKeySpec(keyBytes, "RAW");
hmacSha1.init(macKey);
return hmacSha1.doFinal(text);
// } catch (GeneralSecurityException gse) {
// throw new UndeclaredThrowableException(gse);
// }
}
// 0 1 2 3 4 5 6 7 8
private static final int[] DIGITS_POWER
= { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
/**
* This method generates an OTP value for the given set of parameters.
*
* @param secret the shared secret
* @param movingFactor the counter, time, or other value that changes on a
* per use basis.
* @param codeDigits the number of digits in the OTP, not including the
* checksum, if any.
* @param addChecksum a flag that indicates if a checksum digit
*
*
*
* M'Raihi, et al. Informational [Page 29]
*
* RFC 4226 HOTP Algorithm December 2005
*
*
* should be appended to the OTP.
* @param truncationOffset the offset into the MAC result to begin truncation.
* If this value is out of the range of 0 ... 15, then
* dynamic truncation will be used. Dynamic truncation
* is when the last 4 bits of the last byte of the MAC
* are used to determine the start offset.
* @return A numeric String in base 10 that includes {@link codeDigits} digits
* @throws NoSuchAlgorithmException if no provider makes either HmacSHA1 or
* HMAC-SHA-1 digest algorithms available.
* @throws InvalidKeyException The secret provided was not a valid
* HMAC-SHA-1 key.
*
* plus the optional checksum digit if requested.
*/
public static String generateOTP(byte[]
secret, long movingFactor, int codeDigits, boolean addChecksum,
int truncationOffset) throws NoSuchAlgorithmException, InvalidKeyException {
// put movingFactor value into text byte array
String result = null;
final int digits = addChecksum ? (codeDigits + 1) : codeDigits;
byte[] text = new byte[8];
for (int i = text.length - 1; i >= 0; i--) {
text[i] = (byte) (movingFactor & 0xff);
movingFactor >>= 8;
}
M'Raihi, et al. Informational [Page 29]
RFC 4226 HOTP Algorithm December 2005
// compute hmac hash
byte[] hash = hmac_sha1(secret, text);
// put selected bytes into result int
int offset = hash[hash.length - 1] & 0xf;
* should be appended to the OTP.
* @param truncationOffset the offset into the MAC result to
* begin truncation. If this value is out of
* the range of 0 ... 15, then dynamic
* truncation will be used.
* Dynamic truncation is when the last 4
* bits of the last byte of the MAC are
* used to determine the start offset.
* @throws NoSuchAlgorithmException if no provider makes
* either HmacSHA1 or HMAC-SHA-1
* digest algorithms available.
* @throws InvalidKeyException
* The secret provided was not
* a valid HMAC-SHA-1 key.
*
* @return A numeric String in base 10 that includes
* {@link codeDigits} digits plus the optional checksum
* digit if requested.
*/
static public String generateOTP(byte[] secret,
long movingFactor,
int codeDigits,
boolean addChecksum,
int truncationOffset)
throws NoSuchAlgorithmException, InvalidKeyException{
// put movingFactor value into text byte array
String result = null;
int digits = addChecksum ? (codeDigits + 1) : codeDigits;
byte[] text = new byte[8];
for (int i = text.length - 1; i >= 0; i--) {
text[i] = (byte) (movingFactor & 0xff);
movingFactor >>= 8;
}
if ((0 <= truncationOffset) && (truncationOffset < (hash.length - 4))) {
offset = truncationOffset;
}
// compute hmac hash
byte[] hash = hmac_sha1(secret, text);
int binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16)
| ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff);
// put selected bytes into result int
int offset = hash[hash.length - 1] & 0xf;
if ( (0<=truncationOffset) &&
(truncationOffset<(hash.length-4)) ) {
offset = truncationOffset;
}
int binary =
((hash[offset] & 0x7f) << 24)
| ((hash[offset + 1] & 0xff) << 16)
| ((hash[offset + 2] & 0xff) << 8)
| (hash[offset + 3] & 0xff);
int otp = binary % DIGITS_POWER[codeDigits];
if (addChecksum) {
otp = (otp * 10) + calcChecksum(otp, codeDigits);
}
result = Integer.toString(otp);
while (result.length() < digits) {
result = "0" + result;
}
return result;
}
int otp = binary % DIGITS_POWER[codeDigits];
if (addChecksum) {
otp = (otp * 10) + calcChecksum(otp, codeDigits);
}
result = Integer.toString(otp);
while (result.length() < digits) {
result = "0" + result;
}
return result;
}
}
package org.maxkey.crypto.password.opt.algorithm;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* same as HOTP,but addChecksum = false & truncationOffset = -1
* same as HOTP,but addChecksum = false & truncationOffset = -1.
*
* @author Crystal.Sea
*
*/
public class HmacOTP {
private final static Logger logger = LoggerFactory.getLogger(HmacOTP.class);
public static String gen(byte[] seed, int count, int digits){
try{
return generateOTP(seed, count, digits);
} catch (InvalidKeyException e){
e.printStackTrace();
LoggerFactory.getLogger(HmacOTP.class).error(e.getMessage());
} catch (NoSuchAlgorithmException e){
e.printStackTrace();
LoggerFactory.getLogger(HmacOTP.class).error(e.getMessage());
}
return "";
}
private static final Logger logger = LoggerFactory.getLogger(HmacOTP.class);
/**
* gen.
* @param seed byte
* @param count int
* @param digits int
* @return
*/
public static String gen(byte[] seed, int count, int digits) {
try {
return generateOTP(seed, count, digits);
} catch (InvalidKeyException e) {
e.printStackTrace();
LoggerFactory.getLogger(HmacOTP.class).error(e.getMessage());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
LoggerFactory.getLogger(HmacOTP.class).error(e.getMessage());
}
return "";
}
/**
* @param keyBytes
* @param text
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*/
public static byte[] hmac_sha1(byte[] keyBytes, byte[] text)
throws NoSuchAlgorithmException, InvalidKeyException {
Mac hmacSha1;
try {
hmacSha1 = Mac.getInstance("HmacSHA1");
} catch (NoSuchAlgorithmException nsae) {
hmacSha1 = Mac.getInstance("HMAC-SHA-1");
}
SecretKeySpec macKey = new SecretKeySpec(keyBytes, "RAW");
hmacSha1.init(macKey);
return hmacSha1.doFinal(text);
}
/**
* @param secret
* @param movingFactor
* @param codeDigits
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*/
static private String generateOTP(byte[] secret,
long movingFactor, int codeDigits)
throws NoSuchAlgorithmException, InvalidKeyException {
// put movingFactor value into text byte array
String result = null;
byte[] text = new byte[8];
for (int i = text.length - 1; i >= 0; i--) {
text[i] = (byte) (movingFactor & 0xff);
movingFactor >>= 8;
}
// compute hmac hash
byte[] hash = hmac_sha1(secret, text);
public static byte[] hmac_sha1(byte[] keyBytes, byte[] text)
throws NoSuchAlgorithmException, InvalidKeyException{
Mac hmacSha1;
try {
hmacSha1 = Mac.getInstance("HmacSHA1");
} catch (NoSuchAlgorithmException nsae) {
hmacSha1 = Mac.getInstance("HMAC-SHA-1");
}
SecretKeySpec macKey = new SecretKeySpec(keyBytes, "RAW");
hmacSha1.init(macKey);
return hmacSha1.doFinal(text);
}
// put selected bytes into result int
int offset = hash[hash.length - 1] & 0xf;
static private String generateOTP(byte[] secret, long movingFactor,
int codeDigits) throws NoSuchAlgorithmException,
InvalidKeyException{
// put movingFactor value into text byte array
String result = null;
byte[] text = new byte[8];
for (int i = text.length - 1; i >= 0; i--){
text[i] = (byte) (movingFactor & 0xff);
movingFactor >>= 8;
}
int binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16)
| ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff);
// compute hmac hash
byte[] hash = hmac_sha1(secret, text);
int otp = (int) (binary % Math.pow(10, codeDigits));
// int otp = binary % DIGITS_POWER[codeDigits];
result = Integer.toString(otp);
// put selected bytes into result int
int offset = hash[hash.length - 1] & 0xf;
int binary = ((hash[offset] & 0x7f) << 24)
| ((hash[offset + 1] & 0xff) << 16)
| ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff);
while (result.length() < codeDigits) {
result = "0" + result;
}
return result;
}
int otp = (int) (binary % Math.pow(10, codeDigits));
//int otp = binary % DIGITS_POWER[codeDigits];
result = Integer.toString(otp);
while (result.length() < codeDigits){
result = "0" + result;
}
return result;
}
}
package org.maxkey.crypto.password.opt.algorithm;
public class KeyUriFormat {
public class Types{
public static final String HOTP = "hotp";
public static final String TOTP = "totp";
}
String crypto = "HmacSHA1";
String type;
String secret;
String issuer;
String domain;
int digits = 6;
//just for hotp
Long counter = 0L;
//just for totp
int period = 30;
String account;
/**
*
*/
public KeyUriFormat() {
}
/**
* @param type
* @param secret
*/
public KeyUriFormat(String type, String secret) {
this.type = type;
this.secret = secret;
}
/**
* @param type
* @param secret
* @param issuer
*/
public KeyUriFormat(String type, String secret, String issuer) {
this.type = type;
this.secret = secret;
this.issuer = issuer;
}
/**
* @return the type
*/
public String getType() {
return type;
}
/**
* @param type the type to set
*/
public void setType(String type) {
this.type = type;
}
/**
* @return the secret
*/
public String getSecret() {
return secret;
}
/**
* @param secret the secret to set
*/
public void setSecret(String secret) {
this.secret = secret;
}
/**
* @return the issuer
*/
public String getIssuer() {
return issuer;
}
/**
* @param issuer the issuer to set
*/
public void setIssuer(String issuer) {
this.issuer = issuer;
}
/**
* @return the digits
*/
public int getDigits() {
return digits;
}
/**
* @param digits the digits to set
*/
public void setDigits(int digits) {
this.digits = digits;
}
/**
* @return the counter
*/
public Long getCounter() {
return counter;
}
/**
* @param counter the counter to set
*/
public void setCounter(Long counter) {
this.counter = counter;
}
/**
* @return the period
*/
public int getPeriod() {
return period;
}
/**
* @param period the period to set
*/
public void setPeriod(int period) {
this.period = period;
}
/**
* @return the account
*/
public String getAccount() {
return account;
}
/**
* @param account the account to set
*/
public void setAccount(String account) {
this.account = account;
}
/**
* @return the crypto
*/
public String getCrypto() {
return crypto;
}
/**
* @param crypto the crypto to set
*/
public void setCrypto(String crypto) {
this.crypto = crypto;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
public String format(){
return format(this.account);
}
public String format(String account){
StringBuffer uri=new StringBuffer("otpauth://");
uri.append(type).append("/");
if(null!=this.domain){
uri.append(this.domain).append("/").append(account);
}else{
uri.append(account);
}
uri.append("?secret=").append(secret);
if(null!=issuer){
uri.append("&issuer=").append(issuer);
}
if(digits!=6){
uri.append("&digits=").append(digits);
}
if(type.equalsIgnoreCase(Types.TOTP)&&period!=30){
uri.append("&period=").append(period);
}
if(type.equalsIgnoreCase(Types.HOTP)){
uri.append("&counter=").append(counter);
}
return uri.toString();
}
public class Types {
public static final String HOTP = "hotp";
public static final String TOTP = "totp";
}
String crypto = "HmacSHA1";
String type;
String secret;
String issuer;
String domain;
int digits = 6;
// just for hotp
Long counter = 0L;
// just for totp
int period = 30;
String account;
public KeyUriFormat() {
}
/**
* @param type
* @param secret
*/
public KeyUriFormat(String type, String secret) {
this.type = type;
this.secret = secret;
}
/**
* @param type
* @param secret
* @param issuer
*/
public KeyUriFormat(String type, String secret, String issuer) {
this.type = type;
this.secret = secret;
this.issuer = issuer;
}
/**
* @return the type
*/
public String getType() {
return type;
}
/**
* @param type the type to set
*/
public void setType(String type) {
this.type = type;
}
/**
* @return the secret
*/
public String getSecret() {
return secret;
}
/**
* @param secret the secret to set
*/
public void setSecret(String secret) {
this.secret = secret;
}
/**
* @return the issuer
*/
public String getIssuer() {
return issuer;
}
/**
* @param issuer the issuer to set
*/
public void setIssuer(String issuer) {
this.issuer = issuer;
}
/**
* @return the digits
*/
public int getDigits() {
return digits;
}
/**
* @param digits the digits to set
*/
public void setDigits(int digits) {
this.digits = digits;
}
/**
* @return the counter
*/
public Long getCounter() {
return counter;
}
/**
* @param counter the counter to set
*/
public void setCounter(Long counter) {
this.counter = counter;
}
/**
* @return the period
*/
public int getPeriod() {
return period;
}
/**
* @param period the period to set
*/
public void setPeriod(int period) {
this.period = period;
}
/**
* @return the account
*/
public String getAccount() {
return account;
}
/**
* @param account the account to set
*/
public void setAccount(String account) {
this.account = account;
}
/**
* @return the crypto
*/
public String getCrypto() {
return crypto;
}
/**
* @param crypto the crypto to set
*/
public void setCrypto(String crypto) {
this.crypto = crypto;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
public String format() {
return format(this.account);
}
/**
* format account.
* @param account String
* @return
*/
public String format(String account) {
StringBuffer uri = new StringBuffer("otpauth://");
uri.append(type).append("/");
if (null != this.domain) {
uri.append(this.domain).append("/").append(account);
} else {
uri.append(account);
}
uri.append("?secret=").append(secret);
if (null != issuer) {
uri.append("&issuer=").append(issuer);
}
if (digits != 6) {
uri.append("&digits=").append(digits);
}
if (type.equalsIgnoreCase(Types.TOTP) && period != 30) {
uri.append("&period=").append(period);
}
if (type.equalsIgnoreCase(Types.HOTP)) {
uri.append("&counter=").append(counter);
}
return uri.toString();
}
}
package org.maxkey.crypto.password.opt.algorithm;
import java.util.Arrays;
import java.util.Random;
public class OTPSecret {
private static final Random rand = new Random();
/**
* Seed for HMAC-SHA1 - 20 bytes
* Generates random 20 bytes long TOTP Secret
*
* @return generated secret
*/
public static final byte[] generate() {
int size = 20;
byte[] b = new byte[size];
rand.nextBytes(b);
return Arrays.copyOf(b, size);
}
/**
* Seed by crypto
*
* @return generated secret
*/
public static final byte[] generate(String crypto) {
if(crypto.equalsIgnoreCase("HmacSHA1")||crypto.equalsIgnoreCase("HMAC-SHA-1")){
return generate();
}if(crypto.equalsIgnoreCase("HmacSHA256")||crypto.equalsIgnoreCase("HMAC-SHA-256")){
return generate32();
}if(crypto.equalsIgnoreCase("HmacSHA512")||crypto.equalsIgnoreCase("HMAC-SHA-512")){
return generate64();
}
return generate();
}
/**
* Seed for HMAC-SHA256 - 32 bytes
* Generates random 32 bytes long TOTP Secret
*
* @return generated secret
*/
public static final byte[] generate32() {
int size = 32;
byte[] b = new byte[size];
rand.nextBytes(b);
return Arrays.copyOf(b, size);
}
/**
* Seed forHMAC-SHA512 - 64 bytes
* Generates random 64 bytes long TOTP Secret
*
* @return generated secret
*/
public static final byte[] generate64() {
int size = 64;
byte[] b = new byte[size];
rand.nextBytes(b);
return Arrays.copyOf(b, size);
}
}
package org.maxkey.crypto.password.opt.algorithm;
import java.util.Arrays;
import java.util.Random;
public class OtpSecret {
private static final Random rand = new Random();
/**
* Seed for HMAC-SHA1 - 20 bytes Generates random 20 bytes long TOTP Secret.
*
* @return generated secret
*/
public static final byte[] generate() {
int size = 20;
byte[] b = new byte[size];
rand.nextBytes(b);
return Arrays.copyOf(b, size);
}
/**
* Seed by crypto.
*
* @return generated secret
*/
public static final byte[] generate(String crypto) {
if (crypto.equalsIgnoreCase("HmacSHA1") || crypto.equalsIgnoreCase("HMAC-SHA-1")) {
return generate();
}
if (crypto.equalsIgnoreCase("HmacSHA256") || crypto.equalsIgnoreCase("HMAC-SHA-256")) {
return generate32();
}
if (crypto.equalsIgnoreCase("HmacSHA512") || crypto.equalsIgnoreCase("HMAC-SHA-512")) {
return generate64();
}
return generate();
}
/**
* Seed for HMAC-SHA256 - 32 bytes Generates random 32 bytes long TOTP Secret.
*
* @return generated secret
*/
public static final byte[] generate32() {
int size = 32;
byte[] b = new byte[size];
rand.nextBytes(b);
return Arrays.copyOf(b, size);
}
/**
* Seed forHMAC-SHA512 - 64 bytes Generates random 64 bytes long TOTP Secret.
*
* @return generated secret
*/
public static final byte[] generate64() {
int size = 64;
byte[] b = new byte[size];
rand.nextBytes(b);
return Arrays.copyOf(b, size);
}
}
......@@ -7,214 +7,199 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class TimeBasedOTP {
// 0 1 2 3 4 5 6 7 8
private static final int[] DIGITS_POWER
// 0 1 2 3 4 5 6 7 8
= {1,10,100,1000,10000,100000,1000000,10000000,100000000 };
static String seed64 = "";
static String steps = "0";
static String steps2 = "0";
TimeBasedOTP() {
}
/**
* This method uses the JCE to provide the crypto algorithm.
* HMAC computes a Hashed Message Authentication Code with the
* crypto hash algorithm as a parameter.
*
* @param crypto: the crypto algorithm (HmacSHA1, HmacSHA256,
* HmacSHA512)
* @param keyBytes: the bytes to use for the HMAC key
* @param text: the message or text to be authenticated
*/
private static byte[] hmac_sha(String crypto, byte[] keyBytes,
byte[] text){
try {
Mac hmac;
hmac = Mac.getInstance(crypto);
SecretKeySpec macKey =
new SecretKeySpec(keyBytes, "RAW");
hmac.init(macKey);
return hmac.doFinal(text);
} catch (GeneralSecurityException gse) {
throw new UndeclaredThrowableException(gse);
}
}
/**
* This method converts a HEX string to Byte[]
*
* @param hex: the HEX string
*
* @return: a byte array
*/
private static byte[] hexStr2Bytes(String hex){
// Adding one byte to get the right conversion
// Values starting with "0" can be converted
byte[] bArray = new BigInteger("10" + hex,16).toByteArray();
// Copy all the REAL bytes, not the "first"
byte[] ret = new byte[bArray.length - 1];
for (int i = 0; i < ret.length; i++)
ret[i] = bArray[i+1];
return ret;
}
/**
* This method generates a OTP value for the given
* set of parameters.
* Default Crypto HmacSHA512
* @param key: the shared secret, HEX encoded
* @param time: a value that reflects a time
* @param returnDigits: number of digits to return
*
* @return: a numeric String in base 10 that includes
* {@link truncationDigits} digits
*/
public static String genOTP(String key,
String time,
String returnDigits){
return generateOTP(key, time, returnDigits, "HmacSHA1");
}
/* * This method generates a OTP value for the given
* set of parameters.
* Crypto HmacSHA1
* @param key
* @param time
* @param returnDigits
* @return
*/
public static String generateTOTPHmacSHA1(String key,
String time,
String returnDigits){
return generateOTP(key, time, returnDigits, "HmacSHA1");
}
/* * This method generates a OTP value for the given
* set of parameters.
* Crypto HmacSHA256
* @param key: the shared secret, HEX encoded
* @param time: a value that reflects a time
* @param returnDigits: number of digits to return
*
* @return: a numeric String in base 10 that includes
* {@link truncationDigits} digits
*/
public static String genOTPHmacSHA256(String key,
String time,
String returnDigits){
return generateOTP(key, time, returnDigits, "HmacSHA256");
}
/* *
* This method generates a OTP value for the given
* set of parameters.
* Crypto HmacSHA256
* @param key: the shared secret, HEX encoded
* @param time: a value that reflects a time
* @param returnDigits: number of digits to return
*
* @return: a numeric String in base 10 that includes
* {@link truncationDigits} digits
*/
public static String genOTPHmacSHA512(String key,
String time,
String returnDigits){
return generateOTP(key, time, returnDigits, "HmacSHA512");
}
/**
* This method generates a TOTP value for the given
* set of parameters.
*
* @param key: the shared secret, HEX encoded
* @param time: a value that reflects a time
* @param returnDigits: number of digits to return
* @param crypto: the crypto function to use
*
* @return: a numeric String in base 10 that includes
* {@link truncationDigits} digits
*/
public static void actualiseTime(){
= { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
static String seed64 = "";
static String steps = "0";
static String steps2 = "0";
TimeBasedOTP() {
}
/**
* This method uses the JCE to provide the crypto algorithm. HMAC computes a
* Hashed Message Authentication Code with the crypto hash algorithm as a
* parameter.
*
* @param crypto the crypto algorithm (HmacSHA1, HmacSHA256, HmacSHA512)
* @param keyBytes the bytes to use for the HMAC key
* @param text the message or text to be authenticated
*/
private static byte[] hmac_sha(String crypto, byte[] keyBytes, byte[] text) {
try {
Mac hmac;
hmac = Mac.getInstance(crypto);
SecretKeySpec macKey = new SecretKeySpec(keyBytes, "RAW");
hmac.init(macKey);
return hmac.doFinal(text);
} catch (GeneralSecurityException gse) {
throw new UndeclaredThrowableException(gse);
}
}
/**
* This method converts a HEX string to Byte[].
*
* @param hex the HEX string
*
* @return: a byte array
*/
private static byte[] hexStr2Bytes(String hex) {
// Adding one byte to get the right conversion
// Values starting with "0" can be converted
byte[] bArray = new BigInteger("10" + hex, 16).toByteArray();
// Copy all the REAL bytes, not the "first"
byte[] ret = new byte[bArray.length - 1];
for (int i = 0; i < ret.length; i++) {
ret[i] = bArray[i + 1];
}
return ret;
}
/**
* This method generates a OTP value for the given set of parameters. Default
* Crypto HmacSHA512
*
* @param key the shared secret, HEX encoded
* @param time a value that reflects a time
* @param returnDigits number of digits to return
*
* @return: a numeric String in base 10 that includes {@link truncationDigits}
* digits
*/
public static String genOTP(String key, String time, String returnDigits) {
return generateOTP(key, time, returnDigits, "HmacSHA1");
}
/*
* * This method generates a OTP value for the given set of parameters. Crypto
* HmacSHA1
*
* @param key
*
* @param time
*
* @param returnDigits
*
* @return
*/
public static String generateTOTPHmacSHA1(String key, String time, String returnDigits) {
return generateOTP(key, time, returnDigits, "HmacSHA1");
}
/*
* * This method generates a OTP value for the given set of parameters. Crypto
* HmacSHA256
*
* @param key: the shared secret, HEX encoded
*
* @param time: a value that reflects a time
*
* @param returnDigits: number of digits to return
*
* @return: a numeric String in base 10 that includes {@link truncationDigits}
* digits
*/
public static String genOTPHmacSHA256(String key, String time, String returnDigits) {
return generateOTP(key, time, returnDigits, "HmacSHA256");
}
/*
* * This method generates a OTP value for the given set of parameters. Crypto
* HmacSHA256
*
* @param key: the shared secret, HEX encoded
*
* @param time: a value that reflects a time
*
* @param returnDigits: number of digits to return
*
* @return: a numeric String in base 10 that includes {@link truncationDigits}
* digits
*/
public static String genOTPHmacSHA512(String key, String time, String returnDigits) {
return generateOTP(key, time, returnDigits, "HmacSHA512");
}
/**
* This method generates a TOTP value for the given set of parameters.
*/
public static void actualiseTime() {
// double random = Math.random();
long T0 = 0;
long X = 30;
Date d = new Date();
Long k = d.getTime()/1000;
long testTime[] = {d.getTime()};
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
for (int i=0; i<testTime.length; i++) {
long T = (k - T0)/X;
long T2 = ((k - T0)/X)-1;
// System.out.println(T);
steps = Long.toHexString(T).toUpperCase();
steps2 = Long.toHexString(T2).toUpperCase();
while (steps.length() < 16) steps = "0" + steps;
//String fmtTime = String.format("%1$-11s", k/1000);
//String utcTime = df.format(new Date(testTime[i]));
}
}
public static String generateOTP(String key,
String time,
String returnDigits,
String crypto){
int codeDigits = Integer.decode(returnDigits).intValue();
String result = null;
// Using the counter
// First 8 bytes are for the movingFactor
// Compliant with base RFC 4226 (HOTP)
while (time.length() < 16 )
time = "0" + time;
// Get the HEX in a Byte[]
byte[] msg = hexStr2Bytes(time);
byte[] k = hexStr2Bytes(key);
byte[] hash = hmac_sha(crypto, k, msg);
// put selected bytes into result int
int offset = hash[hash.length - 1] & 0xf;
int binary =
((hash[offset] & 0x7f) << 24) |
((hash[offset + 1] & 0xff) << 16) |
((hash[offset + 2] & 0xff) << 8) |
(hash[offset + 3] & 0xff);
int otp = binary % DIGITS_POWER[codeDigits];
result = Integer.toString(otp);
while (result.length() < codeDigits) {
result = "0" + result;
}
return result;
}
long T0 = 0;
long X = 30;
Date d = new Date();
Long k = d.getTime() / 1000;
long testTime[] = { d.getTime() };
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
for (int i = 0; i < testTime.length; i++) {
long T = (k - T0) / X;
long T2 = ((k - T0) / X) - 1;
// System.out.println(T);
steps = Long.toHexString(T).toUpperCase();
steps2 = Long.toHexString(T2).toUpperCase();
while (steps.length() < 16) {
steps = "0" + steps;
}
//String fmtTime = String.format("%1$-11s", k/1000);
//String utcTime = df.format(new Date(testTime[i]));
}
}
/**
* generateOTP.
* @param key String
* @param time String
* @param returnDigits String
* @param crypto String
* @return
*/
public static String generateOTP(String key, String time, String returnDigits, String crypto) {
int codeDigits = Integer.decode(returnDigits).intValue();
String result = null;
// Using the counter
// First 8 bytes are for the movingFactor
// Compliant with base RFC 4226 (HOTP)
while (time.length() < 16) {
time = "0" + time;
}
// Get the HEX in a Byte[]
byte[] msg = hexStr2Bytes(time);
byte[] k = hexStr2Bytes(key);
byte[] hash = hmac_sha(crypto, k, msg);
// put selected bytes into result int
int offset = hash[hash.length - 1] & 0xf;
int binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16)
| ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff);
int otp = binary % DIGITS_POWER[codeDigits];
result = Integer.toString(otp);
while (result.length() < codeDigits) {
result = "0" + result;
}
return result;
}
}
\ No newline at end of file
/**
*
*/
/**
* @author Administrator
*
*/
package org.maxkey.crypto.password.opt.algorithm;
\ No newline at end of file
package org.maxkey.crypto.password.opt.impl;
import org.maxkey.crypto.password.opt.AbstractOTPAuthn;
import org.maxkey.domain.UserInfo;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* Chip Authentication Program
* EMV stands for Europay, MasterCard and Visa,
* a global standard for inter-operation of integrated circuit cards (IC cards or "chip cards")
* and IC card capable point of sale (POS) terminals and automated teller machines (ATMs),
* for authenticating credit and debit card transactions.
*
* @author Crystal.Sea
*
*/
public class CAPOTPAuthn extends AbstractOTPAuthn {
public CAPOTPAuthn(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public boolean produce(UserInfo userInfo) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean validate(UserInfo userInfo,String token) {
// TODO Auto-generated method stub
return false;
}
}
package org.maxkey.crypto.password.opt.impl;
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
import org.maxkey.domain.UserInfo;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* Chip Authentication Program EMV stands for Europay, MasterCard and Visa, a
* global standard for inter-operation of integrated circuit cards (IC cards or
* "chip cards") and IC card capable point of sale (POS) terminals and automated
* teller machines (ATMs), for authenticating credit and debit card
* transactions.
*
* @author Crystal.Sea
*
*/
public class CapOtpAuthn extends AbstractOptAuthn {
public CapOtpAuthn(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public boolean produce(UserInfo userInfo) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean validate(UserInfo userInfo, String token) {
// TODO Auto-generated method stub
return false;
}
}
package org.maxkey.crypto.password.opt.impl;
import org.apache.commons.codec.binary.Hex;
import org.maxkey.crypto.Base32Utils;
import org.maxkey.crypto.password.opt.AbstractOTPAuthn;
import org.maxkey.crypto.password.opt.algorithm.TimeBasedOTP;
import org.maxkey.domain.UserInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
public class CounterBasedOTPAuthn extends AbstractOTPAuthn {
private final static Logger _logger = LoggerFactory.getLogger(CounterBasedOTPAuthn.class);
public CounterBasedOTPAuthn(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public boolean produce(UserInfo userInfo) {
return true;
}
@Override
public boolean validate(UserInfo userInfo,String token) {
_logger.debug("SharedCounter : "+userInfo.getSharedCounter());
byte[]byteSharedSecret= Base32Utils.decode(userInfo.getSharedSecret());
String hexSharedSecret=Hex.encodeHexString(byteSharedSecret);
String counterBasedToken="";
if(crypto.equalsIgnoreCase("HmacSHA1")){
counterBasedToken=TimeBasedOTP.genOTP(hexSharedSecret,userInfo.getSharedCounter(),""+digits);
}else if(crypto.equalsIgnoreCase("HmacSHA256")){
counterBasedToken=TimeBasedOTP.genOTPHmacSHA256(hexSharedSecret,userInfo.getSharedCounter(),""+digits);
}else if(crypto.equalsIgnoreCase("HmacSHA512")){
counterBasedToken=TimeBasedOTP.genOTPHmacSHA512(hexSharedSecret,userInfo.getSharedCounter(),""+digits);
}
_logger.debug("token : "+token);
_logger.debug("counterBasedToken : "+counterBasedToken);
if(token.equalsIgnoreCase(counterBasedToken)){
return true;
}
return false;
}
}
package org.maxkey.crypto.password.opt.impl;
import org.apache.commons.codec.binary.Hex;
import org.maxkey.crypto.Base32Utils;
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
import org.maxkey.crypto.password.opt.algorithm.TimeBasedOTP;
import org.maxkey.domain.UserInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
public class CounterBasedOtpAuthn extends AbstractOptAuthn {
private static final Logger _logger = LoggerFactory.getLogger(CounterBasedOtpAuthn.class);
public CounterBasedOtpAuthn(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public boolean produce(UserInfo userInfo) {
return true;
}
@Override
public boolean validate(UserInfo userInfo, String token) {
_logger.debug("SharedCounter : " + userInfo.getSharedCounter());
byte[] byteSharedSecret = Base32Utils.decode(userInfo.getSharedSecret());
String hexSharedSecret = Hex.encodeHexString(byteSharedSecret);
String counterBasedToken = "";
if (crypto.equalsIgnoreCase("HmacSHA1")) {
counterBasedToken = TimeBasedOTP.genOTP(
hexSharedSecret,
userInfo.getSharedCounter(),
"" + digits
);
} else if (crypto.equalsIgnoreCase("HmacSHA256")) {
counterBasedToken = TimeBasedOTP.genOTPHmacSHA256(
hexSharedSecret,
userInfo.getSharedCounter(),
"" + digits
);
} else if (crypto.equalsIgnoreCase("HmacSHA512")) {
counterBasedToken = TimeBasedOTP.genOTPHmacSHA512(
hexSharedSecret,
userInfo.getSharedCounter(),
"" + digits
);
}
_logger.debug("token : " + token);
_logger.debug("counterBasedToken : " + counterBasedToken);
if (token.equalsIgnoreCase(counterBasedToken)) {
return true;
}
return false;
}
}
package org.maxkey.crypto.password.opt.impl;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import org.maxkey.crypto.Base32Utils;
import org.maxkey.crypto.password.opt.AbstractOTPAuthn;
import org.maxkey.crypto.password.opt.algorithm.HOTP;
import org.maxkey.domain.UserInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
public class HOTPOTPAuthn extends AbstractOTPAuthn {
private final static Logger _logger = LoggerFactory.getLogger(HOTPOTPAuthn.class);
boolean addChecksum;
int truncation=-1;
public HOTPOTPAuthn(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public boolean produce(UserInfo userInfo) {
return true;
}
@Override
public boolean validate(UserInfo userInfo,String token) {
_logger.debug("SharedCounter : "+userInfo.getSharedCounter());
byte[]byteSharedSecret= Base32Utils.decode(userInfo.getSharedSecret());
String hotpToken;
try {
hotpToken = HOTP.generateOTP(byteSharedSecret, Long.parseLong(userInfo.getSharedCounter()), digits, addChecksum, truncation);
_logger.debug("token : "+token);
_logger.debug("hotpToken : "+hotpToken);
if(token.equalsIgnoreCase(hotpToken)){
return true;
}
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return false;
}
/**
* @return the addChecksum
*/
public boolean isAddChecksum() {
return addChecksum;
}
/**
* @param addChecksum the addChecksum to set
*/
public void setAddChecksum(boolean addChecksum) {
this.addChecksum = addChecksum;
}
/**
* @return the truncation
*/
public int getTruncation() {
return truncation;
}
/**
* @param truncation the truncation to set
*/
public void setTruncation(int truncation) {
this.truncation = truncation;
}
}
package org.maxkey.crypto.password.opt.impl;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import org.maxkey.crypto.Base32Utils;
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
import org.maxkey.crypto.password.opt.algorithm.HOTP;
import org.maxkey.domain.UserInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
public class HotpOtpAuthn extends AbstractOptAuthn {
private static final Logger _logger = LoggerFactory.getLogger(HotpOtpAuthn.class);
boolean addChecksum;
int truncation = -1;
public HotpOtpAuthn(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public boolean produce(UserInfo userInfo) {
return true;
}
@Override
public boolean validate(UserInfo userInfo, String token) {
_logger.debug("SharedCounter : " + userInfo.getSharedCounter());
byte[] byteSharedSecret = Base32Utils.decode(userInfo.getSharedSecret());
String hotpToken;
try {
hotpToken = HOTP.generateOTP(
byteSharedSecret,
Long.parseLong(userInfo.getSharedCounter()),
digits,
addChecksum, truncation
);
_logger.debug("token : " + token);
_logger.debug("hotpToken : " + hotpToken);
if (token.equalsIgnoreCase(hotpToken)) {
return true;
}
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return false;
}
/**
* the addChecksum.
*/
public boolean isAddChecksum() {
return addChecksum;
}
/**
* addChecksum the addChecksum to set.
*/
public void setAddChecksum(boolean addChecksum) {
this.addChecksum = addChecksum;
}
/**
* the truncation.
*/
public int getTruncation() {
return truncation;
}
/**
* truncation the truncation to set.
*/
public void setTruncation(int truncation) {
this.truncation = truncation;
}
}
package org.maxkey.crypto.password.opt.impl;
import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.SimpleEmail;
import org.maxkey.config.EmailConfig;
import org.maxkey.crypto.password.opt.AbstractOTPAuthn;
import org.maxkey.domain.UserInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
public class MailOTPAuthn extends AbstractOTPAuthn {
private final static Logger _logger = LoggerFactory.getLogger(MailOTPAuthn.class);
EmailConfig emailConfig;
public MailOTPAuthn(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public boolean produce(UserInfo userInfo) {
try{
String token=this.genToken(userInfo);
Email email = new SimpleEmail();
email.setHostName(emailConfig.getSmtpHost());
email.setSmtpPort(emailConfig.getPort());
email.setAuthenticator(new DefaultAuthenticator(emailConfig.getUsername(), emailConfig.getPassword()));
email.setSSLOnConnect(emailConfig.isSsl());
email.setFrom(emailConfig.getSenderMail());
email.setSubject("One Time PassWord");
email.setMsg("You Token is "+token+" , it validity in "+(interval/60) +" minutes");
email.addTo(userInfo.getEmail());
email.send();
_logger.debug("token "+token+" send to user +"+userInfo.getUsername()+", email "+userInfo.getEmail());
this.insertDataBase(userInfo, token, userInfo.getUsername(), OPT_TYPES.EMAIL);
return true;
}catch(Exception e){
e.printStackTrace();
}
return false;
}
@Override
public boolean validate(UserInfo userInfo,String token) {
return this.validateDataBase(userInfo, token, OPT_TYPES.EMAIL);
}
/**
* @param emailConfig the emailConfig to set
*/
public void setEmailConfig(EmailConfig emailConfig) {
this.emailConfig = emailConfig;
}
}
package org.maxkey.crypto.password.opt.impl;
import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.SimpleEmail;
import org.maxkey.config.EmailConfig;
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
import org.maxkey.domain.UserInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
public class MailOtpAuthn extends AbstractOptAuthn {
private static final Logger _logger = LoggerFactory.getLogger(MailOtpAuthn.class);
EmailConfig emailConfig;
public MailOtpAuthn(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public boolean produce(UserInfo userInfo) {
try {
String token = this.genToken(userInfo);
Email email = new SimpleEmail();
email.setHostName(emailConfig.getSmtpHost());
email.setSmtpPort(emailConfig.getPort());
email.setAuthenticator(
new DefaultAuthenticator(emailConfig.getUsername(), emailConfig.getPassword()));
email.setSSLOnConnect(emailConfig.isSsl());
email.setFrom(emailConfig.getSenderMail());
email.setSubject("One Time PassWord");
email.setMsg("You Token is " + token
+ " , it validity in " + (interval / 60) + " minutes");
email.addTo(userInfo.getEmail());
email.send();
_logger.debug(
"token " + token + " send to user +" + userInfo.getUsername()
+ ", email " + userInfo.getEmail());
this.insertDataBase(userInfo, token, userInfo.getUsername(), OPT_TYPES.EMAIL);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
@Override
public boolean validate(UserInfo userInfo, String token) {
return this.validateDataBase(userInfo, token, OPT_TYPES.EMAIL);
}
public void setEmailConfig(EmailConfig emailConfig) {
this.emailConfig = emailConfig;
}
}
package org.maxkey.crypto.password.opt.impl;
import org.maxkey.crypto.password.opt.AbstractOTPAuthn;
import org.maxkey.domain.UserInfo;
import org.springframework.jdbc.core.JdbcTemplate;
public class MobileOTPAuthn extends AbstractOTPAuthn {
public MobileOTPAuthn(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public boolean produce(UserInfo userInfo) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean validate(UserInfo userInfo,String token) {
// TODO Auto-generated method stub
return false;
}
}
package org.maxkey.crypto.password.opt.impl;
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
import org.maxkey.domain.UserInfo;
import org.springframework.jdbc.core.JdbcTemplate;
public class MobileOtpAuthn extends AbstractOptAuthn {
public MobileOtpAuthn(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public boolean produce(UserInfo userInfo) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean validate(UserInfo userInfo, String token) {
// TODO Auto-generated method stub
return false;
}
}
package org.maxkey.crypto.password.opt.impl;
import org.maxkey.crypto.password.opt.AbstractOTPAuthn;
import org.maxkey.domain.UserInfo;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* Chip Authentication Program
* EMV stands for Europay, MasterCard and Visa,
* a global standard for inter-operation of integrated circuit cards (IC cards or "chip cards")
* and IC card capable point of sale (POS) terminals and automated teller machines (ATMs),
* for authenticating credit and debit card transactions.
*
* @author Crystal.Sea
*
*/
public class RSAOTPAuthn extends AbstractOTPAuthn {
public RSAOTPAuthn(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public boolean produce(UserInfo userInfo) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean validate(UserInfo userInfo,String token) {
// TODO Auto-generated method stub
return false;
}
}
package org.maxkey.crypto.password.opt.impl;
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
import org.maxkey.domain.UserInfo;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* Chip Authentication Program EMV stands for Europay, MasterCard and Visa, a
* global standard for inter-operation of integrated circuit cards (IC cards or
* "chip cards") and IC card capable point of sale (POS) terminals and automated
* teller machines (ATMs), for authenticating credit and debit card
* transactions.
*
* @author Crystal.Sea
*
*/
public class RsaOtpAuthn extends AbstractOptAuthn {
public RsaOtpAuthn(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public boolean produce(UserInfo userInfo) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean validate(UserInfo userInfo, String token) {
// TODO Auto-generated method stub
return false;
}
}
package org.maxkey.crypto.password.opt.impl;
import org.maxkey.crypto.password.opt.AbstractOTPAuthn;
import org.maxkey.domain.UserInfo;
import org.springframework.jdbc.core.JdbcTemplate;
public class SmsOTPAuthn extends AbstractOTPAuthn {
public SmsOTPAuthn(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public boolean produce(UserInfo userInfo) {
String token=this.genToken(userInfo);
//TODO:You must add send sms code here
this.insertDataBase(userInfo, token, userInfo.getUsername(), OPT_TYPES.SMS);
return true;
}
@Override
public boolean validate(UserInfo userInfo,String token) {
return this.validateDataBase(userInfo, token, OPT_TYPES.SMS);
}
}
package org.maxkey.crypto.password.opt.impl;
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
import org.maxkey.domain.UserInfo;
import org.springframework.jdbc.core.JdbcTemplate;
public class SmsOtpAuthn extends AbstractOptAuthn {
public SmsOtpAuthn(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
}
@Override
public boolean produce(UserInfo userInfo) {
String token = this.genToken(userInfo);
// TODO:You must add send sms code here
this.insertDataBase(userInfo, token, userInfo.getUsername(), OPT_TYPES.SMS);
return true;
}
@Override
public boolean validate(UserInfo userInfo, String token) {
return this.validateDataBase(userInfo, token, OPT_TYPES.SMS);
}
}
package org.maxkey.crypto.password.opt.impl;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import org.apache.commons.codec.binary.Hex;
import org.maxkey.crypto.Base32Utils;
import org.maxkey.crypto.password.opt.AbstractOTPAuthn;
import org.maxkey.crypto.password.opt.algorithm.TimeBasedOTP;
import org.maxkey.domain.UserInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
public class TimeBasedOTPAuthn extends AbstractOTPAuthn {
private final static Logger _logger = LoggerFactory.getLogger(TimeBasedOTPAuthn.class);
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public TimeBasedOTPAuthn(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
}
@Override
public boolean produce(UserInfo userInfo) {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean validate(UserInfo userInfo,String token) {
_logger.debug("utcTime : "+dateFormat.format(new Date()));
long currentTimeSeconds =System.currentTimeMillis() / 1000;
byte[]byteSharedSecret= Base32Utils.decode(userInfo.getSharedSecret());
String hexSharedSecret=Hex.encodeHexString(byteSharedSecret);
String timeBasedToken="";
if(crypto.equalsIgnoreCase("HmacSHA1")){
timeBasedToken=TimeBasedOTP.genOTP(
hexSharedSecret,
Long.toHexString(currentTimeSeconds/interval).toUpperCase()+"",
digits+"");
}else if(crypto.equalsIgnoreCase("HmacSHA256")){
timeBasedToken=TimeBasedOTP.genOTPHmacSHA256(
hexSharedSecret,
Long.toHexString(currentTimeSeconds/interval).toUpperCase()+"",
digits+"");
}else if(crypto.equalsIgnoreCase("HmacSHA512")){
timeBasedToken=TimeBasedOTP.genOTPHmacSHA512(
hexSharedSecret,
Long.toHexString(currentTimeSeconds/interval).toUpperCase()+"",
digits+"");
}
_logger.debug("token : "+token);
_logger.debug("timeBasedToken : "+timeBasedToken);
if(token.equalsIgnoreCase(timeBasedToken)){
return true;
}
return false;
}
}
package org.maxkey.crypto.password.opt.impl;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import org.apache.commons.codec.binary.Hex;
import org.maxkey.crypto.Base32Utils;
import org.maxkey.crypto.password.opt.AbstractOptAuthn;
import org.maxkey.crypto.password.opt.algorithm.TimeBasedOTP;
import org.maxkey.domain.UserInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
public class TimeBasedOtpAuthn extends AbstractOptAuthn {
private static final Logger _logger = LoggerFactory.getLogger(TimeBasedOtpAuthn.class);
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public TimeBasedOtpAuthn(JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
}
@Override
public boolean produce(UserInfo userInfo) {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean validate(UserInfo userInfo, String token) {
_logger.debug("utcTime : " + dateFormat.format(new Date()));
long currentTimeSeconds = System.currentTimeMillis() / 1000;
byte[] byteSharedSecret = Base32Utils.decode(userInfo.getSharedSecret());
String hexSharedSecret = Hex.encodeHexString(byteSharedSecret);
String timeBasedToken = "";
if (crypto.equalsIgnoreCase("HmacSHA1")) {
timeBasedToken = TimeBasedOTP.genOTP(
hexSharedSecret,
Long.toHexString(currentTimeSeconds / interval).toUpperCase() + "",
digits + "");
} else if (crypto.equalsIgnoreCase("HmacSHA256")) {
timeBasedToken = TimeBasedOTP.genOTPHmacSHA256(
hexSharedSecret,
Long.toHexString(currentTimeSeconds / interval).toUpperCase() + "",
digits + "");
} else if (crypto.equalsIgnoreCase("HmacSHA512")) {
timeBasedToken = TimeBasedOTP.genOTPHmacSHA512(
hexSharedSecret,
Long.toHexString(currentTimeSeconds / interval).toUpperCase() + "",
digits + "");
}
_logger.debug("token : " + token);
_logger.debug("timeBasedToken : " + timeBasedToken);
if (token.equalsIgnoreCase(timeBasedToken)) {
return true;
}
return false;
}
}
/**
*
*/
/**
* @author Administrator
*
*/
package org.maxkey.crypto.password.opt.impl;
\ No newline at end of file
package org.maxkey.crypto.password.opt.impl.sms;
public interface SendSms {
public String sendSms();
}
package org.maxkey.crypto.password.opt.impl.sms.netease;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.maxkey.crypto.password.opt.impl.sms.SendSms;
/**
* 网易云信的短信验证.
* @author shimingxy
*
*/
public class SendSmsYunxin implements SendSms {
//发送验证码的请求路径URL
private static final String
SERVER_URL = "https://api.netease.im/sms/sendcode.action";
//网易云信分配的账号,请替换你在管理后台应用下申请的Appkey
private static final String
APP_KEY = "94395d754eb55693043f5d6a2b772ef3";
//网易云信分配的密钥,请替换你在管理后台应用下申请的appSecret
private static final String APP_SECRET = "05d5485357bc";
// 随机数
private static final String NONCE = "123456";
// 短信模板ID
private static final String TEMPLATEID = "14850150";
// 手机号
private static final String MOBILE = "15618726256";
// 验证码长度,范围4~10,默认为4
private static final String CODELEN = "6";
/**
* .
* @param args String
* @throws Exception e
*/
public static void sendSms(String[] args) throws Exception {
HttpPost httpPost = new HttpPost(SERVER_URL);
String curTime = String.valueOf((new Date()).getTime() / 1000L);
/*
* 参考计算CheckSum的java代码,在上述文档的参数列表中,有CheckSum的计算文档示例
*/
String checkSum = SendSmsYunxinCheckSumBuilder
.getCheckSum(APP_SECRET, NONCE, curTime);
// 设置请求的header
httpPost.addHeader("AppKey", APP_KEY);
httpPost.addHeader("Nonce", NONCE);
httpPost.addHeader("CurTime", curTime);
httpPost.addHeader("CheckSum", checkSum);
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
// 设置请求的的参数,requestBody参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
/*
* 1.如果是模板短信,请注意参数mobile是有s的,详细参数配置请参考“发送模板短信文档”
* 2.参数格式是jsonArray的格式,例如 "['13888888888','13666666666']"
* 3.params是根据你模板里面有几个参数,那里面的参数也是jsonArray格式
*/
//https://api.netease.im/sms/sendcode.action
nvps.add(new BasicNameValuePair("templateid", TEMPLATEID));
nvps.add(new BasicNameValuePair("mobile", MOBILE));
nvps.add(new BasicNameValuePair("codeLen", CODELEN));
//authCode 用户自定义验证码
//nvps.add(new BasicNameValuePair("authCode", ""));
//https://api.netease.im/sms/verifycode.action
//nvps.add(new BasicNameValuePair("code", "123456"));
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
HttpClient httpClient = HttpClientBuilder.create().build();
// 执行请求
HttpResponse response = httpClient.execute(httpPost);
/*
* 1.打印执行结果,打印结果一般会200、315、403、404、413、414、500
* 2.具体的code有问题的可以参考官网的Code状态表
*/
System.out.println(EntityUtils.toString(response.getEntity(), "utf-8"));
//{"code":200,"msg":"1","obj":"740673"}
}
public static void main(String[] args) throws Exception {
sendSms(null);
}
@Override
public String sendSms() {
// TODO Auto-generated method stub
return null;
}
}
package org.maxkey.crypto.password.opt.impl.sms.netease;
import java.security.MessageDigest;
public class SendSmsYunxinCheckSumBuilder {
// 计算并获取CheckSum
public static String getCheckSum(String appSecret, String nonce, String curTime) {
return encode("sha1", appSecret + nonce + curTime);
}
// 计算并获取md5值
public static String getMD5(String requestBody) {
return encode("md5", requestBody);
}
private static String encode(String algorithm, String value) {
if (value == null) {
return null;
}
try {
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
messageDigest.update(value.getBytes());
return getFormattedText(messageDigest.digest());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static String getFormattedText(byte[] bytes) {
int len = bytes.length;
StringBuilder buf = new StringBuilder(len * 2);
for (int j = 0; j < len; j++) {
buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
}
return buf.toString();
}
private static final char[] HEX_DIGITS = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd','e', 'f' };
}
package org.maxkey.crypto.password.opt.impl.sms;
\ No newline at end of file
/**
*
*/
/**
* @author Administrator
*
*/
package org.maxkey.crypto.password.opt;
\ No newline at end of file
/**
*
*/
/**
* @author Administrator
*
*/
package org.maxkey.crypto.password;
\ No newline at end of file
......@@ -13,121 +13,105 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OpenHTTPPostDecoder extends HTTPPostDecoder {
private final Logger log = LoggerFactory.getLogger(OpenHTTPPostDecoder.class);
private String receiverEndpoint;
public OpenHTTPPostDecoder() {
super();
}
public OpenHTTPPostDecoder(ParserPool pool) {
super(pool);
}
/**
* Check the validity of the SAML protocol message receiver endpoint against
* requirements indicated in the message.
*
* @param messageContext
* current message context
*
* @throws SecurityException
* thrown if the message Destination attribute is invalid with
* respect to the receiver's endpoint
* @throws MessageDecodingException
* thrown if there is a problem decoding and processing the
* message Destination or receiver endpoint information
*/
@SuppressWarnings("rawtypes")
@Override
protected void checkEndpointURI(SAMLMessageContext messageContext)
throws SecurityException, MessageDecodingException {
log.debug("Checking SAML message intended destination endpoint against receiver endpoint");
String messageDestination = DatatypeHelper
.safeTrimOrNullString(getIntendedDestinationEndpointURI(messageContext));
boolean bindingRequires = isIntendedDestinationEndpointURIRequired(messageContext);
if (messageDestination == null) {
if (bindingRequires) {
log.error("SAML message intended destination endpoint URI required by binding was empty");
throw new SecurityException(
"SAML message intended destination (required by binding) was not present");
} else {
log.debug("SAML message intended destination endpoint in message was empty, not required by binding, skipping");
return;
}
}
String receiverEndpoint = DatatypeHelper
.safeTrimOrNullString(getActualReceiverEndpointURI(messageContext));
log.debug("Intended message destination endpoint: {}",
messageDestination);
log.debug("Actual message receiver endpoint: {}", receiverEndpoint);
// 协议头统一(http或https,需要和destination统一)
if (messageDestination.indexOf("/") != -1
&& receiverEndpoint.indexOf("/") != -1) {
if (!messageDestination.substring(0,
messageDestination.indexOf("/"))
.equalsIgnoreCase(
receiverEndpoint.substring(0,
receiverEndpoint.indexOf("/")))) {
receiverEndpoint = messageDestination.substring(0,
messageDestination.indexOf("/"))
+ receiverEndpoint.substring(receiverEndpoint
.indexOf("/"));
}
}
boolean matched = compareEndpointURIs(messageDestination,
receiverEndpoint);
if (!matched) {
log.error(
"SAML message intended destination endpoint '{}' did not match the recipient endpoint '{}'",
messageDestination, receiverEndpoint);
throw new SecurityException(
"SAML message intended destination endpoint did not match recipient endpoint");
} else {
log.debug("SAML message intended destination endpoint matched recipient endpoint");
}
}
@Override
@SuppressWarnings("rawtypes")
protected String getActualReceiverEndpointURI(
SAMLMessageContext messageContext) throws MessageDecodingException {
InTransport inTransport = messageContext.getInboundMessageTransport();
if (!(inTransport instanceof HttpServletRequestAdapter)) {
throw new MessageDecodingException(
"Message context InTransport instance was an unsupported type");
}
HttpServletRequest httpRequest = ((HttpServletRequestAdapter) inTransport)
.getWrappedRequest();
StringBuffer urlBuilder = httpRequest.getRequestURL();
String tempUrl = urlBuilder.toString();
// 从http协议头开始,跳过前面两个斜杠
tempUrl = tempUrl.substring(tempUrl.indexOf("/", 8) + 1);
return receiverEndpoint + tempUrl;
}
/**
* @param receiverEndpoint
* the receiverEndpoint to set
*/
public void setReceiverEndpoint(String receiverEndpoint) {
this.receiverEndpoint = receiverEndpoint;
}
/**
* @return the receiverEndpoint
*/
public String getReceiverEndpoint() {
return receiverEndpoint;
}
private final Logger log = LoggerFactory.getLogger(OpenHTTPPostDecoder.class);
private String receiverEndpoint;
public OpenHTTPPostDecoder() {
super();
}
public OpenHTTPPostDecoder(ParserPool pool) {
super(pool);
}
/**
* Check the validity of the SAML protocol message receiver endpoint against
* requirements indicated in the message.
*
* @param messageContext current message context
*
* @throws SecurityException thrown if the message Destination attribute
* is invalid with respect to the receiver's
* endpoint
* @throws MessageDecodingException thrown if there is a problem decoding and
* processing the message Destination or
* receiver endpoint information
*/
@SuppressWarnings("rawtypes")
@Override
protected void checkEndpointURI(SAMLMessageContext messageContext)
throws SecurityException, MessageDecodingException {
log.debug("Checking SAML message intended destination endpoint against receiver endpoint");
String messageDestination = DatatypeHelper
.safeTrimOrNullString(getIntendedDestinationEndpointURI(messageContext));
boolean bindingRequires = isIntendedDestinationEndpointURIRequired(messageContext);
if (messageDestination == null) {
if (bindingRequires) {
log.error("SAML message intended destination endpoint URI required by binding was empty");
throw new SecurityException("SAML message intended destination (required by binding) was not present");
} else {
log.debug(
"SAML message intended destination endpoint in message was empty, not required by binding, skipping");
return;
}
}
String receiverEndpoint = DatatypeHelper.safeTrimOrNullString(getActualReceiverEndpointURI(messageContext));
log.debug("Intended message destination endpoint: {}", messageDestination);
log.debug("Actual message receiver endpoint: {}", receiverEndpoint);
// 协议头统一(http或https,需要和destination统一)
if (messageDestination.indexOf("/") != -1 && receiverEndpoint.indexOf("/") != -1) {
if (!messageDestination.substring(0, messageDestination.indexOf("/"))
.equalsIgnoreCase(receiverEndpoint.substring(0, receiverEndpoint.indexOf("/")))) {
receiverEndpoint = messageDestination.substring(0, messageDestination.indexOf("/"))
+ receiverEndpoint.substring(receiverEndpoint.indexOf("/"));
}
}
boolean matched = compareEndpointURIs(messageDestination, receiverEndpoint);
if (!matched) {
log.error("SAML message intended destination endpoint '{}' did not match the recipient endpoint '{}'",
messageDestination, receiverEndpoint);
throw new SecurityException("SAML message intended destination endpoint did not match recipient endpoint");
} else {
log.debug("SAML message intended destination endpoint matched recipient endpoint");
}
}
@Override
@SuppressWarnings("rawtypes")
protected String getActualReceiverEndpointURI(SAMLMessageContext messageContext) throws MessageDecodingException {
InTransport inTransport = messageContext.getInboundMessageTransport();
if (!(inTransport instanceof HttpServletRequestAdapter)) {
throw new MessageDecodingException("Message context InTransport instance was an unsupported type");
}
HttpServletRequest httpRequest = ((HttpServletRequestAdapter) inTransport).getWrappedRequest();
StringBuffer urlBuilder = httpRequest.getRequestURL();
String tempUrl = urlBuilder.toString();
// 从http协议头开始,跳过前面两个斜杠
tempUrl = tempUrl.substring(tempUrl.indexOf("/", 8) + 1);
return receiverEndpoint + tempUrl;
}
/**
* @param receiverEndpoint the receiverEndpoint to set
*/
public void setReceiverEndpoint(String receiverEndpoint) {
this.receiverEndpoint = receiverEndpoint;
}
/**
* @return the receiverEndpoint
*/
public String getReceiverEndpoint() {
return receiverEndpoint;
}
}
......@@ -90,7 +90,7 @@
<ref bean="localeChangeInterceptor" />
</mvc:interceptors>
<bean id="remeberMeService" class="org.maxkey.authn.support.rememberme.JdbcRemeberMeService">
<bean id="remeberMeService" class="org.maxkey.authn.support.rememberme.JdbcRemeberMeService">
<constructor-arg ref="jdbcTemplate"/>
<property name="validity" value="${config.login.remeberme.validity}"/>
</bean>
......@@ -104,24 +104,7 @@
</bean>
<bean id="counterBasedKeyUriFormat" class="org.maxkey.crypto.password.opt.algorithm.KeyUriFormat">
<property name="type" value="hotp" />
<property name="digits" value="6" />
<property name="issuer" value="maxkey" />
<property name="domain" value="maxkey.org" />
<property name="counter" value="0" />
</bean>
<bean id="hotpKeyUriFormat" class="org.maxkey.crypto.password.opt.algorithm.KeyUriFormat">
<property name="type" value="hotp" />
<property name="digits" value="6" />
<property name="issuer" value="maxkey" />
<property name="domain" value="maxkey.org" />
<property name="counter" value="0" />
</bean>
<bean id="tfaOTPAuthn" class="org.maxkey.crypto.password.opt.impl.TimeBasedOTPAuthn">
<bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn">
<constructor-arg ref="jdbcTemplate" />
</bean>
......@@ -151,41 +134,9 @@
</bean>
</property>
</bean>
<!-- Follow is config for Spring security -->
<!--<csrf disabled="true"/>-->
<!-- Login
<http use-expressions="false" disable-url-rewriting="false" xmlns="http://www.springframework.org/schema/security" >
<headers>
<frame-options policy="SAMEORIGIN" />
</headers>
<access-denied-handler error-page="/login"/>
<intercept-url pattern="/index" access="ROLE_USER" />
<intercept-url pattern="/forwardindex" access="ROLE_USER" />
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY,ROLE_USER" />
<form-login authentication-failure-url="/login"
default-target-url="/forwardindex"
login-page="/login"
login-processing-url="/logon.do"
username-parameter="j_username"
password-parameter="j_password"
authentication-success-handler-ref="savedRequestSuccessHandler"/>
<logout logout-url="/logout.do" logout-success-url="/logout" invalidate-session="true" delete-cookies="JSESSIONID" />
<session-management invalid-session-url="/login" />
<anonymous />
</http>
-->
<bean id="savedRequestSuccessHandler" class="org.maxkey.authn.SavedRequestAwareAuthenticationSuccessHandler"> </bean>
<!-- spring authentication provider
<authentication-manager alias="authenticationProvider" xmlns="http://www.springframework.org/schema/security"/>
-->
<!-- LDAP Realm
<bean id="authenticationRealm" class="org.maxkey.web.authentication.realm.ldap.LdapAuthenticationRealm">
<constructor-arg ref="jdbcTemplate"/>
......@@ -225,34 +176,16 @@
</property>
</bean> -->
<!-- Radius Server Realm
<bean id="authenticationRealm" class="org.maxkey.web.authentication.realm.radius.RadiusServerAuthenticationRealm">
<constructor-arg ref="jdbcTemplate"/>
<property name="jradiusServers">
<list>
<bean id="radiusServer1" class="org.maxkey.web.authentication.realm.radius.RadiusServer">
<property name="inetAddress" value="localhost"/>
<property name="secret" value="test1234"/>
</bean>
</list>
</property>
</bean>-->
<!-- Default Realm-->
<!-- realm use jdbc -->
<bean id="authenticationRealm" class="org.maxkey.authn.realm.jdbc.JdbcAuthenticationRealm">
<constructor-arg ref="jdbcTemplate"/>
</bean>
<!-- Authentication providers -->
<bean id="authenticationProvider" class="org.maxkey.authn.RealmAuthenticationProvider" >
</bean>
<!--
<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider ref= "realmAuthenticationProvider"/>
</authentication-manager>
-->
<mvc:annotation-driven />
<mvc:default-servlet-handler />
......
......@@ -6,7 +6,7 @@ import org.apache.commons.codec.binary.Hex;
import org.maxkey.crypto.Base32Utils;
import org.maxkey.crypto.password.PasswordReciprocal;
import org.maxkey.crypto.password.opt.algorithm.KeyUriFormat;
import org.maxkey.crypto.password.opt.algorithm.OTPSecret;
import org.maxkey.crypto.password.opt.algorithm.OtpSecret;
import org.maxkey.dao.service.UserInfoService;
import org.maxkey.domain.UserInfo;
import org.maxkey.util.RQCodeUtils;
......@@ -63,7 +63,7 @@ public class OneTimePasswordController {
@RequestMapping(value = {"gen/timebased"})
public ModelAndView gentimebased() {
UserInfo userInfo = WebContext.getUserInfo();
byte[] byteSharedSecret = OTPSecret.generate(keyUriFormat.getCrypto());
byte[] byteSharedSecret = OtpSecret.generate(keyUriFormat.getCrypto());
String sharedSecret = Base32Utils.encode(byteSharedSecret);
sharedSecret = passwordReciprocal.encode(sharedSecret);
userInfo.setSharedSecret(sharedSecret);
......@@ -96,7 +96,7 @@ public class OneTimePasswordController {
@RequestMapping(value = {"gen/counterbased"})
public ModelAndView gencounterbased() {
UserInfo userInfo = WebContext.getUserInfo();
byte[] byteSharedSecret = OTPSecret.generate(keyUriFormat.getCrypto());
byte[] byteSharedSecret = OtpSecret.generate(keyUriFormat.getCrypto());
String sharedSecret = Base32Utils.encode(byteSharedSecret);
sharedSecret = passwordReciprocal.encode(sharedSecret);
userInfo.setSharedSecret(sharedSecret);
......@@ -128,7 +128,7 @@ public class OneTimePasswordController {
@RequestMapping(value = {"gen/hotp"})
public ModelAndView genhotp() {
UserInfo userInfo = WebContext.getUserInfo();
byte[] byteSharedSecret = OTPSecret.generate(keyUriFormat.getCrypto());
byte[] byteSharedSecret = OtpSecret.generate(keyUriFormat.getCrypto());
String sharedSecret = Base32Utils.encode(byteSharedSecret);
sharedSecret = passwordReciprocal.encode(sharedSecret);
userInfo.setSharedSecret(sharedSecret);
......
......@@ -91,7 +91,7 @@
</bean>
<bean id="tfaOTPAuthn" class="org.maxkey.crypto.password.opt.impl.TimeBasedOTPAuthn">
<bean id="tfaOptAuthn" class="org.maxkey.crypto.password.opt.impl.TimeBasedOtpAuthn">
<constructor-arg ref="jdbcTemplate" />
</bean>
......@@ -179,19 +179,6 @@
</property>
</bean> -->
<!-- Radius Server Realm
<bean id="authenticationRealm" class="org.maxkey.web.authentication.realm.radius.RadiusServerAuthenticationRealm">
<constructor-arg ref="jdbcTemplate"/>
<property name="jradiusServers">
<list>
<bean id="radiusServer1" class="org.maxkey.web.authentication.realm.radius.RadiusServer">
<property name="inetAddress" value="localhost"/>
<property name="secret" value="test1234"/>
</bean>
</list>
</property>
</bean>-->
<!-- Default Realm-->
<!-- realm use jdbc -->
<bean id="authenticationRealm" class="org.maxkey.authn.realm.jdbc.JdbcAuthenticationRealm">
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册