apache/shardingsphere · error · UnsupportedOperationException

Algorithm `%s` is unsupported to decrypt

Error message

Algorithm `%s` is unsupported to decrypt

What it means

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.

Source

Thrown at features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/algorithm/assisted/MD5AssistedEncryptAlgorithm.java:59

    
    private Properties props;
    
    private MessageDigestAlgorithm digestAlgorithm;
    
    @Override
    public void init(final Properties props) {
        this.props = props;
        digestAlgorithm = TypedSPILoader.getService(MessageDigestAlgorithm.class, getType(), props);
    }
    
    @Override
    public Object encrypt(final Object plainValue, final AlgorithmSQLContext algorithmSQLContext) {
        return digestAlgorithm.digest(plainValue);
    }
    
    @Override
    public Object decrypt(final Object cipherValue, final AlgorithmSQLContext algorithmSQLContext) {
        throw new UnsupportedOperationException(String.format("Algorithm `%s` is unsupported to decrypt", getType()));
    }
    
    @Override
    public AlgorithmConfiguration toConfiguration() {
        return new AlgorithmConfiguration(getType(), PropertiesBuilder.build(new Property(SALT_KEY, props.getProperty(SALT_KEY, ""))));
    }
    
    @Override
    public String getType() {
        return "MD5";
    }
}

View on GitHub (pinned to e952770a21)

Solutions

  1. Exclude MD5-encrypted columns from decrypted result projections (select other columns, or accept the digest as the value)
  2. Switch the column to a reversible encrypt algorithm (e.g. AES) if plaintext must be recovered
  3. Store a reversible ciphertext alongside the MD5 digest (separate encrypt column) if you need both comparison and recovery
  4. If you only need equality matching, keep MD5 but adjust the application to never expect decryption

Example fix

# before
- column: password
  queryWithCipherColumn: true
  encryptor: {name: MD5}
# after (if plaintext recovery is required)
- column: password
  encryptor: {name: AES, props: {aes-key-value: '...'}}
Defensive patterns

Strategy: try-catch

Type guard

boolean isReversible(String algorithmType) { return !("MD5".equals(algorithmType) || "SM3".equals(algorithmType) || algorithmType.startsWith("CHAR_DIGEST")); }

Try / catch

catch (UnsupportedOperationException e) { if (e.getMessage().contains("unsupported to decrypt")) { return cipherValue; /* digest is the final value */ } throw e; }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/66139eaed2cba8ba. Report an issue: GitHub.