This is an automated email from the ASF dual-hosted git repository.
jiangtian pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/tsfile.git
The following commit(s) were added to refs/heads/develop by this push:
new 7859080c Zjt/encrypt key from environment (#512)
7859080c is described below
commit 7859080cd46e8f046c8a1f87d95c3944a9eeb7a1
Author: jintao zhu <[email protected]>
AuthorDate: Thu Jun 12 17:54:15 2025 +0800
Zjt/encrypt key from environment (#512)
* use environment variable to generate main encrypt key
* delete chinese annotation
* delete chinese annotation
---
.../apache/tsfile/common/conf/TSFileConfig.java | 10 +-
.../tsfile/common/conf/TSFileDescriptor.java | 2 +-
.../org/apache/tsfile/encrypt/EncryptUtils.java | 110 ++++++++++++++++++++-
.../tsfile/file/metadata/TsFileMetadata.java | 2 +-
.../java/org/apache/tsfile/write/TsFileWriter.java | 4 +-
.../write/v4/AbstractTableModelTsFileWriter.java | 4 +-
6 files changed, 116 insertions(+), 16 deletions(-)
diff --git
a/java/tsfile/src/main/java/org/apache/tsfile/common/conf/TSFileConfig.java
b/java/tsfile/src/main/java/org/apache/tsfile/common/conf/TSFileConfig.java
index fd6a06c1..a987bf34 100644
--- a/java/tsfile/src/main/java/org/apache/tsfile/common/conf/TSFileConfig.java
+++ b/java/tsfile/src/main/java/org/apache/tsfile/common/conf/TSFileConfig.java
@@ -156,7 +156,7 @@ public class TSFileConfig implements Serializable {
private CompressionType compressor = CompressionType.LZ4;
/** encryptKey, this should be 16 bytes String. */
- private String encryptKey = "abcdefghijklmnop";
+ private byte[] encryptKey =
"abcdefghijklmnop".getBytes(TSFileConfig.STRING_CHARSET);
/** Data encryption method, default encryptType is "UNENCRYPTED". */
private String encryptType = "UNENCRYPTED";
@@ -250,16 +250,16 @@ public class TSFileConfig implements Serializable {
this.encryptType = encryptType;
}
- public String getEncryptKey() {
+ public byte[] getEncryptKey() {
return this.encryptKey;
}
- public void setEncryptKey(String encryptKey) {
+ public void setEncryptKey(byte[] encryptKey) {
this.encryptKey = encryptKey;
}
- public void setEncryptKeyFromPath(String encryptKeyPath) {
- this.encryptKey = EncryptUtils.getEncryptKeyFromPath(encryptKeyPath);
+ public void setEncryptKeyFromToken(String token) {
+ this.encryptKey = EncryptUtils.getEncryptKeyFromToken(token);
}
public int getGroupSizeInByte() {
diff --git
a/java/tsfile/src/main/java/org/apache/tsfile/common/conf/TSFileDescriptor.java
b/java/tsfile/src/main/java/org/apache/tsfile/common/conf/TSFileDescriptor.java
index 498716dd..435561d9 100644
---
a/java/tsfile/src/main/java/org/apache/tsfile/common/conf/TSFileDescriptor.java
+++
b/java/tsfile/src/main/java/org/apache/tsfile/common/conf/TSFileDescriptor.java
@@ -83,8 +83,8 @@ public class TSFileDescriptor {
writer.setString(conf::setCompressor, "compressor");
writer.setInt(conf::setBatchSize, "batch_size");
writer.setString(conf::setEncryptType, "encrypt_type");
- writer.setString(conf::setEncryptKeyFromPath, "encrypt_key_path");
writer.setBoolean(conf::setLz4UseJni, "lz4_use_jni");
+ conf.setEncryptKeyFromToken(System.getenv("user_encrypt_token"));
}
private static class PropertiesOverWriter {
diff --git
a/java/tsfile/src/main/java/org/apache/tsfile/encrypt/EncryptUtils.java
b/java/tsfile/src/main/java/org/apache/tsfile/encrypt/EncryptUtils.java
index b697c32e..a6216754 100644
--- a/java/tsfile/src/main/java/org/apache/tsfile/encrypt/EncryptUtils.java
+++ b/java/tsfile/src/main/java/org/apache/tsfile/encrypt/EncryptUtils.java
@@ -25,12 +25,17 @@ import org.apache.tsfile.exception.encrypt.EncryptException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
+import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Objects;
@@ -46,6 +51,12 @@ public class EncryptUtils {
private static volatile EncryptParameter encryptParam;
+ private static final String HMAC_ALGORITHM = "HmacSHA256";
+ private static final int ITERATION_COUNT = 1024;
+ private static final int SALT_LENGTH = 16;
+ private static final int INT_SIZE = 4;
+ private static final int dkLen = 16;
+
public static String getNormalKeyStr() {
if (normalKeyStr == null) {
synchronized (EncryptUtils.class) {
@@ -106,6 +117,96 @@ public class EncryptUtils {
}
}
+ public static byte[] getEncryptKeyFromToken(String token) {
+ if (token == null || token.trim().isEmpty()) {
+ return defaultKey.getBytes();
+ }
+ byte[] salt = generateSalt();
+ try {
+ return deriveKeyInternal(token.getBytes(), salt, ITERATION_COUNT, dkLen);
+ } catch (NoSuchAlgorithmException | InvalidKeyException e) {
+ throw new EncryptException("Error deriving key from token", e);
+ }
+ }
+
+ private static byte[] deriveKeyInternal(byte[] password, byte[] salt, int c,
int dkLen)
+ throws NoSuchAlgorithmException, InvalidKeyException {
+
+ int hLen = getPRFLength();
+
+ if (dkLen < 1) {
+ throw new EncryptException("main key's dkLen must be positive integer: "
+ dkLen);
+ }
+ if ((long) dkLen > (long) (Math.pow(2, 32) - 1) * hLen) {
+ throw new EncryptException("main key's dkLen is too long: " + dkLen);
+ }
+
+ int n = (int) Math.ceil((double) dkLen / hLen);
+ int r = dkLen - (n - 1) * hLen;
+
+ byte[] blocks = new byte[n * hLen];
+
+ for (int i = 1; i <= n; i++) {
+ byte[] block = F(password, salt, c, i);
+ System.arraycopy(block, 0, blocks, (i - 1) * hLen, hLen);
+ }
+
+ return Arrays.copyOf(blocks, dkLen);
+ }
+
+ /** main function F */
+ private static byte[] F(byte[] password, byte[] salt, int c, int i)
+ throws NoSuchAlgorithmException, InvalidKeyException {
+
+ // U1 = PRF(P, S || INT(i))
+ byte[] input = concatenate(salt, intToBigEndian(i));
+ byte[] U = prf(password, input);
+ byte[] result = U.clone();
+
+ // U2 to Uc
+ for (int j = 2; j <= c; j++) {
+ U = prf(password, U);
+ xorBytes(result, U);
+ }
+
+ return result;
+ }
+
+ /** PRF implementation (HMAC-SHA256) */
+ private static byte[] prf(byte[] key, byte[] data)
+ throws NoSuchAlgorithmException, InvalidKeyException {
+ Mac hmac = Mac.getInstance(HMAC_ALGORITHM);
+ hmac.init(new SecretKeySpec(key, HMAC_ALGORITHM));
+ return hmac.doFinal(data);
+ }
+
+ private static int getPRFLength() throws NoSuchAlgorithmException {
+ return Mac.getInstance(HMAC_ALGORITHM).getMacLength();
+ }
+
+ private static byte[] generateSalt() {
+ byte[] salt = new byte[SALT_LENGTH];
+ new SecureRandom().nextBytes(salt);
+ return salt;
+ }
+
+ private static byte[] intToBigEndian(int i) {
+ return new byte[] {(byte) (i >>> 24), (byte) (i >>> 16), (byte) (i >>> 8),
(byte) i};
+ }
+
+ private static void xorBytes(byte[] result, byte[] input) {
+ for (int i = 0; i < result.length; i++) {
+ result[i] ^= input[i];
+ }
+ }
+
+ private static byte[] concatenate(byte[] a, byte[] b) {
+ byte[] output = new byte[a.length + b.length];
+ System.arraycopy(a, 0, output, 0, a.length);
+ System.arraycopy(b, 0, output, a.length, b.length);
+ return output;
+ }
+
public static byte[] hexStringToByteArray(String hexString) {
int len = hexString.length();
byte[] byteArray = new byte[len / 2];
@@ -139,11 +240,10 @@ public class EncryptUtils {
"SHA-256 algorithm not found while using SHA-256 to generate data
key", e);
}
md.update("IoTDB is the best".getBytes());
- md.update(conf.getEncryptKey().getBytes());
+ md.update(conf.getEncryptKey());
byte[] data_key = Arrays.copyOfRange(md.digest(), 0, 16);
data_key =
- IEncryptor.getEncryptor(conf.getEncryptType(),
conf.getEncryptKey().getBytes())
- .encrypt(data_key);
+ IEncryptor.getEncryptor(conf.getEncryptType(),
conf.getEncryptKey()).encrypt(data_key);
StringBuilder valueStr = new StringBuilder();
@@ -180,7 +280,7 @@ public class EncryptUtils {
"SHA-256 algorithm not found while using SHA-256 to generate data
key", e);
}
md.update("IoTDB is the best".getBytes());
- md.update(conf.getEncryptKey().getBytes());
+ md.update(conf.getEncryptKey());
dataEncryptKey = Arrays.copyOfRange(md.digest(), 0, 16);
} else {
encryptType = "org.apache.tsfile.encrypt.UNENCRYPTED";
@@ -227,7 +327,7 @@ public class EncryptUtils {
"SHA-256 algorithm not found while using SHA-256 to generate data
key", e);
}
md.update("IoTDB is the best".getBytes());
- md.update(conf.getEncryptKey().getBytes());
+ md.update(conf.getEncryptKey());
dataEncryptKey = Arrays.copyOfRange(md.digest(), 0, 16);
} else {
encryptType = "org.apache.tsfile.encrypt.UNENCRYPTED";
diff --git
a/java/tsfile/src/main/java/org/apache/tsfile/file/metadata/TsFileMetadata.java
b/java/tsfile/src/main/java/org/apache/tsfile/file/metadata/TsFileMetadata.java
index e4303043..c0e6b464 100644
---
a/java/tsfile/src/main/java/org/apache/tsfile/file/metadata/TsFileMetadata.java
+++
b/java/tsfile/src/main/java/org/apache/tsfile/file/metadata/TsFileMetadata.java
@@ -157,7 +157,7 @@ public class TsFileMetadata {
IDecryptor decryptor =
IDecryptor.getDecryptor(
propertiesMap.get("encryptType"),
-
TSFileDescriptor.getInstance().getConfig().getEncryptKey().getBytes());
+ TSFileDescriptor.getInstance().getConfig().getEncryptKey());
String str = propertiesMap.get("encryptKey");
fileMetaData.dataEncryptKey =
decryptor.decrypt(EncryptUtils.getSecondKeyFromStr(str));
fileMetaData.encryptType = propertiesMap.get("encryptType");
diff --git
a/java/tsfile/src/main/java/org/apache/tsfile/write/TsFileWriter.java
b/java/tsfile/src/main/java/org/apache/tsfile/write/TsFileWriter.java
index 90f8843e..d1a13e7c 100644
--- a/java/tsfile/src/main/java/org/apache/tsfile/write/TsFileWriter.java
+++ b/java/tsfile/src/main/java/org/apache/tsfile/write/TsFileWriter.java
@@ -205,10 +205,10 @@ public class TsFileWriter implements AutoCloseable {
"SHA-256 algorithm not found while using SHA-256 to generate data
key", e);
}
md.update("IoTDB is the best".getBytes());
- md.update(config.getEncryptKey().getBytes());
+ md.update(config.getEncryptKey());
dataEncryptKey = Arrays.copyOfRange(md.digest(), 0, 16);
encryptKey =
- IEncryptor.getEncryptor(config.getEncryptType(),
config.getEncryptKey().getBytes())
+ IEncryptor.getEncryptor(config.getEncryptType(),
config.getEncryptKey())
.encrypt(dataEncryptKey);
} else {
encryptLevel = "0";
diff --git
a/java/tsfile/src/main/java/org/apache/tsfile/write/v4/AbstractTableModelTsFileWriter.java
b/java/tsfile/src/main/java/org/apache/tsfile/write/v4/AbstractTableModelTsFileWriter.java
index 73321ad0..92f4c102 100644
---
a/java/tsfile/src/main/java/org/apache/tsfile/write/v4/AbstractTableModelTsFileWriter.java
+++
b/java/tsfile/src/main/java/org/apache/tsfile/write/v4/AbstractTableModelTsFileWriter.java
@@ -117,10 +117,10 @@ abstract class AbstractTableModelTsFileWriter implements
ITsFileWriter {
"SHA-256 algorithm not found while using SHA-256 to generate data
key", e);
}
md.update("IoTDB is the best".getBytes());
- md.update(config.getEncryptKey().getBytes());
+ md.update(config.getEncryptKey());
dataEncryptKey = Arrays.copyOfRange(md.digest(), 0, 16);
encryptKey =
- IEncryptor.getEncryptor(config.getEncryptType(),
config.getEncryptKey().getBytes())
+ IEncryptor.getEncryptor(config.getEncryptType(),
config.getEncryptKey())
.encrypt(dataEncryptKey);
} else {
encryptLevel = "0";