shimingxy 5 年之前
父節點
當前提交
213d1c81f1
共有 42 個文件被更改,包括 1779 次插入1772 次删除
  1. 3 3
      maxkey-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java
  2. 15 15
      maxkey-core/src/main/java/org/maxkey/crypto/Base32Utils.java
  3. 114 107
      maxkey-core/src/main/java/org/maxkey/crypto/Base64Utils.java
  4. 57 38
      maxkey-core/src/main/java/org/maxkey/crypto/password/PasswordGen.java
  5. 37 38
      maxkey-core/src/main/java/org/maxkey/crypto/password/PasswordReciprocal.java
  6. 0 186
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/AbstractOTPAuthn.java
  7. 208 0
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/AbstractOptAuthn.java
  8. 64 97
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/OneTimePassword.java
  9. 106 124
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/algorithm/HOTP.java
  10. 78 60
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/algorithm/HmacOTP.java
  11. 201 210
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/algorithm/KeyUriFormat.java
  12. 0 69
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/algorithm/OTPSecret.java
  13. 64 0
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/algorithm/OtpSecret.java
  14. 188 203
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/algorithm/TimeBasedOTP.java
  15. 0 8
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/algorithm/package-info.java
  16. 0 37
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/CAPOTPAuthn.java
  17. 35 0
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/CapOtpAuthn.java
  18. 0 47
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/CounterBasedOTPAuthn.java
  19. 58 0
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/CounterBasedOtpAuthn.java
  20. 0 82
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/HOTPOTPAuthn.java
  21. 81 0
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/HotpOtpAuthn.java
  22. 0 59
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/MailOTPAuthn.java
  23. 57 0
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/MailOtpAuthn.java
  24. 0 28
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/MobileOTPAuthn.java
  25. 25 0
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/MobileOtpAuthn.java
  26. 0 37
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/RSAOTPAuthn.java
  27. 35 0
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/RsaOtpAuthn.java
  28. 0 30
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/SmsOTPAuthn.java
  29. 27 0
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/SmsOtpAuthn.java
  30. 0 65
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/TimeBasedOTPAuthn.java
  31. 63 0
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/TimeBasedOtpAuthn.java
  32. 0 7
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/package-info.java
  33. 7 0
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/SendSms.java
  34. 103 0
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/netease/SendSmsYunxin.java
  35. 42 0
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/netease/SendSmsYunxinCheckSumBuilder.java
  36. 1 0
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/package-info.java
  37. 0 8
      maxkey-core/src/main/java/org/maxkey/crypto/password/opt/package-info.java
  38. 0 8
      maxkey-core/src/main/java/org/maxkey/crypto/password/package-info.java
  39. 101 117
      maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/binding/decoder/OpenHTTPPostDecoder.java
  40. 4 71
      maxkey-web-manage/src/main/resources/spring/maxkey-mgt-security.xml
  41. 4 4
      maxkey-web-maxkey/src/main/java/org/maxkey/web/contorller/OneTimePasswordController.java
  42. 1 14
      maxkey-web-maxkey/src/main/resources/spring/maxkey-security.xml

+ 3 - 3
maxkey-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java

@@ -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")

+ 15 - 15
maxkey-core/src/main/java/org/maxkey/crypto/Base32Utils.java

@@ -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);
+    }
+
 }

+ 114 - 107
maxkey-core/src/main/java/org/maxkey/crypto/Base64Utils.java

@@ -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
+    }
 
 }

+ 57 - 38
maxkey-core/src/main/java/org/maxkey/crypto/password/PasswordGen.java

@@ -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();
     }

+ 37 - 38
maxkey-core/src/main/java/org/maxkey/crypto/password/PasswordReciprocal.java

@@ -1,49 +1,48 @@
-/**
- * 
- */
 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());
+    }
 
 }

+ 0 - 186
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/AbstractOTPAuthn.java

@@ -1,186 +0,0 @@
-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;
-		}
-	}
-	
-	
-}

+ 208 - 0
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/AbstractOptAuthn.java

@@ -0,0 +1,208 @@
+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;
+        }
+    }
+
+}

+ 64 - 97
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/OneTimePassword.java

@@ -1,102 +1,69 @@
 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 + "]";
-	}
-	
-	
 }

+ 106 - 124
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/algorithm/HOTP.java

@@ -1,36 +1,35 @@
 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;
-       }
-   
 }

+ 78 - 60
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/algorithm/HmacOTP.java

@@ -1,80 +1,98 @@
 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;
- }
- 
 }

+ 201 - 210
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/algorithm/KeyUriFormat.java

@@ -1,214 +1,205 @@
 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();
+    }
+
 }

+ 0 - 69
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/algorithm/OTPSecret.java

