Hello.
I encrypt specific data outside Palantir Foundry using AES‑GCM‑SIV, and then try to decrypt it inside Foundry with Cipher.
However, decryption fails with the following error. I suspect the ciphertext is shorter than Foundry expects. What is the expected ciphertext layout when using AES‑GCM‑SIV so Cipher can decrypt it successfully?
Error (excerpt):
Caused by: com.palantir.conjure.java.api.errors.ServiceException: ServiceException: INVALID_ARGUMENT (Bellaso:UndecryptableValue)
at com.palantir.bellaso.api.BellasoErrors.undecryptableValue(BellasoErrors.java:112)
at com.palantir.bellaso.encryption.bulk.Suppliers.silently(Suppliers.java:26)
at com.palantir.bellaso.encryption.bulk.AesGcmSivCipherLibrary.decryptString(AesGcmSivCipherLibrary.java:89)
at com.palantir.bellaso.encryption.bulk.EncryptionCipherLibrary.lambda$getDecryptUdf$c1a5cb6e$1(EncryptionCipherLibrary.java:161)
at org.apache.spark.sql.functions$.$anonfun$udf$91(functions.scala:8150)
... 20 more
Caused by: javax.crypto.AEADBadTagException: Tag mismatch
at java.base/com.sun.crypto.provider.GaloisCounterMode$GCMDecrypt.doFinal(GaloisCounterMode.java:1545)
at java.base/com.sun.crypto.provider.GaloisCounterMode.engineDoFinal(GaloisCounterMode.java:417)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2303)
at com.palantir.bellaso.encryption.bulk.AesGcmSivCipherLibrary.lambda$decryptString$1(AesGcmSivCipherLibrary.java:98)
at com.palantir.bellaso.encryption.bulk.Suppliers.silently(Suppliers.java:22)
... 23 more
My AES‑GCM‑SIV code (outside Foundry):
def aes_gcm_encrypt(b64_key: str, plaintext: str, aad: bytes = b""):
raw_key = b64decode(b64_key)
# GCM uses a 12‑byte nonce
nonce = os.urandom(12)
# Encrypt using AES‑GCM‑SIV
aesgcmsiv = AESGCMSIV(raw_key)
ciphertext = aesgcmsiv.encrypt(nonce, plaintext.encode("utf-8"), aad)
encrypted = nonce + ciphertext
return {
"plain_text": plaintext,
"nonce": nonce,
"aad": aad,
"ciphertext_b64": b64encode(encrypted).decode("utf-8"),
}
raw_key = AESGCMSIV.generate_key(256) # 32‑byte random key for AES‑GCM‑SIV (AES‑256)
b64_key = b64encode(raw_key) # Base64 encode the raw key to register it in Palantir Cipher
data = ["apple", "banana", "cherry", "cherry"] # Plaintext samples
for plain_text in data:
encrypted = aes_gcm_encrypt(b64_key, plain_text)
print(encrypted)
Question:
What exact ciphertext composition does Foundry’s Cipher expect for AES‑GCM‑SIV?
(e.g., is it nonce(12) || ciphertext || tag(16) as a single byte sequence, or a different structure?)
Are there any additional bytes/headers that must be present in the encrypted payload before decryption in Cipher?
Any do’s/don’ts for nonce length, tag placement, AAD handling, or Base64 encoding that are required for Cipher to accept and decrypt it?
Thanks in advance!