Skip to content

Commit

Permalink
新增了Chacha20Poly1305加密方式
Browse files Browse the repository at this point in the history
  • Loading branch information
CC-Cheunggg committed Jan 27, 2020
1 parent 70cb577 commit cb78529
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 30 deletions.
28 changes: 3 additions & 25 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
group 'com.cheung'
version '1.6.0.Final'
version '1.7.0.Final'

apply plugin: 'java'
apply plugin: 'idea'
Expand Down Expand Up @@ -31,44 +31,22 @@ buildscript {

dependencies {

compile 'io.netty:netty-all:4.1.31.Final'
compile 'io.netty:netty-all:4.1.45.Final'
compile 'commons-logging:commons-logging:1.2'
// compile 'org.apache.commons:commons-lang3:3.7'
// compile 'commons-beanutils:commons-beanutils:1.9.3'
// compile 'commons-collections:commons-collections:3.2.2'
// compile 'org.apache.commons:commons-configuration2:2.2'
compile 'com.thoughtworks.xstream:xstream:1.4.8'
compile 'xmlpull:xmlpull:1.1.3.1'
compile 'commons-io:commons-io:2.4'
// compile 'commons-codec:commons-codec:1.11'
// compile 'org.apache.commons:commons-exec:1.3'
compile 'org.codehaus.groovy:groovy-all:2.5.2'
compile 'jaxen:jaxen:1.1.6'
// compile 'org.apache.logging.log4j:log4j-core:2.8.2'
compile 'org.slf4j:slf4j-api:1.7.25'
compile 'org.slf4j:jcl-over-slf4j:1.7.25'
// compile 'org.apache.logging.log4j:log4j-slf4j-impl:2.4.1'
compile 'com.google.guava:guava:17.0'
annotationProcessor 'org.projectlombok:lombok:1.18.2'
compileOnly 'org.projectlombok:lombok:1.18.2'
compile 'org.bouncycastle:bcprov-jdk15on:1.60'
// compile 'com.google.crypto.tink:tink:1.2.0'
// compile 'com.lmax:disruptor:3.4.1'
// compile 'org.apache.commons:commons-pool2:2.4.2'
compile 'org.bouncycastle:bcprov-jdk15on:1.64'
compile 'org.springframework.boot:spring-boot-starter:1.5.13.RELEASE'
// compile 'org.springframework.boot:spring-boot-starter-web:1.5.13.RELEASE'
// compile 'org.springframework.boot:spring-boot-starter-jdbc:1.5.13.RELEASE'
// compile 'com.caucho:hessian:4.0.51'
// compile 'org.eclipse.jetty:jetty-server:9.4.10.v20180503'
// compile 'org.eclipse.jetty:jetty-servlet:9.4.10.v20180503'
// compile 'javax.servlet:javax.servlet-api:3.1.0'
compile 'com.fasterxml.jackson.core:jackson-databind:2.9.5'
// compile 'hikari-cp:hikari-cp:2.6.0'
// compile 'org.postgresql:postgresql:42.2.2'
// compile 'javax.mail:mail:1.4.7'
// compile 'io.dropwizard.metrics:metrics-core:4.0.3'
compile 'org.apache.ant:ant:1.10.5'
// compile 'net.java.dev.jna:jna:5.4.0'
compile fileTree(dir: 'localLibs', include: ['*.jar'])


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.generators.HKDFBytesGenerator;
import org.bouncycastle.crypto.modes.AEADBlockCipher;
import org.bouncycastle.crypto.modes.AEADCipher;
import org.bouncycastle.crypto.params.AEADParameters;
import org.bouncycastle.crypto.params.HKDFParameters;
import org.bouncycastle.crypto.params.KeyParameter;
Expand Down Expand Up @@ -39,8 +40,8 @@ public abstract class AEADCryptBase implements ICrypt {
protected boolean _decryptSaltSet;
protected final ReentrantLock encLock = new ReentrantLock();
protected final ReentrantLock decLock = new ReentrantLock();
protected AEADBlockCipher encCipher;
protected AEADBlockCipher decCipher;
protected AEADCipher encCipher;
protected AEADCipher decCipher;
private byte[] encSubkey;
private byte[] decSubkey;
protected byte[] encNonce;
Expand Down Expand Up @@ -202,7 +203,7 @@ protected static int getTagLength() {
return 16;
}

protected abstract AEADBlockCipher getCipher(boolean isEncrypted) throws GeneralSecurityException;
protected abstract AEADCipher getCipher(boolean isEncrypted) throws GeneralSecurityException;

protected abstract void _tcpEncrypt(byte[] data, ByteArrayOutputStream stream) throws GeneralSecurityException, IOException, InvalidCipherTextException;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public enum CryptFactory {
crypts.putAll(SeedStreamCrypt.getCiphers());
crypts.putAll(Chacha20StreamCrypt.getCiphers());
crypts.putAll(AesGcmCrypt.getCiphers());
crypts.putAll(ChaCha20Poly1305Crypt.getCiphers());
}

public ICrypt get(String name, String password) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.modes.AEADBlockCipher;
import org.bouncycastle.crypto.modes.AEADCipher;
import org.bouncycastle.crypto.modes.GCMBlockCipher;

import java.io.ByteArrayOutputStream;
Expand Down Expand Up @@ -51,7 +52,7 @@ public int getKeyLength() {
}

@Override
protected AEADBlockCipher getCipher(boolean isEncrypted)
protected AEADCipher getCipher(boolean isEncrypted)
throws GeneralSecurityException {
switch (_name) {
case CIPHER_AEAD_128_GCM:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package com.cheung.shadowsocks.encryption.impl;

import com.cheung.shadowsocks.encryption.AEADCryptBase;
import com.cheung.shadowsocks.encryption.ICrypt;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.modes.AEADCipher;
import org.bouncycastle.crypto.modes.ChaCha20Poly1305;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.security.GeneralSecurityException;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class ChaCha20Poly1305Crypt extends AEADCryptBase {

public final static String AEAD_CHACHA20_POLY1305 = "chacha20-ietf-poly1305";

public ChaCha20Poly1305Crypt(String name, String password) {
super(name, password);
}

public static Map<String, Class<? extends ICrypt>> getCiphers() {
Map<String, Class<? extends ICrypt>> ciphers = new HashMap<>();
ciphers.put(AEAD_CHACHA20_POLY1305, ChaCha20Poly1305Crypt.class);
return ciphers;
}

@Override
protected AEADCipher getCipher(boolean isEncrypted) throws GeneralSecurityException {
return new ChaCha20Poly1305();
}

@Override
protected void _tcpEncrypt(byte[] data, ByteArrayOutputStream stream) throws GeneralSecurityException, IOException, InvalidCipherTextException {
ByteBuffer buffer = ByteBuffer.wrap(data);
while (buffer.hasRemaining()) {
int nr = Math.min(buffer.remaining(), PAYLOAD_SIZE_MASK);
ByteBuffer.wrap(encBuffer).putShort((short) nr);
encCipher.init(true, getCipherParameters(true));
encCipher.doFinal(
encBuffer,
encCipher.processBytes(encBuffer, 0, 2, encBuffer, 0)
);
stream.write(encBuffer, 0, 2 + getTagLength());
increment(this.encNonce);

buffer.get(encBuffer, 2 + getTagLength(), nr);

encCipher.init(true, getCipherParameters(true));
encCipher.doFinal(
encBuffer,
2 + getTagLength() + encCipher.processBytes(encBuffer, 2 + getTagLength(), nr, encBuffer, 2 + getTagLength())
);
increment(this.encNonce);

stream.write(encBuffer, 2 + getTagLength(), nr + getTagLength());
}
}

@Override
protected void _tcpDecrypt(byte[] data, ByteArrayOutputStream stream) throws InvalidCipherTextException {
ByteBuffer buffer = ByteBuffer.wrap(data);
while (buffer.hasRemaining()) {
log.debug("id:{} remaining {} payloadLenRead:{} payloadRead:{}", hashCode(), buffer.hasRemaining(), payloadLenRead, payloadRead);
if (payloadRead == 0) {
int wantLen = 2 + getTagLength() - payloadLenRead;
int remaining = buffer.remaining();
if (wantLen <= remaining) {
buffer.get(decBuffer, payloadLenRead, wantLen);
} else {
buffer.get(decBuffer, payloadLenRead, remaining);
payloadLenRead += remaining;
return;
}
decCipher.init(false, getCipherParameters(false));
decCipher.doFinal(
decBuffer,
decCipher.processBytes(decBuffer, 0, 2 + getTagLength(), decBuffer, 0)
);
increment(decNonce);
}

int size = ByteBuffer.wrap(decBuffer, 0, 2).getShort();
log.debug("payload length:{},remaining:{},payloadRead:{}", size, buffer.remaining(), payloadRead);
if (size == 0) {
//TODO exists?
return;
} else {
int wantLen = getTagLength() + size - payloadRead;
int remaining = buffer.remaining();
if (wantLen <= remaining) {
buffer.get(decBuffer, 2 + getTagLength() + payloadRead, wantLen);
} else {
buffer.get(decBuffer, 2 + getTagLength() + payloadRead, remaining);
payloadRead += remaining;
return;
}
}

decCipher.init(false, getCipherParameters(false));
decCipher.doFinal(
decBuffer,
(2 + getTagLength()) + decCipher.processBytes(decBuffer, 2 + getTagLength(), size + getTagLength(), decBuffer, 2 + getTagLength())
);
increment(decNonce);

payloadLenRead = 0;
payloadRead = 0;

stream.write(decBuffer, 2 + getTagLength(), size);
}
}

@Override
protected void _udpEncrypt(byte[] data, ByteArrayOutputStream stream) throws Exception {
throw new UnsupportedOperationException();
}

@Override
protected void _udpDecrypt(byte[] data, ByteArrayOutputStream stream) throws Exception {
throw new UnsupportedOperationException();
}

@Override
protected int getKeyLength() {
return 32;
}

@Override
protected int getSaltLength() {
return 32;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ public class ClientProxyHandler extends ChannelInboundHandlerAdapter {
init(host, port);
}

private void init(final String host, final int port) {
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
super.handlerAdded(ctx);
}

private synchronized void init(final String host, final int port) {

try {
ClientProxy channelPool = BootContext.getBeanFactory().getBean(ClientProxy.class);
Expand Down

0 comments on commit cb78529

Please sign in to comment.