增加sm4对称加密的支持

This commit is contained in:
free will committed 2021-08-03 16:13:25 +08:00
1 parent 902f17edec
commit 87a3f669f5
2 files changed
+41 -23

No files matched your search

@@ -19,11 +19,12 @@ 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.Base64Util;
import com.pkusz.min_vpn_client.utils.IPPackageUtil;
import com.pkusz.min_vpn_client.utils.KeyManager;
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.gmutil.sm4.Android_SM4;
import java.io.FileInputStream;
@@ -78,6 +79,8 @@ public class MINVpnConnection implements Runnable{
private final byte[] mSharedSecret;
private final String mSharedSecretString;
private byte[] mEncryptedAESSeed;
private boolean isSM4;
private byte[] realSecret; // => sm4做对称加密时的真实密钥。由mSharedSecret经sm3哈希得到。
// 代理地址 todo:??
private String mProxyHostName;
@@ -117,16 +120,21 @@ public class MINVpnConnection implements Runnable{
* @param proxyHostPort
* @param allow
* @param packages
* @param isSM4 => 是否使用sm4做对称加密通信。false时,则使用AES做对称加密。
*/
@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 Set<String> packages,
final boolean isSM4) {
// VPNService 及 连接ID
mService=service;
mConnectionId=connectionId;
// 使用SM4做对称加密,还是AES做对称加密
this.isSM4=isSM4;
// 服务器地址 及 密钥
mServerName=serverName;
mServerPort=serverPort;
@@ -134,7 +142,11 @@ public class MINVpnConnection implements Runnable{
mSharedSecretString=new String(mSharedSecret);
System.out.println("mSharedSecretString: "+mSharedSecretString);
mEncryptedAESSeed= SM2HelperForConnection.encryptWithSM2(mSharedSecretString);
// realSecret= SM3HelperForConnection.getSM3Hash16(mSharedSecret);
if(isSM4) {
realSecret= SM3HelperForConnection.getSM3Hash16(mSharedSecret);
System.out.println("对称加密方式为sm4,其实际加密密钥为: "+ new String(realSecret)
+" , len: "+realSecret.length);
}
// 测试AES
// System.out.println("!!!密钥:"+mSharedSecretString);
@@ -146,19 +158,19 @@ public class MINVpnConnection implements Runnable{
// System.out.println("!!!raw: "+raw);
// 测试SM4
try {
byte[] enc= Android_SM4.encrypt_ECB_Padding("1234567812345678".getBytes(StandardCharsets.UTF_8),
"wefree".getBytes(StandardCharsets.UTF_8));
System.out.println("enc: "+Arrays.toString(enc));
System.out.println("enc: "+new String(enc));
byte[] dec= Android_SM4.decrypt_ECB_Padding("1234567812345678".getBytes(StandardCharsets.UTF_8),
enc);
System.out.println("dec: "+Arrays.toString(dec));
System.out.println("dec: "+new String(dec));
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchProviderException
| NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
}
// try {
// byte[] enc= Android_SM4.encrypt_ECB_Padding("1234567812345678".getBytes(StandardCharsets.UTF_8),
// "wefree".getBytes(StandardCharsets.UTF_8));
// System.out.println("enc: "+Arrays.toString(enc));
// System.out.println("enc: "+new String(enc));
// byte[] dec= Android_SM4.decrypt_ECB_Padding("1234567812345678".getBytes(StandardCharsets.UTF_8),
// enc);
// System.out.println("dec: "+Arrays.toString(dec));
// System.out.println("dec: "+new String(dec));
// } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchProviderException
// | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e) {
// e.printStackTrace();
// }
// 代理地址(?)
if(!TextUtils.isEmpty(proxyHostName)) {
@@ -282,10 +294,14 @@ public class MINVpnConnection implements Runnable{
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);
byte[] encrytedIPPackage = AESHelperForConnection.encryptWithAES(mSharedSecretString, ipPackageData);
byte[] encrytedIPPackage;
if(isSM4) {
encrytedIPPackage = SM4HelperForConnection.encryptWithSM4(realSecret, ipPackageData);
}else {
encrytedIPPackage = AESHelperForConnection.encryptWithAES(mSharedSecretString, ipPackageData);
}
if(encrytedIPPackage==null){
System.out.println("AES加密错误!!!");
System.out.println("对称加密错误!!! 对称加密是否为sm4: "+isSM4);
return;
}
System.out.println("encryptedIPPackage len: " + encrytedIPPackage.length);
@@ -328,8 +344,11 @@ public class MINVpnConnection implements Runnable{
ByteBuffer buf3 = ByteBuffer.allocate(5000);
// System.out.println("要解密啦,要解密的包是:"+ Arrays.toString(decrpytedIPPackage));
// System.out.println("要解密啦,要解密的包长度是:"+decrpytedIPPackage.length);
buf3.put(Objects.requireNonNull(AESHelperForConnection.decryptWithAES(mSharedSecretString, decrpytedIPPackage)));
// buf3.put(Objects.requireNonNull(SM4HelperForConnection.decryptWithSM4(realSecret, decrpytedIPPackage)));
if(isSM4) {
buf3.put(Objects.requireNonNull(SM4HelperForConnection.decryptWithSM4(realSecret, decrpytedIPPackage)));
}else{
buf3.put(Objects.requireNonNull(AESHelperForConnection.decryptWithAES(mSharedSecretString, decrpytedIPPackage)));
}
// System.out.println("解密结果:"+ Arrays.toString(buf3.array()));
// System.out.println("解密结果-len:"+ buf3.position());
int decryptedDataLen = buf3.position();
@@ -29,7 +29,6 @@ import com.pkusz.min_vpn_client.activity.main.MainActivity;
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;
@@ -154,7 +153,7 @@ public class MINVpnService extends VpnService implements Handler.Callback{
minVpnConnection = new MINVpnConnection(
this, mNextConnectionId.getAndIncrement(), server, port, secret,
proxyHost, proxyPort, allow, packages);
proxyHost, proxyPort, allow, packages,false);
// 对vpn connection进行各种监听设置,并启动执行其run函数
startConnection(minVpnConnection);