Logo 300 406cf2a4135690a879d66987aca1ce97c723a4a6103297b858557a4997423ccf
vpn客户端实现 日薪制

【需求】 实现iOS上的vpn建连,简单的界面展示,功能封装成为lib 和vpn中间服务器建连,实现iOS全局VPN。 连接过程简述: iOS上读取公钥加密一个36字节的指纹(Android实现使用MAC,IMSI,IMEI产生),经过AES加密UDP发给vpn服务器,然后等待读取返回的vpn参数,设置vpn连接。 【Android端参考程序】 //与vpn服务器连接握手程序 private void handshake(DatagramChannel tunnel) throws Exception { // Allocate the buffer for handshaking. ByteBuffer packet = ByteBuffer.allocate(1032); byte[] prepareBuf = new byte[68]; InputStream isPub = getResources().openRawResource(R.raw.xpublic); //InputStream isPemPub = getResources().openRawResource(R.raw.pempublic); getDeviceInfo(); ByteBuffer certHeader = ByteBuffer.allocate(144); // Send the secret several times in case of packet loss. byte[] ID = new byte[36],LogonData = new byte[144]; String PubKey = mToolSet.readKey(isPub); mToolSet.absorbByteArray(ID,0,mWifiMac); mToolSet.absorbByteArray(ID,6,mIMSI); mToolSet.absorbByteArray(ID,21,mIMEI); //android java实现 if(useJava) { if (mToolSet.vpnLogonData(ID,PubKey,LogonData)){ certHeader.put(LogonData); for (int i = 0; i < 3; ++i) { certHeader.position(0); tunnel.write(certHeader); } } } else { //C lib实现 //String PemPubKey = mToolSet.readKey(isPemPub); //VpnJni.vpnLogonData(ID,PemPubKey,LogonData); } // Wait for the parameters within a limited time. for (int i = 0; i < 50; ++i) { Thread.sleep(100); // Normally we should not receive random packets. int length = tunnel.read(packet); if (length > 0 ) { byte[] InData = new byte[length]; packet.flip(); packet.get(InData); byte[] ParamData = new byte[InData.length]; int Ret = mToolSet.vpnInputData(InData,ParamData); if(1 == Ret) configure(new String(ParamData).trim()); else continue; return; } } Log.e(TAG,"error throw time out exception"); throw new IllegalStateException("Timed out"); } //AES解码vpn服务器返回的链接参数 public boolean vpnLogonData(byte[] ID,String PubKey,byte[] LogonData) { mAesKey = new byte[AES_KEY_SIZE]; mAesIv = new byte[AES_KEY_SIZE]; byte[] prepareBuf = new byte[68]; mAesKey = GenerateRandom(AES_KEY_SIZE); mAesIv = GenerateRandom(AES_KEY_SIZE); absorbByteArray(prepareBuf,0,mAesKey); absorbByteArray(prepareBuf,16,mAesIv); absorbByteArray(prepareBuf,32,ID); PublicKey pubKey=null; try{ pubKey = loadPublicKey(PubKey); } catch (Exception e){ e.printStackTrace(); } byte[] encryptedArray = encryptData(prepareBuf, pubKey); ByteBuffer certHeader = ByteBuffer.allocate(144); certHeader.putInt(0x20070811); certHeader.putInt(encryptedArray.length); certHeader.put(encryptedArray); certHeader.putInt((int) 0); int CRCheck = GetCrc32(encryptedArray); certHeader.putInt((int)CRCheck); certHeader.position(0); certHeader.get(LogonData, 0, LogonData.length); return true; } public int vpnInputData(byte[] Encrypted,byte[] Blank) throws Exception { int CRCheck =0; byte[] MagicNumber = copyOfRange(Encrypted,0,4); byte[] TailCheckSum = copyOfRange(Encrypted,Encrypted.length-4,Encrypted.length); byte[] Param = copyOfRange(Encrypted,4,Encrypted.length - 4); byte[] newAesIv = mAesIv.clone(); byte[] newPacket = null; try { newPacket = AesDecodeBuf(mAesKey,newAesIv,Param); } catch(Exception e){ e.printStackTrace(); } CRCheck = GetCrc32(Param); int CalcChecksum = byteArrayToInt(TailCheckSum); if(CRCheck != CalcChecksum){ throw new Exception("bad checksum"); } absorbByteArray(Blank,0,newPacket); int MagicInt = byteArrayToInt(MagicNumber); if(0x19750118 == MagicInt){ return 1; } else if(0x19770718 == MagicInt){ return 2; } return 3; }

Small dffd5309cb7857a2d66ff61b3295678d
昵称登录后显示 4 个月前发布
公司登录后显示

预估 8000 元

已有3人投递

我是技术人才
我在寻找兼职工作

申请成为技术顾问

我是创业者
我在寻找技术人才

发布用人需求