golang/go · error

crypto/rsa: hashed message length does not match hash functi

Error message

crypto/rsa: hashed message length does not match hash function

What it means

After resolving the hash function name in PKCS#1 v1.5 signing/verification, the library checks that len(hashed) matches the expected digest size for that hash (e.g., 32 bytes for SHA-256, 64 for SHA-512). A mismatch means the caller did not actually hash the message with the claimed algorithm, and signing it would produce a structurally invalid signature.

Source

Thrown at src/crypto/internal/fips140/rsa/pkcs1v15.go:76

	em, err := pkcs1v15ConstructEM(&priv.pub, hash, hashed)
	if err != nil {
		return nil, err
	}

	return decrypt(priv, em, withCheck)
}

func pkcs1v15ConstructEM(pub *PublicKey, hash string, hashed []byte) ([]byte, error) {
	// Special case: "" is used to indicate that the data is signed directly.
	var prefix []byte
	if hash != "" {
		var ok bool
		prefix, ok = hashPrefixes[hash]
		if !ok {
			return nil, errors.New("crypto/rsa: unsupported hash function")
		}
		if len(hashed) != hashSize(hash) {
			return nil, errors.New("crypto/rsa: hashed message length does not match hash function")
		}
	}

	// EM = 0x00 || 0x01 || PS || 0x00 || T
	k := pub.Size()
	if k < len(prefix)+len(hashed)+2+8+1 {
		return nil, ErrMessageTooLong
	}
	em := make([]byte, k)
	em[1] = 1
	for i := 2; i < k-len(prefix)-len(hashed)-1; i++ {
		em[i] = 0xff
	}
	copy(em[k-len(prefix)-len(hashed):], prefix)
	copy(em[k-len(hashed):], hashed)
	return em, nil
}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Ensure the hash parameter matches the algorithm used to produce the digest
  2. Let the library hash for you by using SignPKCS1v15 with a hash.Hash instance writing the message, if the API supports it
  3. Verify len(hashed) == hashSize(hashName) before calling the function

Example fix

// before
h := sha512.Sum512(msg)
sig, err := rsa.SignPKCS1v15(rand, key, crypto.SHA256, h[:]) // wrong hash declared

// after
h := sha256.Sum256(msg)
sig, err := rsa.SignPKCS1v15(rand, key, crypto.SHA256, h[:])
Defensive patterns

Strategy: validation

Validate before calling

func validateDigestLength(hash crypto.Hash, digest []byte) error {
    expected := 0
    switch hash {
    case crypto.SHA224: expected = 28
    case crypto.SHA256: expected = 32
    case crypto.SHA384: expected = 48
    case crypto.SHA512: expected = 64
    default: return fmt.Errorf("unsupported hash %v", hash)
    }
    if len(digest) != expected {
        return fmt.Errorf("digest length %d does not match %v (%d)", len(digest), hash, expected)
    }
    return nil
}

if err := validateDigestLength(hashAlg, digest); err != nil { return err }
sig, err := rsa.SignPKCS1v15(rand, key, hashAlg, digest)

Try / catch

sig, err := rsa.SignPKCS1v15(rand, key, hashAlg, hashed)
if err != nil {
    return fmt.Errorf("PKCS#1 v1.5 signing failed (check hash/digest match): %w", err)
}

Prevention

When it happens

Trigger: Calling SignPKCS1v15 or VerifyPKCS1v15 where the hash parameter names SHA-256 but hashed is not 32 bytes, or names SHA-512 but hashed is not 64 bytes, etc.

Common situations: Hashing with a different algorithm than declared (e.g., SHA-384 but passing it as SHA-256); passing a truncated or padded digest; double-hashing or passing the raw message instead of its digest; using a wrong hash.Hash instance to produce the digest.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/1ab044b8b10f455e. Report an issue: GitHub.