dutchcoders/transfer.sh · error

gopenpgp: wrong password in symmetric decryption

Error message

gopenpgp: wrong password in symmetric decryption

What it means

This error is produced by the password-prompt callback in server/handlers.go during symmetric (passphrase-protected) OpenPGP decryption. gopenpgp invokes the callback again when SKESK parsing fails (e.g. the decrypted cipher algorithm is invalid), which for most inputs means the supplied passphrase was wrong. The server returns this error instead of re-prompting, so the uploaded encrypted file cannot be decrypted.

Source

Thrown at server/handlers.go:133

	return decrypt(reader, []byte(password))
}

func decrypt(ciphertext io.ReadCloser, password []byte) (plaintext io.ReadCloser, err error) {
	unarmored, err := armor.Decode(ciphertext)
	if err != nil {
		return
	}

	firstTimeCalled := true
	var prompt = func(keys []openpgp.Key, symmetric bool) ([]byte, error) {
		if firstTimeCalled {
			firstTimeCalled = false
			return password, nil
		}
		// Re-prompt still occurs if SKESK pasrsing fails (i.e. when decrypted cipher algo is invalid).
		// For most (but not all) cases, inputting a wrong passwords is expected to trigger this error.
		return nil, errors.New("gopenpgp: wrong password in symmetric decryption")
	}

	config := &packet.Config{
		DefaultCipher: packet.CipherAES256,
	}

	var emptyKeyRing openpgp.EntityList
	md, err := openpgp.ReadMessage(unarmored.Body, emptyKeyRing, prompt, config)
	if err != nil {
		// Parsing errors when reading the message are most likely caused by incorrect password, but we cannot know for sure
		return
	}

	plaintext = io.NopCloser(md.UnverifiedBody)

	return
}

View on GitHub (pinned to c37bfd9579)

Solutions

  1. Retry the download supplying the exact passphrase used at upload time.
  2. Quote the passphrase correctly in the shell and URL-encode it in the URL/Authorization header to avoid character mangling.
  3. Verify the downloaded artifact is the original encrypted file and not corrupted (compare checksums).
  4. If payloads are legitimate but fail, check the gopenpgp version for SKESK/cipher-algo compatibility issues and update dependencies.

Example fix

// before
curl -OJ --user 'x:wrongpass' https://host/token/filename
// after
curl -OJ --user 'x:correct-passphrase' https://host/token/filename
Defensive patterns

Strategy: validation

Validate before calling

# verify the passphrase decrypts before sharing/uploading:
echo test | gpg --symmetric --cipher-algo AES256 -o /tmp/t.gpg && \
  gpg --decrypt --passphrase '$PASSPHRASE' /tmp/t.gpg >/dev/null || echo "bad passphrase"

Try / catch

out, err := downloadWithPassword(token, file, pass)
if err != nil && strings.Contains(err.Error(), "wrong password") {
	// prompt user again for the correct passphrase
	return retryWithNewPassword()
}

Prevention

When it happens

Trigger: A client uploads a file encrypted with a symmetric passphrase, then GETs it with a --password that does not match the encryption passphrase; the second callback invocation (firstTimeCalled already false) returns this error.

Common situations: User typos the passphrase on download, passphrase contains characters mangled by shell quoting or URL encoding, file was re-encrypted with a different passphrase, or an actually corrupted/invalid encrypted payload triggers the same re-prompt path.

Related errors


AI-assisted analysis of dutchcoders/transfer.sh@c37bfd9579 (2026-09-05). Data as JSON: /api/errors/10da4741c1ef545c. Report an issue: GitHub.