first commit
This commit is contained in:
81
docs/security-stack/crypto/crypto-rsa/src/verify/pkcs1v15.md
Normal file
81
docs/security-stack/crypto/crypto-rsa/src/verify/pkcs1v15.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# verify/pkcs1v15
|
||||
|
||||
## Purpose
|
||||
|
||||
RSASSA-PKCS1-v1\_5 signature verification per RFC 8017 §8.2.2. Recovers
|
||||
the encoded message from `signature` via `s^e mod n`, reconstructs the
|
||||
expected EMSA-PKCS1-v1\_5 encoding of `message` with the same hash, and
|
||||
compares the two byte strings constant-time.
|
||||
|
||||
## Features
|
||||
|
||||
- RFC 8017 §8.2.2 conformant
|
||||
- Constant-time encoded-message compare via `constantTimeEqual` from `@suaveplan/crypto-utils`
|
||||
- Returns `false` on rejection (no exception); throws only on structural malformation (signature length mismatch)
|
||||
- Accepts either an `RsaPublicKey` or an `RsaPrivateKey` (both carry `n` and `e`)
|
||||
- Modulus-length policy gates run on every call
|
||||
- Records `crypto_rsa.verify_duration_ms` and `crypto_rsa.outcome_total{operation,outcome}` on every call
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { rsaVerifyPkcs1v15 } from "@suaveplan/crypto-rsa/verify/pkcs1v15";
|
||||
import { rsaSignPkcs1v15 } from "@suaveplan/crypto-rsa/sign/pkcs1v15";
|
||||
|
||||
const message = new TextEncoder().encode("hello, signed world");
|
||||
const signature = rsaSignPkcs1v15(privateKey, message, { hash: "SHA-256" });
|
||||
const ok = rsaVerifyPkcs1v15(publicKey, message, signature, {
|
||||
hash: "SHA-256",
|
||||
});
|
||||
console.log(ok); // true
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
A bit-flipped signature, a tampered message, or a hash mismatch all
|
||||
return `false` without revealing which one tripped the gate.
|
||||
|
||||
```ts
|
||||
import { rsaVerifyPkcs1v15 } from "@suaveplan/crypto-rsa/verify/pkcs1v15";
|
||||
|
||||
const tampered = new Uint8Array(signature);
|
||||
tampered[0] = tampered[0] ^ 0x01;
|
||||
console.log(
|
||||
rsaVerifyPkcs1v15(publicKey, message, tampered, { hash: "SHA-256" })
|
||||
); // false
|
||||
|
||||
console.log(
|
||||
rsaVerifyPkcs1v15(publicKey, message, signature, { hash: "SHA-512" })
|
||||
); // false (hash mismatch)
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `rsaVerifyPkcs1v15(key, message, signature, options): boolean`
|
||||
|
||||
- `key: RsaPublicKey | RsaPrivateKey`
|
||||
- `message: Uint8Array` — the bytes that were signed
|
||||
- `signature: Uint8Array` — must be exactly `byteLength(n)` long
|
||||
- `options.hash: RsaHashAlgorithm` — must match the hash used at sign time
|
||||
- `options.allowLegacy?: boolean`
|
||||
- `options.allowOversize?: boolean`
|
||||
- **returns** `true` when the signature is valid, `false` on any verify-level rejection
|
||||
- **throws** `CryptoRsaError(CRYPTO_RSA.INVALID_SIGNATURE)` on signature length mismatch
|
||||
- **throws** `CryptoRsaError(CRYPTO_RSA.MODULUS_TOO_SHORT)` / `MODULUS_TOO_LARGE` / `UNSUPPORTED_HASH`
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The signature integer `s = os2ip(signature)` is checked against `s < n`
|
||||
before the modular exponentiation; signatures with `s >= n` are
|
||||
rejected with `false` rather than allowed to wrap around.
|
||||
- Comparison uses `constantTimeEqual(recovered, expected)` — never
|
||||
`===` and never byte-by-byte short-circuit. This is the verify-side
|
||||
defence against the timing-oracle attacks described in Bleichenbacher
|
||||
2006 (the SHA-1 padding-oracle exploit) and follow-ups.
|
||||
- The encoded message is reconstructed every call rather than carried
|
||||
alongside the signature. This is the RFC 8017 §8.2.2 design — the
|
||||
verifier MUST regenerate `EM` from the public inputs to detect
|
||||
signature substitution.
|
||||
- The `verify_duration_ms` histogram is recorded on every code path
|
||||
(success, rejection, structural error) so service-side dashboards see
|
||||
the full latency distribution including the failure modes.
|
||||
Reference in New Issue
Block a user