EMSA-PSS (RFC 8017 §9.1) hasht M' = 0x00×8 ‖ mHash ‖ salt zu H, bildet DB = PS ‖ 0x01 ‖ salt, maskiert es mit MGF1(H) und gibt maskedDB ‖ H ‖ 0xbc aus, das anschließend wie jede RSA-Signatur potenziert wird. Die Parameter sind der Hash, die Maskengenerierungsfunktion (MGF1 mit eigenem Hash), die Salt-Länge und das Trailer-Feld; Signierer und Verifizierer müssen sich auf alle einigen.
Die Salt-Länge ist die klassische Fehlerquelle bei der Interoperabilität. JOSE PS256/PS384/PS512 legen MGF1 auf denselben Hash und die Salt-Länge auf die Hashlänge fest (RFC 7518 §3.5), und FIPS 186-5 §5.4(g) verlangt 0 ≤ sLen ≤ hLen. OpenSSL 1.1.1 und 3.0 signierten standardmäßig mit dem maximalen Salt (222 Byte bei RSA-2048 mit SHA-256), OpenSSL ab 3.1 dagegen standardmäßig mit auto-digestmax, was in der Praxis der Digest-Länge entspricht; ein Verifizierer, der eine andere Länge festlegt, lehnt die Signatur mit salt length check failed ab.
TLS 1.3 verlangt PSS, sobald RSA Handshake-Daten signiert: rsa_pss_rsae_sha256 (0x0804) nutzt einen gewöhnlichen Schlüssel vom Typ rsaEncryption, rsa_pss_pss_sha256 (0x0809) einen Schlüssel, den die OID id-RSASSA-PSS 1.2.840.113549.1.1.10 (RFC 4055) auf PSS beschränkt. PKCS #1 v1.5 überlebt nur in Signaturen von Zertifikaten. Die Schlüssel sind mit PKCS #1 v1.5 austauschbar: Stellst du von RS256 auf PS256 um, brauchst du keinen neuen Schlüssel, nur Verifizierer, die PSS akzeptieren.