Skip to content

Commit 6ef3193

Browse files
authored
Merge pull request dawei101#43 from dawei101/dawei/rc4md5_n_chacha20
Dawei/rc4md5 n chacha20
2 parents ed7d2da + 4b375a7 commit 6ef3193

File tree

12 files changed

+219
-37
lines changed

12 files changed

+219
-37
lines changed

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ Last release: [Download](https://github.com/dawei101/shadowsocks-android-java/re
66

77
本版本为shadowsocks android版的纯java版本
88

9-
因为实现原理的缘故,会牺牲掉很多功能(比如dns解析),虽然省电,但在速度有明显不足。建议作为玩具使用。
10-
11-
This version of shadowsocks for android is pure java version,take it as a toy please.
9+
因为实现原理的缘故,会牺牲掉很多功能(比如dns解析).
10+
This version of shadowsocks for android is pure java version.
1211

1312

1413
代码多整理自 [smartproxy](https://github.com/hedaode/SmartProxy)[shadowsocks-java](https://github.com/blakey22/shadowsocks-java)
@@ -33,11 +32,11 @@ ss://base64encode(method:password@host:port)
3332

3433
And also it inherited the support of http(s) proxy from Smartproxy , Set the url as stardand http(s) proxy format when use it.
3534

36-
http(s)代理格式
35+
http代理格式
3736

38-
http(s)proxy foramt:
37+
http proxy foramt:
3938
```
40-
http(s)://(username:passsword)@host:port
39+
http://(username:passsword)@host:port
4140
```
4241

4342
支持的加密类型:
@@ -56,6 +55,9 @@ aes-256-ofb
5655
camellia-128-cfb
5756
camellia-192-cfb
5857
camellia-256-cfb
58+
chacha20
59+
chacha20-ietf
60+
rc4-md5
5961
```
6062

6163
### 兄弟版本 Brother version

app/build.gradle

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@ buildscript {
66
mavenCentral()
77
}
88
dependencies {
9-
classpath 'com.android.tools.build:gradle:2.1.0'
9+
classpath 'com.android.tools.build:gradle:2.3.3'
1010
}
1111
}
1212

1313
android {
14-
compileSdkVersion 25
15-
buildToolsVersion "23.0.1"
14+
compileSdkVersion 26
15+
buildToolsVersion '26.0.1'
1616
useLibrary 'org.apache.http.legacy'
1717

1818
defaultConfig {
1919
applicationId "com.vm.shadowsocks"
2020
minSdkVersion 15
21-
targetSdkVersion 25
21+
targetSdkVersion 26
2222
versionCode 1
23-
versionName "1.1"
23+
versionName "1.2"
2424
}
2525
buildTypes {
2626
release {
@@ -39,16 +39,15 @@ repositories {
3939
}
4040

4141
dependencies {
42-
compile fileTree(dir: 'libs', include: ['*.jar'])
42+
compile fileTree(include: ['*.jar'], dir: 'libs')
43+
4344
testCompile 'junit:junit:4.12'
45+
4446
compile 'com.embarkmobile:zxing-android-minimal:2.0.0@aar'
4547
compile 'com.embarkmobile:zxing-android-integration:2.0.0@aar'
4648
compile 'com.google.zxing:core:3.0.1'
47-
compile 'org.bouncycastle:bcprov-jdk15on:1.52'
49+
50+
compile 'org.bouncycastle:bcprov-jdk15on:1.57'
4851
compile 'com.futuremind.recyclerfastscroll:fastscroll:0.2.5'
4952
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
50-
compile('com.googlecode.json-simple:json-simple:1.1.1') {
51-
exclude group: 'junit', module: 'junit'
52-
exclude group: 'org.hamcrest', module: 'hamcrest-core'
53-
}
5453
}

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
<uses-permission android:name="android.permission.INTERNET" />
66
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
7+
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
78

89
<application
910
android:allowBackup="true"

app/src/main/java/com/vm/shadowsocks/core/LocalVpnService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ private void runVPN() throws Exception {
246246
}
247247
onIPPacketReceived(m_IPHeader, size);
248248
}
249-
Thread.sleep(100);
249+
Thread.sleep(20);
250250
}
251251
in.close();
252252
disconnectVPN();

app/src/main/java/com/vm/shadowsocks/core/ProxyConfig.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@
2929

3030
public class ProxyConfig {
3131
public static final ProxyConfig Instance = new ProxyConfig();
32-
public final static boolean IS_DEBUG = true;
32+
public final static boolean IS_DEBUG = false;
3333
public static String AppInstallID;
3434
public static String AppVersion;
3535
public final static int FAKE_NETWORK_MASK = CommonMethods.ipStringToInt("255.255.0.0");
36-
public final static int FAKE_NETWORK_IP = CommonMethods.ipStringToInt("10.231.0.0");
36+
public final static int FAKE_NETWORK_IP = CommonMethods.ipStringToInt("172.25.0.0");
3737

3838
ArrayList<IPAddress> m_IpList;
3939
ArrayList<IPAddress> m_DnsList;
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.vm.shadowsocks.tunnel.shadowsocks;
2+
3+
import org.bouncycastle.crypto.StreamCipher;
4+
import org.bouncycastle.crypto.engines.ChaChaEngine;
5+
import org.bouncycastle.crypto.engines.ChaCha7539Engine;
6+
7+
import java.io.ByteArrayOutputStream;
8+
import java.security.InvalidAlgorithmParameterException;
9+
import java.util.HashMap;
10+
import java.util.Map;
11+
12+
import javax.crypto.SecretKey;
13+
import javax.crypto.spec.SecretKeySpec;
14+
15+
public class Chacha20Crypt extends CryptBase {
16+
public final static String CIPHER_CHACHA20 = "chacha20";
17+
public final static String CIPHER_CHACHA20_IETF = "chacha20-ietf";
18+
19+
public static Map<String, String> getCiphers() {
20+
Map<String, String> ciphers = new HashMap<>();
21+
ciphers.put(CIPHER_CHACHA20, Chacha20Crypt.class.getName());
22+
ciphers.put(CIPHER_CHACHA20_IETF, Chacha20Crypt.class.getName());
23+
return ciphers;
24+
}
25+
26+
public Chacha20Crypt(String name, String password) {
27+
super(name, password);
28+
}
29+
30+
@Override
31+
protected StreamCipher getCipher(boolean isEncrypted) throws InvalidAlgorithmParameterException {
32+
if (_name.equals(CIPHER_CHACHA20)) {
33+
return new ChaChaEngine();
34+
}
35+
else if (_name.equals(CIPHER_CHACHA20_IETF)) {
36+
return new ChaCha7539Engine();
37+
}
38+
return null;
39+
}
40+
41+
@Override
42+
protected SecretKey getKey() {
43+
return new SecretKeySpec(_ssKey.getEncoded(), "AES");
44+
45+
}
46+
47+
@Override
48+
protected void _encrypt(byte[] data, ByteArrayOutputStream stream) {
49+
int noBytesProcessed;
50+
byte[] buffer = new byte[data.length];
51+
52+
noBytesProcessed = encCipher.processBytes(data, 0, data.length, buffer, 0);
53+
stream.write(buffer, 0, noBytesProcessed);
54+
}
55+
56+
@Override
57+
protected void _decrypt(byte[] data, ByteArrayOutputStream stream) {
58+
int BytesProcessedNum;
59+
byte[] buffer = new byte[data.length];
60+
BytesProcessedNum = decCipher.processBytes(data, 0, data.length, buffer, 0);
61+
stream.write(buffer, 0, BytesProcessedNum);
62+
63+
}
64+
65+
@Override
66+
public int getKeyLength() {
67+
if (_name.equals(CIPHER_CHACHA20) || _name.equals(CIPHER_CHACHA20_IETF)) {
68+
return 32;
69+
}
70+
return 0;
71+
}
72+
73+
@Override
74+
public int getIVLength() {
75+
if (_name.equals(CIPHER_CHACHA20)) {
76+
return 8;
77+
}
78+
else if (_name.equals(CIPHER_CHACHA20_IETF)) {
79+
return 12;
80+
}
81+
return 0;
82+
}
83+
}

app/src/main/java/com/vm/shadowsocks/tunnel/shadowsocks/CryptBase.java

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@
3131

3232
package com.vm.shadowsocks.tunnel.shadowsocks;
3333

34-
import org.bouncycastle.crypto.StreamBlockCipher;
34+
import org.bouncycastle.crypto.CipherParameters;
35+
import org.bouncycastle.crypto.StreamCipher;
3536
import org.bouncycastle.crypto.params.KeyParameter;
3637
import org.bouncycastle.crypto.params.ParametersWithIV;
3738

3839
import java.io.ByteArrayOutputStream;
3940
import java.io.IOException;
4041
import java.security.InvalidAlgorithmParameterException;
42+
import java.security.MessageDigest;
4143
import java.security.SecureRandom;
4244
import java.util.concurrent.locks.Lock;
4345
import java.util.concurrent.locks.ReentrantLock;
@@ -50,14 +52,20 @@
5052
*/
5153
public abstract class CryptBase implements ICrypt {
5254

53-
protected abstract StreamBlockCipher getCipher(boolean isEncrypted) throws InvalidAlgorithmParameterException;
55+
protected abstract StreamCipher getCipher(boolean isEncrypted) throws InvalidAlgorithmParameterException;
5456

5557
protected abstract SecretKey getKey();
5658

5759
protected abstract void _encrypt(byte[] data, ByteArrayOutputStream stream);
5860

5961
protected abstract void _decrypt(byte[] data, ByteArrayOutputStream stream);
6062

63+
protected CipherParameters getCipherParameters(byte[] iv){
64+
_decryptIV = new byte[_ivLength];
65+
System.arraycopy(iv, 0, _decryptIV, 0, _ivLength);
66+
return new ParametersWithIV(new KeyParameter(_key.getEncoded()), _decryptIV);
67+
}
68+
6169
protected final String _name;
6270
protected final SecretKey _key;
6371
protected final ShadowSocksKey _ssKey;
@@ -69,8 +77,8 @@ public abstract class CryptBase implements ICrypt {
6977
protected byte[] _decryptIV;
7078
protected final Lock encLock = new ReentrantLock();
7179
protected final Lock decLock = new ReentrantLock();
72-
protected StreamBlockCipher encCipher;
73-
protected StreamBlockCipher decCipher;
80+
protected StreamCipher encCipher;
81+
protected StreamCipher decCipher;
7482
private Logger logger = Logger.getLogger(CryptBase.class.getName());
7583

7684
public CryptBase(String name, String password) {
@@ -86,26 +94,26 @@ protected void setIV(byte[] iv, boolean isEncrypt) {
8694
return;
8795
}
8896

97+
CipherParameters cipherParameters = null;
98+
8999
if (isEncrypt) {
90-
_encryptIV = new byte[_ivLength];
91-
System.arraycopy(iv, 0, _encryptIV, 0, _ivLength);
100+
cipherParameters = getCipherParameters(iv);
92101
try {
93102
encCipher = getCipher(isEncrypt);
94-
ParametersWithIV parameterIV = new ParametersWithIV(new KeyParameter(_key.getEncoded()), _encryptIV);
95-
encCipher.init(isEncrypt, parameterIV);
96103
} catch (InvalidAlgorithmParameterException e) {
97104
logger.info(e.toString());
98105
}
106+
encCipher.init(isEncrypt, cipherParameters);
99107
} else {
100108
_decryptIV = new byte[_ivLength];
101109
System.arraycopy(iv, 0, _decryptIV, 0, _ivLength);
110+
cipherParameters = getCipherParameters(iv);
102111
try {
103112
decCipher = getCipher(isEncrypt);
104-
ParametersWithIV parameterIV = new ParametersWithIV(new KeyParameter(_key.getEncoded()), _decryptIV);
105-
decCipher.init(isEncrypt, parameterIV);
106113
} catch (InvalidAlgorithmParameterException e) {
107114
logger.info(e.toString());
108115
}
116+
decCipher.init(isEncrypt, cipherParameters);
109117
}
110118
}
111119

@@ -174,4 +182,14 @@ public void decrypt(byte[] data, int length, ByteArrayOutputStream stream) {
174182
System.arraycopy(data, 0, d, 0, length);
175183
decrypt(d, stream);
176184
}
185+
186+
187+
public static byte[] md5Digest(byte[] input) {
188+
try {
189+
MessageDigest md5 = MessageDigest.getInstance("MD5");
190+
return md5.digest(input);
191+
} catch (Exception e) {
192+
throw new RuntimeException(e);
193+
}
194+
}
177195
}

app/src/main/java/com/vm/shadowsocks/tunnel/shadowsocks/CryptFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public class CryptFactory {
4848
putAll(CamelliaCrypt.getCiphers());
4949
putAll(BlowFishCrypt.getCiphers());
5050
putAll(SeedCrypt.getCiphers());
51+
putAll(Chacha20Crypt.getCiphers());
52+
putAll(Rc4Md5Crypt.getCiphers());
5153
// TODO: other crypts
5254
}};
5355
private static Logger logger = Logger.getLogger(CryptFactory.class.getName());
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.vm.shadowsocks.tunnel.shadowsocks;
2+
3+
import org.bouncycastle.crypto.CipherParameters;
4+
import org.bouncycastle.crypto.StreamCipher;
5+
import org.bouncycastle.crypto.engines.RC4Engine;
6+
import org.bouncycastle.crypto.params.KeyParameter;
7+
8+
import java.io.ByteArrayOutputStream;
9+
import java.security.InvalidAlgorithmParameterException;
10+
import java.util.HashMap;
11+
import java.util.Map;
12+
13+
import javax.crypto.SecretKey;
14+
import javax.crypto.spec.SecretKeySpec;
15+
16+
17+
public class Rc4Md5Crypt extends CryptBase {
18+
public static String CIPHER_RC4_MD5 = "rc4-md5";
19+
20+
public static Map<String, String> getCiphers() {
21+
Map<String, String> ciphers = new HashMap<String, String>();
22+
ciphers.put(CIPHER_RC4_MD5, Rc4Md5Crypt.class.getName());
23+
return ciphers;
24+
}
25+
26+
public Rc4Md5Crypt(String name, String password) {
27+
super(name, password);
28+
}
29+
30+
@Override
31+
protected StreamCipher getCipher(boolean isEncrypted) throws InvalidAlgorithmParameterException {
32+
return new RC4Engine();
33+
}
34+
35+
@Override
36+
protected SecretKey getKey() {
37+
return new SecretKeySpec(_ssKey.getEncoded(), "AES");
38+
}
39+
40+
@Override
41+
protected void _encrypt(byte[] data, ByteArrayOutputStream stream) {
42+
int noBytesProcessed;
43+
byte[] buffer = new byte[data.length];
44+
45+
noBytesProcessed = encCipher.processBytes(data, 0, data.length, buffer, 0);
46+
stream.write(buffer, 0, noBytesProcessed);
47+
}
48+
49+
@Override
50+
protected void _decrypt(byte[] data, ByteArrayOutputStream stream) {
51+
int noBytesProcessed;
52+
byte[] buffer = new byte[data.length];
53+
54+
noBytesProcessed = decCipher.processBytes(data, 0, data.length, buffer, 0);
55+
stream.write(buffer, 0, noBytesProcessed);
56+
}
57+
58+
@Override
59+
public int getIVLength() {
60+
return 16;
61+
}
62+
63+
@Override
64+
public int getKeyLength() {
65+
return 16;
66+
}
67+
68+
@Override
69+
protected CipherParameters getCipherParameters(byte[] iv) {
70+
byte[] bts = new byte[_keyLength + _ivLength];
71+
System.arraycopy(_key.getEncoded(), 0, bts, 0, _keyLength);
72+
System.arraycopy(iv, 0, bts, _keyLength, _ivLength);
73+
return new KeyParameter(md5Digest(bts));
74+
}
75+
}

app/src/main/res/raw/config

Lines changed: 6 additions & 4 deletions
Large diffs are not rendered by default.

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ buildscript {
55
jcenter()
66
}
77
dependencies {
8-
classpath 'com.android.tools.build:gradle:2.1.0'
8+
classpath 'com.android.tools.build:gradle:2.3.3'
99

1010
// NOTE: Do not place your application dependencies here; they belong
1111
// in the individual module build.gradle files

0 commit comments

Comments
 (0)