马里奥系统开发「冯生」【191﹎5743﹍0738】〔V或电〕马里奥模式开发、马里奥app开发、马里奥平台开发、马里奥软件开发。马里奥系统源码开发。马里奥模式系统定制开发,马里奥模式软件系统定制开发,类似马里奥模式app系统定制开发,类似马里奥模式开发案例介绍,马里奥系统开发专业开发公司,马里奥app开发专业开发公司
------温馨提示:专业开发公司,非平台方,玩家勿扰------
后端代码网上很多,随便找了一个,测试可用
package com.bessky.hrmis.common.rbac.encrypt;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Base64;
/**
*
*
*google身份验证器,java服务端实现
*/
public class GoogleAuthenticator{
//生成的key长度(Generate secret key length)
public static final int SECRET_SIZE=10;
public static final String SEED="g8GjEvTbW5oVSV7avL47357438reyhreyuryetredLDVKs2m0QN7vxRs2im5MDaNCWGmcD2rvcZx";
//Java实现随机数算法
public static final String RANDOM_NUMBER_ALGORITHM="SHA1PRNG";
//最多可偏移的时间
int window_size=10;//default 3-max 17
/**
*set the windows size.This is an integer value representing the number of
*30 second windows we allow The bigger the window,the more tolerant of
*clock skew we are.
*
*param s
*window size-must be>=1 and<=17.Other values are ignored
*/
public void setWindowSize(int s){
if(s>=1&&s<=17)
window_size=s;
}
/**
*Generate a random secret key.This must be saved by the server and
*associated with the users account to verify the code displayed by Google
*Authenticator.The user must register this secret on their device.
*生成一个随机秘钥
*
*return secret key
*/
public static String generateSecretKey(){
SecureRandom sr=null;
try{
sr=SecureRandom.getInstance(RANDOM_NUMBER_ALGORITHM);
sr.setSeed(Base64.decodeBase64(SEED.getBytes()));
byte[]buffer=sr.generateSeed(SECRET_SIZE);
Base32 codec=new Base32();
byte[]bEncodedKey=codec.encode(buffer);
String encodedKey=new String(bEncodedKey);
return encodedKey;
}catch(NoSuchAlgorithmException e){
//should never occur...configuration error
}
return null;
}
/**
*生成一个google身份验证器,识别的字符串,只需要把该方法返回值生成二维码扫描就可以了。
*param label
*标签
*param user
*账号
*param secret
*密钥
*return
*/
public static String getQRBarcode(String label,String user,String secret){
String format="otpauth://totp/%s:%s?secret=%s";
return String.format(format,label,user,secret);
}
/**
*生成一个google身份验证器,识别的字符串,只需要把该方法返回值生成二维码扫描就可以了。
*
*param user
*账号
*param secret
*密钥
*return
*/
public static String getQRBarcode(String user,String secret){
String format="otpauth://totp/%s?secret=%s";
return String.format(format,user,secret);
}
/**
*Check the code entered by the user to see if it is valid验证code是否合法
*
*param secret
*The users secret.
*param code
*The code displayed on the users device
*param t
*The time in msec(System.currentTimeMillis()for example)
*return
*/
public boolean check_code(String secret,long code,long timeMsec){
if(secret==null||"".equals(secret))
{
return false;
}
Base32 codec=new Base32();
byte[]decodedKey=codec.decode(secret);
//convert unix msec time into a 30 second"window"
//this is per the TOTP spec(see the RFC for details)
long t=(timeMsec/1000L)/30L;
//Window is used to check codes generated in the near past.
//You can use this value to tune how far you're willing to go.
for(int i=-window_size;i<=window_size;++i){
long hash;
try{
hash=verify_code(decodedKey,t+i);
}catch(Exception e){
//Yes,this is bad form-but
//the exceptions thrown would be rare and a static
//configuration problem
e.printStackTrace();
throw new RuntimeException(e.getMessage());
//return false;
}
if(hash==code){
return true;
}
}
//The validation code is invalid.
return false;
}
private static int verify_code(byte[]key,long t)throws NoSuchAlgorithmException,InvalidKeyException{
byte[]data=new byte[8];
long value=t;
for(int i=8;i-->0;value>>>=8){
data<i>=(byte)value;