debug vpnconnection...

This commit is contained in:
free will
2021-07-26 20:20:52 +08:00
parent 4c21165f8d
commit 90812c8e1a
3 changed files with 102 additions and 15 deletions
@@ -18,6 +18,7 @@ import android.text.TextUtils;
import androidx.annotation.RequiresApi;
import com.pkusz.min_vpn_client.model.MINVpnSettingAPI;
import com.pkusz.min_vpn_client.utils.AESHelperForConnection;
import com.pkusz.min_vpn_client.utils.IPPackageUtil;
import com.pkusz.min_vpn_client.utils.KeyManager;
import com.pkusz.min_vpn_client.utils.RuleUtil;
@@ -29,6 +30,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Objects;
import java.util.Set;
@@ -68,7 +70,7 @@ public class MINVpnConnection implements Runnable{
private final String mSharedSecretString;
private byte[] mEncryptedAESSeed;
// 实际使用的密钥是:随机产生的密钥经过sm3哈希,取前16字节
private byte[] realSecret;
// private byte[] realSecret;
// 代理地址 todo:??
private String mProxyHostName;
@@ -109,10 +111,11 @@ public class MINVpnConnection implements Runnable{
* @param allow
* @param packages
*/
@RequiresApi(api = Build.VERSION_CODES.O)
public MINVpnConnection(final VpnService service, final int connectionId,
final String serverName, final int serverPort, final byte[] sharedSecret,
final String proxyHostName, final int proxyHostPort, boolean allow,
final Set<String> packages) {
final String serverName, final int serverPort, final byte[] sharedSecret,
final String proxyHostName, final int proxyHostPort, boolean allow,
final Set<String> packages) {
// VPNService 及 连接ID
mService=service;
mConnectionId=connectionId;
@@ -125,11 +128,19 @@ public class MINVpnConnection implements Runnable{
mServerPort=serverPort;
mSharedSecret=sharedSecret;
mSharedSecretString=new String(mSharedSecret);
System.out.println("mSharedSecretString: "+mSharedSecretString);
mEncryptedAESSeed= SM2HelperForConnection.encryptWithSM2(mSharedSecretString);
realSecret= SM3HelperForConnection.getSM3Hash16(mSharedSecret);
// realSecret= SM3HelperForConnection.getSM3Hash16(mSharedSecret);
// 测试sm4
SM4HelperForConnection.encryptWithSM4(realSecret, "sss".getBytes());
// 测试AES
// System.out.println("!!!密钥:"+mSharedSecretString);
// byte[] res=AESHelperForConnection.encryptWithAES(mSharedSecretString,
// "ilovecodingilovecodingilovecodingilovecodingilovecodingilovecodingilovecodingilovecoding" +
// "ilovecodingilovecodingsuygdygyegdw".getBytes(StandardCharsets.UTF_8));
// System.out.println("!!!: "+res);
// String raw=AESHelperForConnection.decryptWithAES(mSharedSecretString,res);
// System.out.println("!!!raw: "+raw);
// 代理地址(?)
if(!TextUtils.isEmpty(proxyHostName)) {
@@ -176,9 +187,72 @@ public class MINVpnConnection implements Runnable{
return;
}
// TestTransferData(face);
// 3. 进行数据中转操作
transferData(face);
}
// 测试加解密
private void TestTransferData(LogicFace face){
FileInputStream inputStream=new FileInputStream(
this.mParcelFileDescriptor.getFileDescriptor());
FileOutputStream outputStream=new FileOutputStream(
this.mParcelFileDescriptor.getFileDescriptor());
ByteBuffer buff1 = ByteBuffer.allocate(MAX_PACKET_SIZE);
ByteBuffer buff2 = ByteBuffer.allocate(MAX_PACKET_SIZE);
Thread recvFromTunAndSendThread = new Thread(() -> {
// while (!this.stop) {
buff1.clear();
buff2.clear();
int readLen = 0;
int encryptedLen;
// 1. 读取tun网卡数据,放入buff1
try {
readLen = inputStream.read(buff1.array(), 0, MAX_PACKET_SIZE);
} catch (Exception e) {
e.printStackTrace();
// break;
}
if (readLen > 0) {
System.out.println("read from tun , readLen = " + readLen);
buff1.position(0);
buff1.limit(readLen);
// 2. 对数据做AES加密,然后将服务器分配的地址[allocatedAddress]和加密数据一起放入buff2
buff2.put(Objects.requireNonNull(IPPackageUtil.StringAddress2byteAddress(allocatedAddress)));
byte[] ipPackageData = new byte[readLen];
System.arraycopy(buff1.array(), 0, ipPackageData, 0, readLen);
System.out.println("mSharedSecretString length: "+mSharedSecretString.length());
System.out.println("raw ipPackageData: "+ Arrays.toString(ipPackageData));
System.out.println("raw ipPackageData: "+ new String(ipPackageData));
System.out.println("raw ipPackageData len: "+ ipPackageData.length);
// System.out.println("realSecret length: "+realSecret.length);
// byte[] encrytedIPPackage = SM4HelperForConnection.encryptWithSM4(realSecret, ipPackageData);
byte[] encrytedIPPackage = AESHelperForConnection.encryptWithAES(mSharedSecretString, ipPackageData);
if(encrytedIPPackage==null){
System.out.println("AES加密错误!!!");
return;
}
System.out.println("encryptedIPPackage len: " + encrytedIPPackage.length);
System.out.println("encryptedIPPackage: "+ Arrays.toString(encrytedIPPackage));
System.out.println("encryptedIPPackage: "+ new String(encrytedIPPackage));
System.out.println("buff2 position: " + buff2.position());
buff2.put(encrytedIPPackage);
encryptedLen = buff2.position();
buff2.position(0);
buff2.limit(encryptedLen);
// 3. 将buff2通过face发送出去
sendInterestPkt(face, buff2,encryptedLen);
}
// }
});
recvFromTunAndSendThread.start();
}
/**
* 双线程中转数据
@@ -219,13 +293,15 @@ public class MINVpnConnection implements Runnable{
byte[] ipPackageData = new byte[readLen];
System.arraycopy(buff1.array(), 0, ipPackageData, 0, readLen);
System.out.println("mSharedSecretString length: "+mSharedSecretString.length());
System.out.println("realSecret length: "+realSecret.length);
byte[] encrytedIPPackage = SM4HelperForConnection.encryptWithSM4(realSecret, ipPackageData);
// System.out.println("realSecret length: "+realSecret.length);
// byte[] encrytedIPPackage = SM4HelperForConnection.encryptWithSM4(realSecret, ipPackageData);
byte[] encrytedIPPackage = AESHelperForConnection.encryptWithAES(mSharedSecretString, ipPackageData);
if(encrytedIPPackage==null){
System.out.println("sm4加密错误!!!");
System.out.println("AES加密错误!!!");
return;
}
System.out.println("encryptedIPPackage len: " + encrytedIPPackage.length);
System.out.println("encryptedIPPackage: "+ Arrays.toString(encrytedIPPackage));
System.out.println("buff2 position: " + buff2.position());
buff2.put(encrytedIPPackage);
encryptedLen = buff2.position();
@@ -251,7 +327,7 @@ public class MINVpnConnection implements Runnable{
// 2. 接收服务器返回的数据包,放入buf2
CPacket interest;
try {
interest = face.receiveCPacket(0);
interest = face.receiveCPacket(10000);
}catch (Exception e){
continue;
}
@@ -266,8 +342,8 @@ public class MINVpnConnection implements Runnable{
byte[] decrpytedIPPackage = new byte[buf2.position()];
System.arraycopy(buf2.array(), 0, decrpytedIPPackage, 0, buf2.position());
ByteBuffer buf3 = ByteBuffer.allocate(5000);
// buf3.put(Objects.requireNonNull(AESHelperForConnection.decryptWithAES(mSharedSecretString, decrpytedIPPackage)));
buf3.put(Objects.requireNonNull(SM4HelperForConnection.decryptWithSM4(realSecret, decrpytedIPPackage)));
buf3.put(Objects.requireNonNull(AESHelperForConnection.decryptWithAES(mSharedSecretString, decrpytedIPPackage)));
// buf3.put(Objects.requireNonNull(SM4HelperForConnection.decryptWithSM4(realSecret, decrpytedIPPackage)));
int decryptedDataLen = buf3.position();
byte firstByte = buf3.get(0);
if (firstByte == 0) {
@@ -374,7 +450,7 @@ public class MINVpnConnection implements Runnable{
// 构造兴趣包负载字段:加密密钥 & 本地前缀
ByteBuffer requestBuf = ByteBuffer.allocate(1024);
byte len= ByteHelper.uint8ToByte(mEncryptedAESSeed.length);
requestBuf.put((byte) 1).put(len).put(mEncryptedAESSeed).put(fuck.getBytes()).flip();
requestBuf.put((byte) 4).put(len).put(mEncryptedAESSeed).put(fuck.getBytes()).flip();
// requestBuf.put((byte) 1).put(len).put(mEncryptedAESSeed).put(this.localPrefix.getBytes()).flip();
// 构造目的标识:/{service prefix}/{cPacket seq}/{defraudString}
Identifier serverIdentifier;
@@ -30,6 +30,7 @@ import com.pkusz.min_vpn_client.model.MINVpnSettingAPI;
import com.pkusz.min_vpn_client.model.event.ConnectEvent;
import com.pkusz.min_vpn_client.model.event.TimeoutEvent;
import com.pkusz.min_vpn_client.utils.RSACryptoForConnection;
import com.pkusz.min_vpn_client.utils.SM4HelperForConnection;
import org.greenrobot.eventbus.EventBus;
@@ -141,7 +142,8 @@ public class MINVpnService extends VpnService implements Handler.Callback{
final String server = MINVpnSettingAPI.INSTANCE.getMirIpAddress();
final int port = MINVpnSettingAPI.INSTANCE.getMirPort();
// 生成消息加密密钥
final byte[] secret = RSACryptoForConnection.getRandomAESSeed().PlainSeed.getBytes();
// final byte[] secret = RSACryptoForConnection.getRandomAESSeed().PlainSeed.getBytes();
final byte[] secret = SM4HelperForConnection.getRandomSeed(); // 获取随机16位长度密钥,用于对称加密
// 权限控制集合(并不知道为啥弄这个,我只是继承了由多人零零散散写、改了一年的客户端代码。)
final boolean allow = false;
final Set<String> packages = new HashSet<>();
@@ -5,8 +5,10 @@ import android.os.Build;
import androidx.annotation.RequiresApi;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
@@ -35,6 +37,8 @@ public class AESHelperForConnection {
byte[] plaintext = message.getBytes();
byte[] result = ecipher.doFinal(plaintext, 0, plaintext.length);
System.out.println("!!!aes res: "+ Arrays.toString(result));
System.out.println("!!!aes res: "+ new String(result));
Base64.Encoder encoder = Base64.getEncoder();
// return Base64.encodeToString(result, Base64.DEFAULT);
return encoder.encodeToString(result);
@@ -44,6 +48,11 @@ public class AESHelperForConnection {
return null;
}
// @RequiresApi(api = Build.VERSION_CODES.O)
// public static byte[] encryptWithAES(String key, byte[] plaintext) {
// return encryptWithAES(key,new String(plaintext)).getBytes(StandardCharsets.UTF_8);
// }
// AES without base64 encrypt
public static byte[] encryptWithAES(String key, byte[] plaintext) {
try {