package com.ruterfu.test;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import javax.crypto.Mac;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Random;
public class HuaweiWS5200AccessUtils {
private String csrfParam;
private String csrfToken;
private String cookie;
private final OkHttpClient okHttpClient = new OkHttpClient();
private static final String URL = "http://10.0.0.10";
private static final String password = "123456";
public static void main(String[] args) {
HuaweiWS5200AccessUtils router = new HuaweiWS5200AccessUtils();
if(router.init() && router.login()) {
// 获得主机
String data = router.accessRouter("/api/system/HostInfo");
System.out.println(data);
}
}
public boolean login() {
JSONObject data = new JSONObject();
String firstNonce = randomNonce();
data.put("username", "admin");
data.put("firstnonce", firstNonce);
JSONObject loginNonce = accessRouter("/api/system/user_login_nonce", data, null);
if(loginNonce != null) {
try {
int iterations = loginNonce.getIntValue("iterations");
String salt = loginNonce.getString("salt");
String serverNonce = loginNonce.getString("servernonce");
byte[] saltedPassword = getSaltedPassword(password, hexToByteArray(salt), iterations);
byte[] clientKey = getHmac("Client Key", saltedPassword);
byte[] storeKey = getStoreKey(clientKey);
String authMsg = firstNonce + "," + serverNonce + "," + serverNonce;
byte[] clientSignature = getHmac(authMsg, storeKey);
for (int i = 0; i < clientKey.length; i++) {
clientKey[i] = (byte) (clientKey[i] ^ clientSignature[i]);
}
String clientProof = bytesToHex(clientKey);
JSONObject login = new JSONObject();
login.put("clientproof", clientProof);
login.put("finalnonce", serverNonce);
JSONObject loginDone = accessRouter("/api/system/user_login_proof", login, null);
return loginDone.containsKey("err") && loginDone.getIntValue("err") == 0;
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
private byte[] getSaltedPassword(String password, byte[] salt, int iterations) throws NoSuchAlgorithmException, InvalidKeySpecException {
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations, 256);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
return f.generateSecret(spec).getEncoded();
}
private byte[] getHmac(String key, byte[] input) throws NoSuchAlgorithmException, InvalidKeyException {
String hmacName = "HmacSHA256";
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.US_ASCII), hmacName);
Mac mac = Mac.getInstance(hmacName);
mac.init(secretKeySpec);
mac.update(input);
return mac.doFinal();
}
private byte[] getStoreKey(byte[] clientKey) throws NoSuchAlgorithmException {
return MessageDigest.getInstance("SHA-256").digest(clientKey);
}
/**
* from https://blog.csdn.net/qq_34763699/article/details/78650272
*/
public static byte[] hexToByteArray(String inHex){
int hexLength = inHex.length();
byte[] result;
if (hexLength % 2 == 1){
hexLength++;
result = new byte[(hexLength / 2)];
inHex = "0" + inHex;
}else {
result = new byte[(hexLength / 2)];
}
int j=0;
for (int i = 0; i < hexLength; i += 2){
result[j]=(byte)Integer.parseInt(inHex.substring(i, i + 2),16);
j++;
}
return result;
}
/**
* from https://blog.csdn.net/qq_34763699/article/details/78650272
*/
public static String bytesToHex(byte[] bytes) {
StringBuffer sb = new StringBuffer();
for(int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if(hex.length() < 2){
sb.append(0);
}
sb.append(hex);
}
return sb.toString();
}
public boolean init() {
Request request = new Request.Builder().url(URL + "/html/index.html").get().build();
try(Response response = okHttpClient.newCall(request).execute(); ResponseBody responseBody = response.body() != null ? response.body() : null) {
if(response.code() == 200) {
String data = responseBody.string();
int csrfStart = data.indexOf("csrf_param");
data = data.substring(csrfStart);
int csrfParamStart = data.indexOf("=\"");
int csrfParamEnd = data.indexOf("\"/>");
csrfParam = data.substring(csrfParamStart + 2, csrfParamEnd).trim();
int csrfTokenStart = data.indexOf("csrf_token");
data = data.substring(csrfTokenStart);
int csrfTokenParamStart = data.indexOf("=\"");
int csrfTokenParamEnd = data.indexOf("\"/>");
csrfToken = data.substring(csrfTokenParamStart + 2, csrfTokenParamEnd).trim();
String cookiePath = response.header("Set-Cookie");
int cookieSplit = cookiePath.indexOf(";");
cookie = cookiePath.substring(0, cookieSplit);
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private JSONObject accessRouter(String url, JSONObject data, String action) {
JSONObject jsonObject = new JSONObject();
JSONObject csrf = new JSONObject();
csrf.put("csrf_param", csrfParam);
csrf.put("csrf_token", csrfToken);
jsonObject.put("csrf", csrf);
jsonObject.put("data", data);
if(action != null && action.length() > 0) {
jsonObject.put("action", action);
}
Request request = new Request.Builder().url(URL + url).header("Cookie", cookie).post(RequestBody.create(jsonObject.toJSONString(), MediaType.parse("application/json"))).build();
try(Response response = okHttpClient.newCall(request).execute(); ResponseBody responseBody = response.body() != null ? response.body() : null) {
if(response.code() == 200) {
JSONObject repsJson = JSON.parseObject(responseBody.string());
if(repsJson.containsKey("csrf_token")) {
this.csrfToken = repsJson.getString("csrf_token");
repsJson.remove("csrf_token");
}
if(repsJson.containsKey("csrf_param")) {
this.csrfParam = repsJson.getString("csrf_param");
repsJson.remove("csrf_param");
}
String newHeader = response.header("Set-Cookie");
if(newHeader != null) {
cookie = newHeader;
}
return repsJson;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private String accessRouter(String url) {
Request request = new Request.Builder().url(URL + url).header("Cookie", cookie).get().build();
try(Response response = okHttpClient.newCall(request).execute(); ResponseBody responseBody = response.body() != null ? response.body() : null) {
if(response.code() == 200) {
String body = responseBody.string();
String newHeader = response.header("Set-Cookie");
if(newHeader != null) {
cookie = newHeader;
}
return body;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private String randomNonce() {
String rand = "abcdef1234567890";
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 64; i++) {
int number = random.nextInt(rand.length());
sb.append(rand.charAt(number));
}
return sb.toString();
}
}
https://www.ruterfu.com/2021/04/19/20210419-login-by-codes-huawei-router-WS5200/
浙公网安备 33010602011771号