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
- Use one of the supported hash functions: crypto.SHA256, crypto.SHA384, crypto.SHA512, etc.
- Pass hash.Hash.String() correctly — ensure you're passing the hash name, not the hash value
- 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
- Stick to SHA-256, SHA-384, or SHA-512 for new RSA signatures
- Avoid BLAKE2/BLAKE3 with PKCS#1 v1.5 — they are not in the supported set
- Pass the crypto.Hash enum constant, not a string literal
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
- crypto/rsa: hashed message length does not match hash functi
- rsa: key too small
- crypto/rsa: input must be hashed with given hash
- crypto/rsa: salt length cannot be negative
- mlkem: invalid encapsulation key length
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/e0d45b4e15352697.
Report an issue: GitHub.