golang/go · error
crypto/rsa: input must be hashed with given hash
Error message
crypto/rsa: input must be hashed with given hash
What it means
In RSASSA-PSS encoding (emsa_pss_encode), the mHash (message digest) must be exactly hLen bytes, where hLen is hash.Size() for the hash function passed to SignPSS. This check ensures the caller actually hashed the message with the specified algorithm before PSS padding is applied. A length mismatch indicates a protocol or caller error.
Source
Thrown at src/crypto/internal/fips140/rsa/pkcs1v22.go:86
incCounter(&counter)
}
}
func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byte, error) {
// See RFC 8017, Section 9.1.1.
hLen := hash.Size()
sLen := len(salt)
emLen := (emBits + 7) / 8
// 1. If the length of M is greater than the input limitation for the
// hash function (2^61 - 1 octets for SHA-1), output "message too
// long" and stop.
//
// 2. Let mHash = Hash(M), an octet string of length hLen.
if len(mHash) != hLen {
return nil, errors.New("crypto/rsa: input must be hashed with given hash")
}
// 3. If emLen < hLen + sLen + 2, output "encoding error" and stop.
if emLen < hLen+sLen+2 {
return nil, ErrMessageTooLong
}
em := make([]byte, emLen)
psLen := emLen - sLen - hLen - 2
db := em[:psLen+1+sLen]
h := em[psLen+1+sLen : emLen-1]
// 4. Generate a random octet string salt of length sLen; if sLen = 0,
// then salt is the empty string.
//
// 5. Let
// M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt;View on GitHub (pinned to b6b368adc5)
Solutions
- Ensure the hash.Hash passed to SignPSS is the same one used to compute the digest
- Verify len(hashed) == hash.Size() before calling SignPSS
- Use a helper that both hashes and signs in one step to avoid the mismatch
Example fix
// before hash := sha512.New() hash.Write(msg) digest := sha256.Sum256(msg) // wrong hash! sig, err := rsa.SignPSS(rand, key, hash, digest[:], nil) // after hash := sha256.New() hash.Write(msg) sig, err := rsa.SignPSS(rand, key, crypto.SHA256, hash.Sum(nil), nil)
Defensive patterns
Strategy: validation
Validate before calling
func validatePSSDigest(hash crypto.Hash, digest []byte) error {
if len(digest) != hash.Size() {
return fmt.Errorf("PSS digest length %d != %v size %d", len(digest), hash, hash.Size())
}
return nil
}
if err := validatePSSDigest(hashAlg, digest); err != nil { return err }
sig, err := rsa.SignPSS(rand, key, hashAlg, digest, nil) Try / catch
sig, err := rsa.SignPSS(rand, key, hashAlg, hashed, nil)
if err != nil {
return fmt.Errorf("PSS signing failed (check hash/digest match): %w", err)
} Prevention
- Use the same hash.Hash instance for both SignPSS and computing the digest
- Verify len(hashed) == hash.Size() before signing
- Create a single helper that hashes-and-signs to eliminate the mismatch surface
When it happens
Trigger: Calling rsa.SignPSS with a hashed slice whose length does not equal hash.Size() — e.g., passing a 32-byte SHA-256 digest but with a SHA-512 hash.Hash instance, or passing a truncated digest.
Common situations: Mismatch between the hash.Hash instance and the actual digest bytes (common when refactoring hash algorithms); passing a pre-computed digest from a different hash function; accidentally passing the raw message instead of its hash.
Related errors
- crypto/rsa: hashed message length does not match hash functi
- crypto/rsa: salt length cannot be negative
- rsa: key too small
- crypto/rsa: unsupported hash function
- crypto/rsa: invalid PSS salt length
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/dd94a3f340a73f1d.
Report an issue: GitHub.