Closed gyCode2017 closed 2 months ago
Hi @tuichenchuxin Can you help with some advice?
Hi @GaoEinstein , I had a look at the code, AESEncryptAlgorithm.decrypt
always return String
type for now, but not different types of Object.
Since EncryptContext
just contains columnName
, without column metadata. So it could not decode to related Java types, e.g. BigDecimal.
Are you interesting to supply a design proposal (contains how to change related API), we could discuss it then.
A relatively simple solution may be as follows.
` @RequiredArgsConstructor @Getter @Setter public final class TypedEncryptContext {
private final EncryptContext encryptContext;
/**
* entity字段的原始类型
*/
private final Class<?> entityFieldType;
}
public interface TypedEncryptAlgorithm<I, O> {
/**
* 数据库中某字段的数据解密
* @param cipherValue 数据库中存储的密文
* @param encryptContext 上下文
* @return 解密结果
*/
I decrypt(O cipherValue, TypedEncryptContext encryptContext);
} `
` public final class TypedEncryptAlgorithmAdapter {
public static Object decrypt(Object cipherValue, EncryptContext encryptContext, StandardEncryptAlgorithm delegate,
Class<?> type) {
if (delegate instanceof TypedEncryptAlgorithm) {
TypedEncryptContext typedEncryptContext = new TypedEncryptContext(encryptContext, type);
return ((TypedEncryptAlgorithm) delegate).decrypt(cipherValue, typedEncryptContext);
}
return delegate.decrypt(cipherValue, encryptContext);
}
} ` An alternative solution would be to override the SPI, EncryptResultDecoratorEngine, by modifying META-INF/services/org.apache.shardingsphere.infra.merge.engine.ResultProcessEngine. Additionally, we can override EncryptDQLResultDecorator and EncryptMergedResult. By implementing TypedEncryptAlgorithmAdapter in org.apache.shardingsphere.encrypt.merge.dql.EncryptMergedResult#getValue, we can execute the decryption process and effectively address this issue.
If the official version allows modifications in org.apache.shardingsphere.encrypt.merge.dql.EncryptMergedResult#getValue by adding the field type to the context, the work I have done above would be unnecessary.
@strongduanmu , could you help to have a look at it? Maybe it's related to encrypt refactoring.
Hi @GaoEinstein I wonder where the primitive type is obtained from? hardcode? Logical columns don't actually exist in the database, so we can't get the logical type.
Hi @GaoEinstein I wonder where the primitive type is obtained from? hardcode? Logical columns don't actually exist in the database, so we can't get the logical type.
Hi @strongduanmu ,5.3.2 org.apache.shardingsphere.encrypt.merge.dql.EncryptMergedResult#getValue. The second param final Class<?> type
Hi @GaoEinstein I wonder where the primitive type is obtained from? hardcode? Logical columns don't actually exist in the database, so we can't get the logical type.
Isn't the second parameter the actual type of the field? Did I make a mistake? I hope to receive a correction and reply. thank you
@GaoEinstein Can you investigate how different database JDBC drivers handle the getValue(1, Type)
method? This doesn't seem to be something that encryption needs to handle, but the logic of the JDBC driver layer, what do you think?
There hasn't been any activity on this issue recently, and in order to prioritize active issues, it will be marked as stale.
Is your feature request related to a problem?
When I am using the sharding encryption jdbc module, I want to achieve automatic type conversion of ciphertext fields after decryption, such as the amount - BigDecimal. However, EncryptContext lacks an original field type configuration, so I would like to propose a requirement to add a field that can be used in my decryption method
Describe the feature you would like.
code position: org.apache.shardingsphere.encrypt.merge.dql.EncryptMergedResult#getValue
` @Override public Object getValue(final int columnIndex, final Class<?> type) throws SQLException { Optional encryptContext = metaData.findEncryptContext(columnIndex);
if (!encryptContext.isPresent() || !metaData.isQueryWithCipherColumn(encryptContext.get().getTableName(), encryptContext.get().getColumnName())) {
return mergedResult.getValue(columnIndex, type);
}
Optional encryptAlgorithm = metaData.findEncryptor(encryptContext.get().getTableName(), encryptContext.get().getColumnName());
if (!encryptAlgorithm.isPresent()) {
return mergedResult.getValue(columnIndex, type);
}
Object cipherValue = mergedResult.getValue(columnIndex, Object.class);
then usage in org.apache.shardingsphere.encrypt.algorithm.AESEncryptAlgorithm
// org.apache.shardingsphere.encrypt.algorithm.AESEncryptAlgorithm#decrypt
`public Object decrypt(String ciphertext, EncryptContext encryptContext) { if (null == ciphertext) { return null; }
Hope to help solve or answer the problem!thank you very much~