{"record":{"id":"66139eaed2cba8ba","repo":"apache/shardingsphere","slug":"algorithm-s-is-unsupported-to-decrypt","errorCode":null,"errorMessage":"Algorithm `%s` is unsupported to decrypt","messagePattern":"Algorithm `(.+?)` is unsupported to decrypt","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/algorithm/assisted/MD5AssistedEncryptAlgorithm.java","lineNumber":59,"sourceCode":"    \n    private Properties props;\n    \n    private MessageDigestAlgorithm digestAlgorithm;\n    \n    @Override\n    public void init(final Properties props) {\n        this.props = props;\n        digestAlgorithm = TypedSPILoader.getService(MessageDigestAlgorithm.class, getType(), props);\n    }\n    \n    @Override\n    public Object encrypt(final Object plainValue, final AlgorithmSQLContext algorithmSQLContext) {\n        return digestAlgorithm.digest(plainValue);\n    }\n    \n    @Override\n    public Object decrypt(final Object cipherValue, final AlgorithmSQLContext algorithmSQLContext) {\n        throw new UnsupportedOperationException(String.format(\"Algorithm `%s` is unsupported to decrypt\", getType()));\n    }\n    \n    @Override\n    public AlgorithmConfiguration toConfiguration() {\n        return new AlgorithmConfiguration(getType(), PropertiesBuilder.build(new Property(SALT_KEY, props.getProperty(SALT_KEY, \"\"))));\n    }\n    \n    @Override\n    public String getType() {\n        return \"MD5\";\n    }\n}\n","sourceCodeStart":41,"sourceCodeEnd":72,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/algorithm/assisted/MD5AssistedEncryptAlgorithm.java#L41-L72","documentation":"MD5AssistedEncryptAlgorithm is a one-way digest: encrypt() hashes via MessageDigestAlgorithm, and decrypt() always throws UnsupportedOperationException because an MD5 digest cannot be reversed. The message names the algorithm type ('MD5') as unsupported for decryption.","triggerScenarios":"Configuring a column with the MD5 assisted-encrypt algorithm and then executing a query whose result must be returned decrypted — e.g. a SELECT whose projection includes the MD5-encrypted column so EncryptMergedResult calls decrypt(), or an explicit API decrypt call.","commonSituations":"Reusing an MD5 config from a sharding/assisted-query scenario for a column that the application also reads back; migrating from a reversible algorithm to MD5 while old query paths still expect plaintext results; querying with SELECT * on tables with MD5 columns.","solutions":["Exclude MD5-encrypted columns from decrypted result projections (select other columns, or accept the digest as the value)","Switch the column to a reversible encrypt algorithm (e.g. AES) if plaintext must be recovered","Store a reversible ciphertext alongside the MD5 digest (separate encrypt column) if you need both comparison and recovery","If you only need equality matching, keep MD5 but adjust the application to never expect decryption"],"exampleFix":"# before\n- column: password\n  queryWithCipherColumn: true\n  encryptor: {name: MD5}\n# after (if plaintext recovery is required)\n- column: password\n  encryptor: {name: AES, props: {aes-key-value: '...'}}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"boolean isReversible(String algorithmType) { return !(\"MD5\".equals(algorithmType) || \"SM3\".equals(algorithmType) || algorithmType.startsWith(\"CHAR_DIGEST\")); }","tryCatchPattern":"catch (UnsupportedOperationException e) { if (e.getMessage().contains(\"unsupported to decrypt\")) { return cipherValue; /* digest is the final value */ } throw e; }","preventionTips":["Never SELECT MD5-encrypted columns expecting plaintext","Document one-way columns in the schema for application teams","Choose AES or another reversible algorithm when read-back is required"],"tags":["encrypt","md5","one-way-hash","unsupported-operation"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}