OtterMind/Chat2DB · error · BusinessException
api.decryptPasswordError
api.decryptPasswordError
Error message
api.decryptPasswordError
What it means
BusinessException 'api.decryptPasswordError' from decryptToken when RSA/ECB/PKCS1Padding decryption of an encrypted field (password/host/url/user) fails. This is distinct from 143: here the key decoded fine, but the ciphertext does not decrypt against this key.
Source
Thrown at chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/db/DbWorkspaceDataSourceServiceImpl.java:243
try {
byte[] keyBytes = Base64.getDecoder().decode(privateKeyString);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
} catch (Exception e) {
throw new BusinessException("api.privateKeyNotFound");
}
}
private String decryptToken(String encryptedToken, PrivateKey privateKey) {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedToken));
return new String(decryptedBytes, StandardCharsets.UTF_8);
} catch (Exception e) {
log.error("decrypt token error", e);
throw new BusinessException("api.decryptPasswordError");
}
}
private String decryptString(String password) {
if (password == null || password.isEmpty()) {
return password;
}
return AesGcmUtil.configured().decrypt(password);
}
private String encryptString(String password) {
if (password == null || password.isEmpty()) {
return password;
}
return AesGcmUtil.configured().encrypt(password);
}
}
View on GitHub (pinned to 5ee1e990e7)
Solutions
- Re-save the datasource credentials so they are re-encrypted with the current organization key.
- Ensure the same key pair used at encrypt time is available at decrypt time (check key rotation / environment promotion).
- Confirm the stored value is actually the RSA ciphertext, not plain text or AES-encrypted local value.
Defensive patterns
Strategy: fallback
Validate before calling
// ensure field was encrypted with the current key before attempting decrypt // (no public predicate exists; rely on re-save after key rotation)
Try / catch
try { return decryptToken(token, privateKey); }
catch (BusinessException e) { // api.decryptPasswordError
// prompt user to re-enter credentials so they are re-encrypted
throw new CredentialReentryRequiredException();
} Prevention
- After any key rotation, re-save datasource credentials.
- Do not mix local-AES and cloud-RSA encrypted values across environments.
- Never manually edit encrypted fields.
When it happens
Trigger: Cipher.doFinal raises (BadPadding/IllegalBlockSize) because the token was encrypted with a different key pair, is not valid Base64, was double-encrypted, or the field is plain text being treated as ciphertext.
Common situations: Datasource was saved under one org key but is being read under another (key rotation mismatch); field was manually edited; migration imported ciphertext without migrating keys; Base64 padding corrupted.
Related errors
- common.needLoggedIn
- api.privateKeyNotFound
- Decryption error
- No database connection context found. Call list_all_datasour
- No database connection context found. Provide dataSourceId/d
AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14).
Data as JSON: /api/errors/5cd1d4ce99ffaee6.
Report an issue: GitHub.