This is an automated email from the ASF dual-hosted git repository. chengzhang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push: new 4990de4bb73 Add provider of cryptographic properties (#34410) 4990de4bb73 is described below commit 4990de4bb732a32dd709cbe280dc3d8a30fa0216 Author: ZhangCheng <chengzh...@apache.org> AuthorDate: Mon Jan 20 20:20:22 2025 +0800 Add provider of cryptographic properties (#34410) * Add provider of cryptographic properties * Add provider of cryptographic properties * Add provider of cryptographic properties --- .../core/CryptographicPropertiesProvider.java | 61 ++++++++++++++++++++++ .../aes/AESCryptographicAlgorithm.java | 36 ++++++------- .../DefaultAESPropertiesProvider.java} | 59 ++++++++------------- ...ptographic.core.CryptographicPropertiesProvider | 18 +++++++ .../props/DefaultAESPropertiesProviderTest.java | 47 +++++++++++++++++ 5 files changed, 164 insertions(+), 57 deletions(-) diff --git a/infra/algorithm/type/cryptographic/core/src/main/java/org/apache/shardingsphere/infra/algorithm/cryptographic/core/CryptographicPropertiesProvider.java b/infra/algorithm/type/cryptographic/core/src/main/java/org/apache/shardingsphere/infra/algorithm/cryptographic/core/CryptographicPropertiesProvider.java new file mode 100644 index 00000000000..49a2c0caad1 --- /dev/null +++ b/infra/algorithm/type/cryptographic/core/src/main/java/org/apache/shardingsphere/infra/algorithm/cryptographic/core/CryptographicPropertiesProvider.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.infra.algorithm.cryptographic.core; + +import org.apache.shardingsphere.infra.algorithm.core.ShardingSphereAlgorithm; + +/** + * Provider of cryptographic properties. + */ +public interface CryptographicPropertiesProvider extends ShardingSphereAlgorithm { + + /** + * Get secret key. + * + * @return secret key. + */ + byte[] getSecretKey(); + + /** + * Get mode. + * + * @return mode + */ + String getMode(); + + /** + * Get padding. + * + * @return padding + */ + String getPadding(); + + /** + * Get iv parameter. + * + * @return iv parameter + */ + byte[] getIvParameter(); + + /** + * Get encoder. + * + * @return encoder + */ + String getEncoder(); +} diff --git a/infra/algorithm/type/cryptographic/type/aes/src/main/java/org/apache/shardingsphere/infra/algorithm/cryptographic/aes/AESCryptographicAlgorithm.java b/infra/algorithm/type/cryptographic/type/aes/src/main/java/org/apache/shardingsphere/infra/algorithm/cryptographic/aes/AESCryptographicAlgorithm.java index 83b9b58da35..f5036afc89c 100644 --- a/infra/algorithm/type/cryptographic/type/aes/src/main/java/org/apache/shardingsphere/infra/algorithm/cryptographic/aes/AESCryptographicAlgorithm.java +++ b/infra/algorithm/type/cryptographic/type/aes/src/main/java/org/apache/shardingsphere/infra/algorithm/cryptographic/aes/AESCryptographicAlgorithm.java @@ -18,16 +18,14 @@ package org.apache.shardingsphere.infra.algorithm.cryptographic.aes; import lombok.SneakyThrows; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.shardingsphere.infra.algorithm.core.exception.AlgorithmInitializationException; import org.apache.shardingsphere.infra.algorithm.cryptographic.core.CryptographicAlgorithm; -import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions; +import org.apache.shardingsphere.infra.algorithm.cryptographic.core.CryptographicPropertiesProvider; +import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; -import java.util.Arrays; import java.util.Base64; import java.util.Properties; @@ -36,23 +34,11 @@ import java.util.Properties; */ public final class AESCryptographicAlgorithm implements CryptographicAlgorithm { - private static final String AES_KEY = "aes-key-value"; - - private static final String DIGEST_ALGORITHM_NAME = "digest-algorithm-name"; - - private byte[] secretKey; + private CryptographicPropertiesProvider propsProvider; @Override public void init(final Properties props) { - secretKey = getSecretKey(props); - } - - private byte[] getSecretKey(final Properties props) { - String aesKey = props.getProperty(AES_KEY); - ShardingSpherePreconditions.checkNotEmpty(aesKey, () -> new AlgorithmInitializationException(this, "%s can not be null or empty", AES_KEY)); - String digestAlgorithm = props.getProperty(DIGEST_ALGORITHM_NAME); - ShardingSpherePreconditions.checkNotEmpty(digestAlgorithm, () -> new AlgorithmInitializationException(this, "%s can not be null or empty", DIGEST_ALGORITHM_NAME)); - return Arrays.copyOf(DigestUtils.getDigest(digestAlgorithm.toUpperCase()).digest(aesKey.getBytes(StandardCharsets.UTF_8)), 16); + propsProvider = TypedSPILoader.getService(CryptographicPropertiesProvider.class, "DEFAULT", props); } @SneakyThrows(GeneralSecurityException.class) @@ -62,7 +48,11 @@ public final class AESCryptographicAlgorithm implements CryptographicAlgorithm { return null; } byte[] result = getCipher(Cipher.ENCRYPT_MODE).doFinal(String.valueOf(plainValue).getBytes(StandardCharsets.UTF_8)); - return Base64.getEncoder().encodeToString(result); + return encode(result); + } + + private String encode(final byte[] value) { + return Base64.getEncoder().encodeToString(value); } @SneakyThrows(GeneralSecurityException.class) @@ -71,13 +61,17 @@ public final class AESCryptographicAlgorithm implements CryptographicAlgorithm { if (null == cipherValue) { return null; } - byte[] result = getCipher(Cipher.DECRYPT_MODE).doFinal(Base64.getDecoder().decode(cipherValue.toString().trim())); + byte[] result = getCipher(Cipher.DECRYPT_MODE).doFinal(decode(cipherValue.toString().trim())); return new String(result, StandardCharsets.UTF_8); } + private byte[] decode(final String value) { + return Base64.getDecoder().decode(value); + } + private Cipher getCipher(final int decryptMode) throws GeneralSecurityException { Cipher result = Cipher.getInstance(getType()); - result.init(decryptMode, new SecretKeySpec(secretKey, getType())); + result.init(decryptMode, new SecretKeySpec(propsProvider.getSecretKey(), getType())); return result; } diff --git a/infra/algorithm/type/cryptographic/type/aes/src/main/java/org/apache/shardingsphere/infra/algorithm/cryptographic/aes/AESCryptographicAlgorithm.java b/infra/algorithm/type/cryptographic/type/aes/src/main/java/org/apache/shardingsphere/infra/algorithm/cryptographic/aes/props/DefaultAESPropertiesProvider.java similarity index 63% copy from infra/algorithm/type/cryptographic/type/aes/src/main/java/org/apache/shardingsphere/infra/algorithm/cryptographic/aes/AESCryptographicAlgorithm.java copy to infra/algorithm/type/cryptographic/type/aes/src/main/java/org/apache/shardingsphere/infra/algorithm/cryptographic/aes/props/DefaultAESPropertiesProvider.java index 83b9b58da35..020183dab15 100644 --- a/infra/algorithm/type/cryptographic/type/aes/src/main/java/org/apache/shardingsphere/infra/algorithm/cryptographic/aes/AESCryptographicAlgorithm.java +++ b/infra/algorithm/type/cryptographic/type/aes/src/main/java/org/apache/shardingsphere/infra/algorithm/cryptographic/aes/props/DefaultAESPropertiesProvider.java @@ -15,36 +15,49 @@ * limitations under the License. */ -package org.apache.shardingsphere.infra.algorithm.cryptographic.aes; +package org.apache.shardingsphere.infra.algorithm.cryptographic.aes.props; -import lombok.SneakyThrows; +import lombok.Getter; import org.apache.commons.codec.digest.DigestUtils; import org.apache.shardingsphere.infra.algorithm.core.exception.AlgorithmInitializationException; -import org.apache.shardingsphere.infra.algorithm.cryptographic.core.CryptographicAlgorithm; +import org.apache.shardingsphere.infra.algorithm.cryptographic.core.CryptographicPropertiesProvider; import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions; -import javax.crypto.Cipher; -import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; -import java.security.GeneralSecurityException; import java.util.Arrays; -import java.util.Base64; import java.util.Properties; /** - * AES cryptographic algorithm. + * Provider of default AES cryptographic properties. */ -public final class AESCryptographicAlgorithm implements CryptographicAlgorithm { +public final class DefaultAESPropertiesProvider implements CryptographicPropertiesProvider { private static final String AES_KEY = "aes-key-value"; private static final String DIGEST_ALGORITHM_NAME = "digest-algorithm-name"; + @Getter private byte[] secretKey; + @Getter + private String mode; + + @Getter + private String padding; + + @Getter + private byte[] ivParameter; + + @Getter + private String encoder; + @Override public void init(final Properties props) { secretKey = getSecretKey(props); + mode = ""; + padding = ""; + ivParameter = new byte[0]; + encoder = "BASE64"; } private byte[] getSecretKey(final Properties props) { @@ -55,34 +68,8 @@ public final class AESCryptographicAlgorithm implements CryptographicAlgorithm { return Arrays.copyOf(DigestUtils.getDigest(digestAlgorithm.toUpperCase()).digest(aesKey.getBytes(StandardCharsets.UTF_8)), 16); } - @SneakyThrows(GeneralSecurityException.class) - @Override - public String encrypt(final Object plainValue) { - if (null == plainValue) { - return null; - } - byte[] result = getCipher(Cipher.ENCRYPT_MODE).doFinal(String.valueOf(plainValue).getBytes(StandardCharsets.UTF_8)); - return Base64.getEncoder().encodeToString(result); - } - - @SneakyThrows(GeneralSecurityException.class) - @Override - public Object decrypt(final Object cipherValue) { - if (null == cipherValue) { - return null; - } - byte[] result = getCipher(Cipher.DECRYPT_MODE).doFinal(Base64.getDecoder().decode(cipherValue.toString().trim())); - return new String(result, StandardCharsets.UTF_8); - } - - private Cipher getCipher(final int decryptMode) throws GeneralSecurityException { - Cipher result = Cipher.getInstance(getType()); - result.init(decryptMode, new SecretKeySpec(secretKey, getType())); - return result; - } - @Override public String getType() { - return "AES"; + return "DEFAULT"; } } diff --git a/infra/algorithm/type/cryptographic/type/aes/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.algorithm.cryptographic.core.CryptographicPropertiesProvider b/infra/algorithm/type/cryptographic/type/aes/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.algorithm.cryptographic.core.CryptographicPropertiesProvider new file mode 100644 index 00000000000..2df5b267114 --- /dev/null +++ b/infra/algorithm/type/cryptographic/type/aes/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.algorithm.cryptographic.core.CryptographicPropertiesProvider @@ -0,0 +1,18 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +org.apache.shardingsphere.infra.algorithm.cryptographic.aes.props.DefaultAESPropertiesProvider diff --git a/infra/algorithm/type/cryptographic/type/aes/src/test/java/org/apache/shardingsphere/infra/algorithm/cryptographic/aes/props/DefaultAESPropertiesProviderTest.java b/infra/algorithm/type/cryptographic/type/aes/src/test/java/org/apache/shardingsphere/infra/algorithm/cryptographic/aes/props/DefaultAESPropertiesProviderTest.java new file mode 100644 index 00000000000..203d9da6263 --- /dev/null +++ b/infra/algorithm/type/cryptographic/type/aes/src/test/java/org/apache/shardingsphere/infra/algorithm/cryptographic/aes/props/DefaultAESPropertiesProviderTest.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.infra.algorithm.cryptographic.aes.props; + +import org.apache.shardingsphere.infra.algorithm.core.exception.AlgorithmInitializationException; +import org.apache.shardingsphere.infra.algorithm.cryptographic.core.CryptographicPropertiesProvider; +import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; +import org.apache.shardingsphere.test.util.PropertiesBuilder; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class DefaultAESPropertiesProviderTest { + + @Test + void assertCreateNewInstanceWithoutAESKey() { + assertThrows(AlgorithmInitializationException.class, () -> TypedSPILoader.getService(CryptographicPropertiesProvider.class, "DEFAULT")); + } + + @Test + void assertCreateNewInstanceWithAESKey() { + CryptographicPropertiesProvider provider = TypedSPILoader.getService(CryptographicPropertiesProvider.class, "DEFAULT", + PropertiesBuilder.build(new PropertiesBuilder.Property("aes-key-value", "test"), new PropertiesBuilder.Property("digest-algorithm-name", "SHA-1"))); + assertThat(provider.getSecretKey().length, is(16)); + assertThat(provider.getMode(), is("")); + assertThat(provider.getPadding(), is("")); + assertThat(provider.getIvParameter(), is(new byte[0])); + assertThat(provider.getEncoder(), is("BASE64")); + } +}