@@ -1,69 +0,0 @@
-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);
-	}
-
-
-	
-}

+ 64 - 0
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/algorithm/OtpSecret.java

@@ -0,0 +1,64 @@
+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);
+    }
+
+}

+ 188 - 203
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/algorithm/TimeBasedOTP.java

@@ -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;
+    }
 
 }

+ 0 - 8
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/algorithm/package-info.java

@@ -1,8 +0,0 @@
-/**
- * 
- */
-/**
- * @author Administrator
- *
- */
-package org.maxkey.crypto.password.opt.algorithm;

+ 0 - 37
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/CAPOTPAuthn.java

@@ -1,37 +0,0 @@
-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;
-	}
-	
-
-	
-}

+ 35 - 0
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/CapOtpAuthn.java

@@ -0,0 +1,35 @@
+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;
+    }
+
+}

+ 0 - 47
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/CounterBasedOTPAuthn.java

@@ -1,47 +0,0 @@
-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;
-	}
-	
-}

+ 58 - 0
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/CounterBasedOtpAuthn.java

@@ -0,0 +1,58 @@
+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;
+    }
+
+}

+ 0 - 82
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/HOTPOTPAuthn.java

@@ -1,82 +0,0 @@
-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;
-	}
-	
-	
-	
-}

+ 81 - 0
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/HotpOtpAuthn.java

@@ -0,0 +1,81 @@
+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;
+    }
+
+}

+ 0 - 59
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/MailOTPAuthn.java

@@ -1,59 +0,0 @@
-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;
-	}
-
-	
-}

+ 57 - 0
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/MailOtpAuthn.java

@@ -0,0 +1,57 @@
+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;
+    }
+
+}

+ 0 - 28
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/MobileOTPAuthn.java

@@ -1,28 +0,0 @@
-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;
-	}
-	
-
-	
-}

+ 25 - 0
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/MobileOtpAuthn.java

@@ -0,0 +1,25 @@
+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;
+    }
+
+}

+ 0 - 37
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/RSAOTPAuthn.java

@@ -1,37 +0,0 @@
-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;
-	}
-	
-
-	
-}

+ 35 - 0
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/RsaOtpAuthn.java

@@ -0,0 +1,35 @@
+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;
+    }
+
+}

+ 0 - 30
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/SmsOTPAuthn.java

@@ -1,30 +0,0 @@
-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);
-	}
-	
-
-	
-}

+ 27 - 0
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/SmsOtpAuthn.java

@@ -0,0 +1,27 @@
+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);
+    }
+
+}

+ 0 - 65
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/TimeBasedOTPAuthn.java

@@ -1,65 +0,0 @@
-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;
-
-	}
-	
-}

+ 63 - 0
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/TimeBasedOtpAuthn.java

@@ -0,0 +1,63 @@
+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;
+
+    }
+
+}

+ 0 - 7
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/package-info.java

@@ -1,8 +1 @@
-/**
- * 
- */
-/**
- * @author Administrator
- *
- */
 package org.maxkey.crypto.password.opt.impl;

+ 7 - 0
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/SendSms.java

@@ -0,0 +1,7 @@
+package org.maxkey.crypto.password.opt.impl.sms;
+
+public interface SendSms {
+
+    public String sendSms();
+    
+}

+ 103 - 0
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/netease/SendSmsYunxin.java

@@ -0,0 +1,103 @@
+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;
+    }
+    
+}

+ 42 - 0
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/netease/SendSmsYunxinCheckSumBuilder.java

@@ -0,0 +1,42 @@
+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' };
+}

+ 1 - 0
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/impl/sms/package-info.java

@@ -0,0 +1 @@
+package org.maxkey.crypto.password.opt.impl.sms;

+ 0 - 8
maxkey-core/src/main/java/org/maxkey/crypto/password/opt/package-info.java

@@ -1,8 +0,0 @@
-/**
- * 
- */
-/**
- * @author Administrator
- *
- */
-package org.maxkey.crypto.password.opt;

+ 0 - 8
maxkey-core/src/main/java/org/maxkey/crypto/password/package-info.java

@@ -1,8 +0,0 @@
-/**
- * 
- */
-/**
- * @author Administrator
- *
- */
-package org.maxkey.crypto.password;

+ 101 - 117
maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/binding/decoder/OpenHTTPPostDecoder.java

@@ -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;
+    }
 }

+ 4 - 71
maxkey-web-manage/src/main/resources/spring/maxkey-mgt-security.xml

@@ -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 />

+ 4 - 4
maxkey-web-maxkey/src/main/java/org/maxkey/web/contorller/OneTimePasswordController.java

@@ -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);

+ 1 - 14
maxkey-web-maxkey/src/main/resources/spring/maxkey-security.xml

@@ -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">