Dedicated line crypto
This commit is contained in:
@@ -36,6 +36,7 @@ import we.util.NettyDataBufferUtils;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -60,7 +61,9 @@ public class FizzServerHttpRequestDecorator extends ServerHttpRequestDecorator {
|
||||
@Nullable
|
||||
private MultiValueMap<String, HttpCookie> cookies;
|
||||
|
||||
private Flux<DataBuffer> body = Flux.empty();
|
||||
private Flux<DataBuffer> body = Flux.empty();
|
||||
|
||||
private byte[] bodyBytes;
|
||||
|
||||
public FizzServerHttpRequestDecorator(ServerHttpRequest delegate) {
|
||||
super(delegate);
|
||||
@@ -128,16 +131,20 @@ public class FizzServerHttpRequestDecorator extends ServerHttpRequestDecorator {
|
||||
}
|
||||
|
||||
public void setEmptyBody() {
|
||||
this.body = Flux.empty();
|
||||
body = Flux.empty();
|
||||
bodyBytes = null;
|
||||
}
|
||||
|
||||
public void setBody(DataBuffer body) {
|
||||
if (body instanceof PooledDataBuffer) {
|
||||
byte[] bytes = new byte[body.readableByteCount()];
|
||||
body.read(bytes);
|
||||
byte[] bytes = NettyDataBufferUtils.copyBytes(body);
|
||||
setBody(bytes);
|
||||
} else {
|
||||
this.body = Flux.just(body);
|
||||
ByteBuffer byteBuffer = body.asByteBuffer();
|
||||
if (byteBuffer.hasArray()) {
|
||||
bodyBytes = byteBuffer.array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +154,8 @@ public class FizzServerHttpRequestDecorator extends ServerHttpRequestDecorator {
|
||||
}
|
||||
|
||||
public void setBody(byte[] body) {
|
||||
NettyDataBuffer from = NettyDataBufferUtils.from(body);
|
||||
bodyBytes = body;
|
||||
NettyDataBuffer from = NettyDataBufferUtils.from(bodyBytes);
|
||||
this.body = Flux.just(from);
|
||||
}
|
||||
|
||||
@@ -156,13 +164,7 @@ public class FizzServerHttpRequestDecorator extends ServerHttpRequestDecorator {
|
||||
return body;
|
||||
}
|
||||
|
||||
// public DataBuffer getRawBody() {
|
||||
// final DataBuffer[] raw = {null};
|
||||
// body.subscribe(
|
||||
// dataBuffer -> {
|
||||
// raw[0] = dataBuffer;
|
||||
// }
|
||||
// );
|
||||
// return raw[0];
|
||||
// }
|
||||
public byte[] getBodyBytes() {
|
||||
return bodyBytes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public abstract class FizzServerHttpResponseDecorator extends ServerHttpResponse
|
||||
if (body != NettyDataBufferUtils.EMPTY_DATA_BUFFER) {
|
||||
if (body instanceof PooledDataBuffer) {
|
||||
try {
|
||||
b = NettyDataBufferUtils.from(body.asByteBuffer());
|
||||
b = NettyDataBufferUtils.copy2heap(body);
|
||||
} finally {
|
||||
NettyDataBufferUtils.release(body);
|
||||
}
|
||||
|
||||
@@ -54,15 +54,25 @@ public abstract class NettyDataBufferUtils extends org.springframework.core.io.b
|
||||
return (NettyDataBuffer) dataBufferFactory.wrap(bytes);
|
||||
}
|
||||
|
||||
public static NettyDataBuffer from(ByteBuffer byteBuffer) {
|
||||
/*public static NettyDataBuffer from(ByteBuffer byteBuffer) {
|
||||
return dataBufferFactory.wrap(byteBuffer);
|
||||
}
|
||||
|
||||
public static NettyDataBuffer from(ByteBuf byteBuf) {
|
||||
return dataBufferFactory.wrap(byteBuf);
|
||||
}*/
|
||||
|
||||
public static byte[] copyBytes(DataBuffer dataBuffer) {
|
||||
byte[] bytes = new byte[dataBuffer.readableByteCount()];
|
||||
dataBuffer.read(bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static boolean release(@Nullable String traceId, @Nullable DataBuffer dataBuffer) {
|
||||
public static DataBuffer copy2heap(DataBuffer dataBuffer) {
|
||||
return from(copyBytes(dataBuffer));
|
||||
}
|
||||
|
||||
/*public static boolean release(@Nullable String traceId, @Nullable DataBuffer dataBuffer) {
|
||||
if (dataBuffer instanceof PooledDataBuffer) {
|
||||
PooledDataBuffer pooledDataBuffer = (PooledDataBuffer) dataBuffer;
|
||||
if (pooledDataBuffer.isAllocated()) {
|
||||
@@ -81,5 +91,5 @@ public abstract class NettyDataBufferUtils extends org.springframework.core.io.b
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
107
fizz-common/src/main/java/we/util/SymmetricCryptoUtils.java
Normal file
107
fizz-common/src/main/java/we/util/SymmetricCryptoUtils.java
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2020 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package we.util;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.KeyUtil;
|
||||
import cn.hutool.crypto.Padding;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.PBEParameterSpec;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
*/
|
||||
|
||||
public abstract class SymmetricCryptoUtils {
|
||||
|
||||
private SymmetricCryptoUtils() {
|
||||
}
|
||||
|
||||
public static Cipher createCipher(SymmetricAlgorithm algorithm, String key, int mode) {
|
||||
byte[] keyBytes = SecureUtil.decode(key);
|
||||
String algorithmName = algorithm.getValue();
|
||||
SecretKey secretKey = KeyUtil.generateKey(algorithmName, keyBytes);
|
||||
|
||||
Cipher cipher = SecureUtil.createCipher(algorithmName);
|
||||
|
||||
byte[] iv = cipher.getIV();
|
||||
AlgorithmParameterSpec parameterSpec = null;
|
||||
if (StrUtil.startWithIgnoreCase(algorithmName, "AES")) {
|
||||
if (iv != null) {
|
||||
parameterSpec = new IvParameterSpec(iv);
|
||||
}
|
||||
} else if (StrUtil.startWithIgnoreCase(algorithmName, "PBE")) {
|
||||
if (null == iv) {
|
||||
iv = RandomUtil.randomBytes(8);
|
||||
}
|
||||
parameterSpec = new PBEParameterSpec(iv, 100);
|
||||
}
|
||||
|
||||
try {
|
||||
if (null == parameterSpec) {
|
||||
cipher.init(mode, secretKey);
|
||||
} else {
|
||||
cipher.init(mode, secretKey, parameterSpec);
|
||||
}
|
||||
} catch (InvalidAlgorithmParameterException | InvalidKeyException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return cipher;
|
||||
}
|
||||
|
||||
public static boolean isZeroPadding(SymmetricAlgorithm algorithm) {
|
||||
String algorithmName = algorithm.getValue();
|
||||
return algorithmName.contains(Padding.ZeroPadding.name());
|
||||
}
|
||||
|
||||
public static byte[] paddingWith0(byte[] data, int blockSize) {
|
||||
int length = data.length;
|
||||
int remainLength = length % blockSize;
|
||||
if (remainLength > 0) {
|
||||
return ArrayUtil.resize(data, length + blockSize - remainLength);
|
||||
} else {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] removePadding(byte[] data, int blockSize) {
|
||||
if (blockSize > 0) {
|
||||
int length = data.length;
|
||||
int remainLength = length % blockSize;
|
||||
if (remainLength == 0) {
|
||||
int i = length - 1;
|
||||
while (i >= 0 && 0 == data[i]) {
|
||||
i--;
|
||||
}
|
||||
return ArrayUtil.resize(data, i + 1);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
72
fizz-common/src/main/java/we/util/SymmetricDecryptor.java
Normal file
72
fizz-common/src/main/java/we/util/SymmetricDecryptor.java
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2020 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package we.util;
|
||||
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
*/
|
||||
|
||||
public class SymmetricDecryptor {
|
||||
|
||||
public final SymmetricAlgorithm algorithm;
|
||||
|
||||
public final String secretKey;
|
||||
|
||||
private final Cipher cipher;
|
||||
|
||||
private final boolean isZeroPadding;
|
||||
|
||||
public SymmetricDecryptor(SymmetricAlgorithm algorithm, String key) {
|
||||
this.algorithm = algorithm;
|
||||
secretKey = key;
|
||||
cipher = SymmetricCryptoUtils.createCipher(algorithm, key, Cipher.DECRYPT_MODE);
|
||||
isZeroPadding = SymmetricCryptoUtils.isZeroPadding(algorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param data can be hex or base64 string
|
||||
*/
|
||||
public String decrypt(String data) {
|
||||
byte[] decode = SecureUtil.decode(data);
|
||||
return StrUtil.str(decrypt(decode), CharsetUtil.CHARSET_UTF_8);
|
||||
}
|
||||
|
||||
public byte[] decrypt(byte[] data) {
|
||||
int blockSize = cipher.getBlockSize();
|
||||
byte[] decryptData;
|
||||
try {
|
||||
decryptData = cipher.doFinal(data);
|
||||
} catch (IllegalBlockSizeException | BadPaddingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (isZeroPadding) {
|
||||
return SymmetricCryptoUtils.removePadding(decryptData, blockSize);
|
||||
} else {
|
||||
return decryptData;
|
||||
}
|
||||
}
|
||||
}
|
||||
73
fizz-common/src/main/java/we/util/SymmetricEncryptor.java
Normal file
73
fizz-common/src/main/java/we/util/SymmetricEncryptor.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2020 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package we.util;
|
||||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.HexUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
*/
|
||||
|
||||
public class SymmetricEncryptor {
|
||||
|
||||
public final SymmetricAlgorithm algorithm;
|
||||
|
||||
public final String secretKey;
|
||||
|
||||
private final Cipher cipher;
|
||||
|
||||
private final boolean isZeroPadding;
|
||||
|
||||
public SymmetricEncryptor(SymmetricAlgorithm algorithm, String key) {
|
||||
this.algorithm = algorithm;
|
||||
secretKey = key;
|
||||
cipher = SymmetricCryptoUtils.createCipher(algorithm, key, Cipher.ENCRYPT_MODE);
|
||||
isZeroPadding = SymmetricCryptoUtils.isZeroPadding(algorithm);
|
||||
}
|
||||
|
||||
public byte[] encrypt(byte[] data) {
|
||||
if (isZeroPadding) {
|
||||
data = SymmetricCryptoUtils.paddingWith0(data, cipher.getBlockSize());
|
||||
}
|
||||
try {
|
||||
return cipher.doFinal(data);
|
||||
} catch (IllegalBlockSizeException | BadPaddingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] encrypt(String data) {
|
||||
return encrypt(StrUtil.bytes(data, CharsetUtil.CHARSET_UTF_8));
|
||||
}
|
||||
|
||||
public String base64encrypt(String data) {
|
||||
return Base64.encode(encrypt(data));
|
||||
}
|
||||
|
||||
public String hexEncrypt(String data) {
|
||||
return HexUtil.encodeHexStr(encrypt(data));
|
||||
}
|
||||
}
|
||||
@@ -132,4 +132,15 @@ public abstract class Utils {
|
||||
return new Throwable(msg, null, false, false) {
|
||||
};
|
||||
}
|
||||
|
||||
public static String getMessage(Throwable t) {
|
||||
String message = t.getMessage();
|
||||
if (message == null) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(t.toString()).append(Consts.S.LF);
|
||||
b.append("at ").append(t.getStackTrace()[0].toString());
|
||||
message = b.toString();
|
||||
}
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
24
fizz-common/src/test/java/we/util/SymmetricCryptoTests.java
Normal file
24
fizz-common/src/test/java/we/util/SymmetricCryptoTests.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package we.util;
|
||||
|
||||
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class SymmetricCryptoTests {
|
||||
|
||||
@Test
|
||||
public void encryptTest() {
|
||||
String secretKey = "1gG1dVcEaQz8JyifTHeEnQ==";
|
||||
SymmetricEncryptor symmetricEncryptor = new SymmetricEncryptor(SymmetricAlgorithm.AES, secretKey);
|
||||
String encrypt = symmetricEncryptor.base64encrypt("abc");
|
||||
|
||||
SymmetricDecryptor symmetricDecryptor = new SymmetricDecryptor(SymmetricAlgorithm.AES, secretKey);
|
||||
String decrypt = symmetricDecryptor.decrypt(encrypt);
|
||||
|
||||
Assertions.assertEquals("abc", decrypt);
|
||||
|
||||
byte[] encryptBytes = symmetricEncryptor.encrypt("123".getBytes());
|
||||
byte[] decryptBytes = symmetricDecryptor.decrypt(encryptBytes);
|
||||
Assertions.assertEquals("123", new String(decryptBytes));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user