mirror of
https://gitee.com/willfree/min-vpn-client_v2.git
synced 2026-06-03 15:36:14 +08:00
尝试了各种方法,没有解决安卓与jre的javax.encrypto冲突的问题,下周准备返璞归真,不使用sm4而重新使用aes进行对称加密通信
This commit is contained in:
+12
-3
@@ -34,7 +34,7 @@ android {
|
||||
}
|
||||
|
||||
compileSdkVersion 30
|
||||
buildToolsVersion "30.0.3"
|
||||
buildToolsVersion '30.0.3'
|
||||
|
||||
sourceSets.main.jniLibs.srcDirs = ['libs']
|
||||
|
||||
@@ -75,8 +75,17 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation files('libs\\gmhelper.jar')
|
||||
implementation files('libs\\BaiduLBS_Android.jar')
|
||||
implementation files('libs/gmhelper.jar')
|
||||
implementation files('libs/BaiduLBS_Android.jar')
|
||||
implementation files('libs/vpnjce-1.0.jar')
|
||||
|
||||
// 在依赖中添加对jre的依赖,以尝试解决android.jar中原生javax与java中的javax的冲突问题
|
||||
//noinspection GradlePath
|
||||
// implementation files('C:/MyEnv/Java/jdk1.8.0_301/jre/lib/rt.jar')
|
||||
// compileOnly files('C:/MyEnv/Java/jdk1.8.0_301/jre/lib/rt.jar')
|
||||
// implementation files('C:/MyEnv/Java/jdk1.8.0_301/jre/lib/jce.jar')
|
||||
// compileOnly files('C:/MyEnv/Java/jdk1.8.0_301/jre/lib/jce.jar')
|
||||
// implementation files('libs\\jce.jar')
|
||||
|
||||
// testImplementation 'junit:junit:4.+'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
|
||||
Binary file not shown.
@@ -18,14 +18,12 @@ 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.RSACryptoForConnection;
|
||||
import com.pkusz.min_vpn_client.utils.RuleUtil;
|
||||
import com.pkusz.min_vpn_client.utils.SM2HelperForConnection;
|
||||
import com.pkusz.min_vpn_client.utils.SM3HelperForConnection;
|
||||
import com.pkusz.min_vpn_client.utils.SM4HelperForConnection;
|
||||
import com.pkusz.min_vpn_client.utils.SafetyInfoUtil;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
@@ -43,8 +41,6 @@ import logicface.LogicFace;
|
||||
import logicface.LogicFaceException;
|
||||
import mgmt.RegisterPrefixHelper;
|
||||
import packet.CPacket;
|
||||
import packet.Data;
|
||||
import packet.Interest;
|
||||
import packet.PacketException;
|
||||
import util.ByteHelper;
|
||||
|
||||
@@ -71,6 +67,8 @@ public class MINVpnConnection implements Runnable{
|
||||
private final byte[] mSharedSecret;
|
||||
private final String mSharedSecretString;
|
||||
private byte[] mEncryptedAESSeed;
|
||||
// 实际使用的密钥是:随机产生的密钥经过sm3哈希,取前16字节
|
||||
private byte[] realSecret;
|
||||
|
||||
// 代理地址 todo:??
|
||||
private String mProxyHostName;
|
||||
@@ -80,7 +78,7 @@ public class MINVpnConnection implements Runnable{
|
||||
private final boolean mAllow;
|
||||
private final Set<String> mPackages;
|
||||
|
||||
// todo: ??
|
||||
// 服务器给客户端的tun网卡分配的IP地址
|
||||
private String allocatedAddress;
|
||||
|
||||
// 待决Intent、回调函数(建立连接成功;建立连接失败;长时间不操作的超时回调)
|
||||
@@ -127,8 +125,11 @@ public class MINVpnConnection implements Runnable{
|
||||
mServerPort=serverPort;
|
||||
mSharedSecret=sharedSecret;
|
||||
mSharedSecretString=new String(mSharedSecret);
|
||||
// mEncryptedAESSeed= RSACryptoForConnection.encrypt5(mSharedSecretString);
|
||||
mEncryptedAESSeed= SM2HelperForConnection.encrypt(mSharedSecretString);
|
||||
mEncryptedAESSeed= SM2HelperForConnection.encryptWithSM2(mSharedSecretString);
|
||||
realSecret= SM3HelperForConnection.getSM3Hash16(mSharedSecret);
|
||||
|
||||
// 测试sm4
|
||||
SM4HelperForConnection.encryptWithSM4(realSecret, "sss".getBytes());
|
||||
|
||||
// 代理地址(?)
|
||||
if(!TextUtils.isEmpty(proxyHostName)) {
|
||||
@@ -218,7 +219,12 @@ 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());
|
||||
byte[] encrytedIPPackage = SM4HelperForConnection.encryptWithSM4(mSharedSecretString, ipPackageData);
|
||||
System.out.println("realSecret length: "+realSecret.length);
|
||||
byte[] encrytedIPPackage = SM4HelperForConnection.encryptWithSM4(realSecret, ipPackageData);
|
||||
if(encrytedIPPackage==null){
|
||||
System.out.println("sm4加密错误!!!");
|
||||
return;
|
||||
}
|
||||
System.out.println("encryptedIPPackage len: " + encrytedIPPackage.length);
|
||||
System.out.println("buff2 position: " + buff2.position());
|
||||
buff2.put(encrytedIPPackage);
|
||||
@@ -243,7 +249,12 @@ public class MINVpnConnection implements Runnable{
|
||||
// face.registerIdentifier(new Identifier(this.localPrefix),5000,helper);
|
||||
|
||||
// 2. 接收服务器返回的数据包,放入buf2
|
||||
CPacket interest = face.receiveCPacket(-1);
|
||||
CPacket interest;
|
||||
try {
|
||||
interest = face.receiveCPacket(0);
|
||||
}catch (Exception e){
|
||||
continue;
|
||||
}
|
||||
System.out.println("recv interest packet, name : " + interest.getSrcIdentifier().toString());
|
||||
System.out.println("兴趣包中装的数据长度 : " + interest.payload.getValue().length);
|
||||
int dataLen = interest.payload.getValue().length;
|
||||
@@ -256,7 +267,7 @@ public class MINVpnConnection implements Runnable{
|
||||
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(mSharedSecretString, decrpytedIPPackage)));
|
||||
buf3.put(Objects.requireNonNull(SM4HelperForConnection.decryptWithSM4(realSecret, decrpytedIPPackage)));
|
||||
int decryptedDataLen = buf3.position();
|
||||
byte firstByte = buf3.get(0);
|
||||
if (firstByte == 0) {
|
||||
@@ -270,7 +281,7 @@ public class MINVpnConnection implements Runnable{
|
||||
System.out.println("transfer data error: outputStream.write error");
|
||||
}
|
||||
}
|
||||
} catch (SecurityException | LogicFaceException e) {
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("transfer data error: recvFromServerAndReadThread.start error");
|
||||
}
|
||||
|
||||
@@ -22,4 +22,6 @@ public class IPPackageUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public class SM2HelperForConnection {
|
||||
// return enRes;
|
||||
// }
|
||||
|
||||
public static byte[] encrypt(String data){
|
||||
public static byte[] encryptWithSM2(String data){
|
||||
byte[] enRes;
|
||||
try {
|
||||
enRes = BC_KeyManager.sm2encrypt(pubkey_ForNewVPN.getBytes(StandardCharsets.UTF_8),
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.pkusz.min_vpn_client.utils;
|
||||
/*
|
||||
* @Author: Wang Feng
|
||||
* @Description:
|
||||
* @Version: 1.0.0
|
||||
* @Date: 10:07 2021/7/22
|
||||
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
|
||||
*/
|
||||
|
||||
import org.zz.gmhelper.SM3Util;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class SM3HelperForConnection {
|
||||
/**
|
||||
* 将传入参数使用sm3做哈希,然后返回前16个字节
|
||||
* @param randBytes
|
||||
* @return
|
||||
*/
|
||||
public static byte[] getSM3Hash16(byte[] randBytes){
|
||||
System.out.println("sm3哈希之前的密钥:"+new String(randBytes));
|
||||
byte[] hashRes=SM3Util.hash(randBytes);
|
||||
byte[] res=new byte[16];
|
||||
System.arraycopy(hashRes,0,res,0,16);
|
||||
System.out.println("sm3哈希得到的密钥:"+res.length+" , "+new String(res));
|
||||
System.out.println("sm3哈希得到的密钥:"+Arrays.toString(res));
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,15 @@ package com.pkusz.min_vpn_client.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import com.pkusz.min_vpn_client.utils.gmutil.sm4.VPN_SM4;
|
||||
|
||||
import org.zz.gmhelper.SM4Util;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
@@ -20,6 +25,7 @@ import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
|
||||
import VMSConnection.Security.BC_KeyManager;
|
||||
import VMSConnection.Security.SM4.BC_SM4;
|
||||
|
||||
public class SM4HelperForConnection {
|
||||
public static byte[] encryptWithSM4(String secret,byte[] rawText){
|
||||
@@ -40,6 +46,38 @@ public class SM4HelperForConnection {
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] encryptWithSM4(byte[] secretkey, byte[] origData) {
|
||||
// try {
|
||||
// return VPN_SM4.encrypt_ECB_Padding(secretkey, origData);
|
||||
// } catch (Exception e){
|
||||
// e.printStackTrace();
|
||||
// return null;
|
||||
// }
|
||||
try {
|
||||
return SM4Util.encrypt_ECB_Padding(secretkey,origData);
|
||||
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] decryptWithSM4(byte[] secretkey, byte[] crypted){
|
||||
// System.out.println("sec: " + secretkey);
|
||||
// System.out.println("cry: " + Arrays.toString(crypted));
|
||||
// try {
|
||||
// return VPN_SM4.decrypt_ECB_Padding(secretkey, crypted);
|
||||
// } catch (Exception e){
|
||||
// e.printStackTrace();
|
||||
// return null;
|
||||
// }
|
||||
try {
|
||||
return SM4Util.decrypt_ECB_Padding(secretkey,crypted);
|
||||
} catch (IllegalBlockSizeException | BadPaddingException | InvalidKeyException | NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取长度为16字节的随机种子/随机密钥
|
||||
* @return
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
package com.pkusz.min_vpn_client.utils.gmutil.sm4;
|
||||
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import javax.vpncrypto.*;
|
||||
import javax.vpncrypto.spec.IvParameterSpec;
|
||||
import javax.vpncrypto.spec.SecretKeySpec;
|
||||
import java.security.*;
|
||||
|
||||
/*
|
||||
* @Author: hongyu guo
|
||||
* @Description: sm4算法
|
||||
* 解尝试解决报错:Provider BC does not provide SM4/ECB/PKCS5Padding
|
||||
*
|
||||
* @Version: 1.0.0
|
||||
* @Date: 16:26 2021/03/04
|
||||
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
|
||||
*/
|
||||
public class VPN_SM4 {
|
||||
static {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
public static final String ALGORITHM_NAME = "SM4";
|
||||
public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";
|
||||
public static final String ALGORITHM_NAME_ECB_NOPADDING = "SM4/ECB/NoPadding";
|
||||
public static final String ALGORITHM_NAME_CBC_PADDING = "SM4/CBC/PKCS5Padding";
|
||||
public static final String ALGORITHM_NAME_CBC_NOPADDING = "SM4/CBC/NoPadding";
|
||||
|
||||
/**
|
||||
* SM4算法目前只支持128位(即密钥16字节)
|
||||
*/
|
||||
public static final int DEFAULT_KEY_SIZE = 128;
|
||||
|
||||
/**
|
||||
* 生成16字节的sm4 key
|
||||
* @param
|
||||
* @return byte[]
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @author hongyu guo
|
||||
* @date 2021/3/15
|
||||
**/
|
||||
public static byte[] generateKey() throws NoSuchAlgorithmException, NoSuchProviderException {
|
||||
return generateKey(DEFAULT_KEY_SIZE);
|
||||
}
|
||||
|
||||
public static byte[] generateKey(int keySize) throws NoSuchAlgorithmException, NoSuchProviderException {
|
||||
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
|
||||
kg.init(keySize, new SecureRandom());
|
||||
return kg.generateKey().getEncoded();
|
||||
}
|
||||
|
||||
public static byte[] encrypt_ECB_Padding(byte[] key, byte[] data)
|
||||
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
|
||||
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
|
||||
Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);
|
||||
return cipher.doFinal(data);
|
||||
}
|
||||
|
||||
public static byte[] decrypt_ECB_Padding(byte[] key, byte[] cipherText)
|
||||
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
|
||||
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
|
||||
Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);
|
||||
return cipher.doFinal(cipherText);
|
||||
}
|
||||
|
||||
public static byte[] encrypt_ECB_NoPadding(byte[] key, byte[] data)
|
||||
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
|
||||
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
|
||||
Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_NOPADDING, Cipher.ENCRYPT_MODE, key);
|
||||
return cipher.doFinal(data);
|
||||
}
|
||||
|
||||
public static byte[] decrypt_ECB_NoPadding(byte[] key, byte[] cipherText)
|
||||
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
|
||||
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
|
||||
Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_NOPADDING, Cipher.DECRYPT_MODE, key);
|
||||
return cipher.doFinal(cipherText);
|
||||
}
|
||||
|
||||
public static byte[] encrypt_CBC_Padding(byte[] key, byte[] iv, byte[] data)
|
||||
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
|
||||
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException,
|
||||
InvalidAlgorithmParameterException {
|
||||
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_PADDING, Cipher.ENCRYPT_MODE, key, iv);
|
||||
return cipher.doFinal(data);
|
||||
}
|
||||
|
||||
public static byte[] decrypt_CBC_Padding(byte[] key, byte[] iv, byte[] cipherText)
|
||||
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
|
||||
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
|
||||
InvalidAlgorithmParameterException {
|
||||
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_PADDING, Cipher.DECRYPT_MODE, key, iv);
|
||||
return cipher.doFinal(cipherText);
|
||||
}
|
||||
|
||||
public static byte[] encrypt_CBC_NoPadding(byte[] key, byte[] iv, byte[] data)
|
||||
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
|
||||
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException,
|
||||
InvalidAlgorithmParameterException {
|
||||
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_NOPADDING, Cipher.ENCRYPT_MODE, key, iv);
|
||||
return cipher.doFinal(data);
|
||||
}
|
||||
|
||||
public static byte[] decrypt_CBC_NoPadding(byte[] key, byte[] iv, byte[] cipherText)
|
||||
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
|
||||
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
|
||||
InvalidAlgorithmParameterException {
|
||||
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_NOPADDING, Cipher.DECRYPT_MODE, key, iv);
|
||||
return cipher.doFinal(cipherText);
|
||||
}
|
||||
|
||||
private static Cipher generateECBCipher(String algorithmName, int mode, byte[] key)
|
||||
throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
|
||||
InvalidKeyException {
|
||||
Cipher cipher = null;
|
||||
try {
|
||||
cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
|
||||
cipher.init(mode, sm4Key);
|
||||
return cipher;
|
||||
}
|
||||
|
||||
private static Cipher generateCBCCipher(String algorithmName, int mode, byte[] key, byte[] iv)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException,
|
||||
NoSuchProviderException, NoSuchPaddingException {
|
||||
Cipher cipher = null;
|
||||
try {
|
||||
cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
|
||||
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
|
||||
cipher.init(mode, sm4Key, ivParameterSpec);
|
||||
return cipher;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user