Browse Source

feat: 完成steam令牌本地获取

master
niushuai233 3 years ago
commit
1d903f15a7
  1. 100
      pom.xml
  2. 24
      src/main/java/cc/niushuai/project/steam/token/SteamTokenApplication.java
  3. 49
      src/main/java/cc/niushuai/project/steam/token/entity/SteamCommand.java
  4. 29
      src/main/java/cc/niushuai/project/steam/token/entity/SteamInfo.java
  5. 20
      src/main/java/cc/niushuai/project/steam/token/enums/GuardCalcTypeEnum.java
  6. 82
      src/main/java/cc/niushuai/project/steam/token/ins/SteamTwoFactorToken.java
  7. 48
      src/main/java/cc/niushuai/project/steam/token/util/CommandParseUtil.java
  8. 69
      src/main/java/cc/niushuai/project/steam/token/util/GlobalUtil.java

100
pom.xml

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cc.niushuai.project</groupId>
<artifactId>steam-token</artifactId>
<version>0.0.1</version>
<description>steam令牌计算</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<hutool.version>5.7.22</hutool.version>
<commons.cli.version>1.3</commons.cli.version>
<lombok.version>1.18.22</lombok.version>
</properties>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>${commons.cli.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>aliyun</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>aliyun-plugin</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<build>
<finalName>steam-token-generator</finalName>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<!-- 程序入口 -->
<mainClass>cc.niushuai.project.steam.token.SteamTokenApplication</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>assembly</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

24
src/main/java/cc/niushuai/project/steam/token/SteamTokenApplication.java

@ -0,0 +1,24 @@
package cc.niushuai.project.steam.token;
import cc.niushuai.project.steam.token.ins.SteamTwoFactorToken;
import cc.niushuai.project.steam.token.util.GlobalUtil;
import cn.hutool.core.date.DateUtil;
/**
* Steam 令牌计算
*
* @author niushuai
* @date 2022/8/29 17:53
*/
public class SteamTokenApplication {
public static void main(String[] args) {
GlobalUtil.init(args);
System.out.println("初始化命令行参数成功" + args);
String steamGuardCode = SteamTwoFactorToken.generateSteamGuardCode(GlobalUtil.getShared_secret());
System.out.println("当前时间: " + DateUtil.now());
System.out.println("Steam令牌: " + steamGuardCode);
}
}

49
src/main/java/cc/niushuai/project/steam/token/entity/SteamCommand.java

@ -0,0 +1,49 @@
package cc.niushuai.project.steam.token.entity;
import cc.niushuai.project.steam.token.enums.GuardCalcTypeEnum;
import cc.niushuai.project.steam.token.util.GlobalUtil;
import cn.hutool.core.util.StrUtil;
import lombok.Data;
/**
* steam文件令牌信息
*
* @author niushuai
* @date 2022/8/30 10:47
*/
@Data
public class SteamCommand {
private GuardCalcTypeEnum type;
/**
* 直接指定秘钥
*/
private String sharedSecret;
/**
* 指定steam令牌文件 从文件中读取秘钥
*/
private String path;
public SteamCommand verify() {
if (StrUtil.isEmpty(sharedSecret) && StrUtil.isEmpty(path)) {
System.err.println("参数缺失!");
printUsage();
GlobalUtil.exit();
}
if (StrUtil.isNotEmpty(sharedSecret)) {
this.setType(GuardCalcTypeEnum.COMMAND);
} else {
this.setType(GuardCalcTypeEnum.STEAM_FILE);
}
return this;
}
public void printUsage() {
System.out.println("usage: \n\tjava -jar steam-token-generator.jar [-sharedSecret xxx] [-path xxx]");
System.out.println("eg: \n\tjava -jar steam-token-generator.jar -sharedSecret sJH7ffdwqgluzJK0tB6L7LklYSg=");
System.out.println("\tjava -jar steam-token-generator.jar -path Steamguard-16561111382543543");
System.out.println("tips: \n\t两个参数任选其一, 若都传递则直接使用sharedSecret");
}
}

29
src/main/java/cc/niushuai/project/steam/token/entity/SteamInfo.java

@ -0,0 +1,29 @@
package cc.niushuai.project.steam.token.entity;
import cc.niushuai.project.steam.token.enums.GuardCalcTypeEnum;
import lombok.Data;
/**
* steam文件令牌信息
*
* @author niushuai
* @date 2022/8/30 10:47
*/
@Data
public class SteamInfo {
private GuardCalcTypeEnum type;
private String shared_secret;
private String serial_number;
private String revocation_code;
private String uri;
private String server_time;
private String account_name;
private String token_gid;
private String identity_secret;
private String secret_1;
private String status;
private Integer steamguard_scheme;
private String steamid;
}

20
src/main/java/cc/niushuai/project/steam/token/enums/GuardCalcTypeEnum.java

@ -0,0 +1,20 @@
package cc.niushuai.project.steam.token.enums;
/**
* 令牌计算类型
*
* @author niushuai
* @date 2022/8/30 11:05
*/
public enum GuardCalcTypeEnum {
/**
* 命令行参数
*/
COMMAND,
/**
* 读取文件
*/
STEAM_FILE;
}

82
src/main/java/cc/niushuai/project/steam/token/ins/SteamTwoFactorToken.java

@ -0,0 +1,82 @@
package cc.niushuai.project.steam.token.ins;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.StrUtil;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
/**
* SteamToken计算
*
* @author niushuai
* @date 2022/8/29 17:55
*/
public class SteamTwoFactorToken {
private static final byte[] s_rgchSteamguardCodeChars = {50, 51, 52, 53, 54, 55, 56, 57, 66, 67, 68, 70, 71, 72, 74, 75, 77, 78, 80, 81, 82, 84, 86, 87, 88, 89};
private byte[] mSecret;
public SteamTwoFactorToken(String sharedSecret) {
if (StrUtil.isNotEmpty(sharedSecret)) {
this.mSecret = Base64.decode(sharedSecret.getBytes());
} else {
throw new RuntimeException("未知参数 shared_secret");
}
}
public static String generateSteamGuardCode(String sharedSecret) {
return new SteamTwoFactorToken(sharedSecret).generateSteamGuardCode();
}
public final String generateSteamGuardCode() {
return generateSteamGuardCodeForTime(currentTime());
}
private final String generateSteamGuardCodeForTime(long calcTime) {
if (this.mSecret == null) {
return "";
}
byte[] bArr = new byte[8];
long j2 = calcTime / 30;
int i = 8;
while (true) {
int i2 = i - 1;
if (i <= 0) {
break;
}
bArr[i2] = (byte) ((int) j2);
j2 >>>= 8;
i = i2;
}
SecretKeySpec secretKeySpec = new SecretKeySpec(this.mSecret, "HmacSHA1");
try {
Mac instance = Mac.getInstance("HmacSHA1");
instance.init(secretKeySpec);
byte[] doFinal = instance.doFinal(bArr);
int i3 = doFinal[19] & 15;
int i4 = (doFinal[i3 + 3] & 255) | ((doFinal[i3 + 2] & 255) << 8) | ((doFinal[i3] & Byte.MAX_VALUE) << 24) | ((doFinal[i3 + 1] & 255) << 16);
byte[] bArr2 = new byte[5];
for (int i5 = 0; i5 < 5; i5++) {
byte[] bArr3 = s_rgchSteamguardCodeChars;
bArr2[i5] = bArr3[i4 % bArr3.length];
i4 /= bArr3.length;
}
return new String(bArr2);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 系统时间 不带毫秒
*
* @author niushuai
* @date: 2022/8/30 10:28
* @return: {@link long} 秒级时间戳
*/
public final long currentTime() {
return System.currentTimeMillis() / 1000;
}
}

48
src/main/java/cc/niushuai/project/steam/token/util/CommandParseUtil.java

@ -0,0 +1,48 @@
package cc.niushuai.project.steam.token.util;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.json.JSONUtil;
import org.apache.commons.cli.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
* 处理命令行参数
*
* @author niushuai
* @date: 2022/8/30 10:42
*/
public class CommandParseUtil {
public static <T> T parse(String[] args, Class<T> clazz) {
CommandLineParser parser = new DefaultParser();
//获取字段
Field[] fields = ReflectUtil.getFields(clazz);
//使用字段创建options,options是parse需要的参数
Options options = new Options();
for (Field field : fields) {
String name = field.getName();
Option option = Option.builder(name).argName(name)
.desc(name)
.hasArg(true)
.type(field.getType())
.build();
options.addOption(option);
}
try {
CommandLine cl = parser.parse(options, args);
Map<String, String> map = new HashMap<>();
for (Field argsField : fields) {
String name = argsField.getName();
map.put(name, cl.getOptionValue(name));
}
return (T) JSONUtil.toBean(JSONUtil.toJsonStr(map), clazz);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

69
src/main/java/cc/niushuai/project/steam/token/util/GlobalUtil.java

@ -0,0 +1,69 @@
package cc.niushuai.project.steam.token.util;
import cc.niushuai.project.steam.token.entity.SteamCommand;
import cc.niushuai.project.steam.token.entity.SteamInfo;
import cc.niushuai.project.steam.token.enums.GuardCalcTypeEnum;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import java.util.stream.Collectors;
/**
* 初始化工具类
*
* @author niushuai
* @date 2022/8/30 10:33
*/
public class GlobalUtil {
private static String shared_secret = "";
/**
* 处理命令行参数
*
* @param args 命令行参数
* @author niushuai
* @date: 2022/8/30 10:52
*/
public static void init(String[] args) {
SteamCommand command = CommandParseUtil.parse(args, SteamCommand.class).verify();
System.out.println("秘钥解析类型: " + command.getType());
if (GuardCalcTypeEnum.COMMAND.equals(command.getType())) {
shared_secret = command.getSharedSecret();
} else {
// 需要先读文件 再取值
try {
String steamGuardInfoJson = FileUtil.readLines(command.getPath(), "UTF-8").stream().collect(Collectors.joining());
// 文件内容转bean
SteamInfo steamInfo = JSONUtil.toBean(steamGuardInfoJson, SteamInfo.class);
System.out.println("Steam ID: " + steamInfo.getSteamid());
System.out.println("Steam 账户: " + steamInfo.getAccount_name());
shared_secret = steamInfo.getShared_secret();
} catch (IORuntimeException e) {
System.err.println("Steam令牌文件未找到: " + command.getPath() + ", 请确认路径是否正确!");
}
}
if (StrUtil.isEmpty(shared_secret)) {
String msg = GuardCalcTypeEnum.COMMAND.equals(command.getType()) ? "命令行shared_secret参数" : "Steam令牌文件路径";
System.err.println("未找到相关秘钥[shared_secret], 请确认" + msg + "是否正确");
exit();
}
System.out.println("shared_secret init success: " + shared_secret);
}
public static String getShared_secret() {
return shared_secret;
}
public static void exit() {
System.exit(0);
}
}
Loading…
Cancel
Save