golang/go · error

crypto/rsa: unsupported hash function

Error message

crypto/rsa: unsupported hash function

What it means

pkcs1v15ConstructEM looks up the hash function name in the hashPrefixes map to get the DER-encoded AlgorithmIdentifier prefix for PKCS#1 v1.5 signature padding. Supported names are: MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256, SHA3-224, SHA3-256, SHA3-384, SHA3-512, MD5+SHA1 (TLS special case), and RIPEMD-160. An unrecognized name yields this error.

Source

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

}

func signPKCS1v15(priv *PrivateKey, hash string, hashed []byte) ([]byte, error) {
	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)

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Use one of the supported hash functions: crypto.SHA256, crypto.SHA384, crypto.SHA512, etc.
  2. Pass hash.Hash.String() correctly — ensure you're passing the hash name, not the hash value
  3. For direct signing without a hash prefix, pass hash 0 and empty hashed message as specified by the API

Example fix

// before
sig, err := rsa.SignPKCS1v15(rand, key, crypto.BLAKE2b_256, hashed) // not supported

// after
sig, err := rsa.SignPKCS1v15(rand, key, crypto.SHA256, hashedSHA256)
Defensive patterns

Strategy: validation

Validate before calling

var supportedPKCS1v15Hashes = map[crypto.Hash]bool{
    crypto.MD5: true, crypto.SHA1: true, crypto.SHA224: true,
    crypto.SHA256: true, crypto.SHA384: true, crypto.SHA512: true,
    crypto.SHA512_224: true, crypto.SHA512_256: true,
    crypto.SHA3_224: true, crypto.SHA3_256: true,
    crypto.SHA3_384: true, crypto.SHA3_512: true,
}

func isSupportedPKCS1v15Hash(h crypto.Hash) bool {
    return supportedPKCS1v15Hashes[h]
}

if !isSupportedPKCS1v15Hash(hashAlg) {
    return errors.New("unsupported hash for PKCS#1 v1.5")
}

Try / catch

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

Prevention

When it happens

Trigger: Calling SignPKCS1v15 or VerifyPKCS1v15 (which internally call pkcs1v15ConstructEM) with a hash crypto.Hash whose String() method returns a name not in the hashPrefixes map — for example, hash.Hash(0), BLAKE2b, or an entirely custom hash.

Common situations: Using a non-standard hash function (BLAKE2, BLAKE3) that is not in the FIPS-approved set; passing crypto.Hash(0) (no hash, direct signing) but with an empty prefix mismatch; using a hash constant from a different library that doesn't match Go's crypto.Hash enum.

Related errors


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