Files
obscura/crates/obscura-js/Cargo.toml
T
MrBeanDev ed75730e2d feat(js): implement WebCrypto SubtleCrypto secret-key algorithms
crypto.subtle only implemented digest. sign returned a fixed 32-byte
buffer, verify always returned true, encrypt and decrypt threw, and
generateKey, importKey and deriveBits handed back placeholder data.
Pages that use WebCrypto (anti-bot probes, PKCE and other auth flows,
client-side crypto) silently got wrong results.

Implement the secret-key half of WebCrypto on RustCrypto, following the
existing op_subtle_digest pattern:

- HMAC sign and verify (SHA-1/256/384/512)
- AES-GCM, AES-CBC and AES-CTR encrypt and decrypt
- PBKDF2 and HKDF deriveBits and deriveKey
- raw and symmetric JWK (oct) importKey and exportKey, generateKey,
  wrapKey and unwrapKey
- getRandomValues and randomUUID now draw from the OS CSPRNG instead of
  Math.random, so they are uniform across typed-array widths and no
  longer a fingerprinting tell

Unsupported algorithms (RSA, ECDSA, ECDH) and key formats (pkcs8, spki)
throw NotSupportedError instead of returning fake data. The crypto runs
in stateless Rust ops; the bootstrap.js shim only marshals bytes and
normalizes algorithm parameters, so the native fast paths are untouched
and there is no cost unless a page calls crypto.

Verified against RFC 4231 (HMAC), the NIST GCM vectors, NIST SP800-38A
(AES-CTR), RFC 6070 (PBKDF2) and RFC 5869 (HKDF), plus roundtrip and
tag/padding tamper-rejection checks.
2026-07-01 12:11:55 +05:30

44 lines
1.3 KiB
TOML

[package]
name = "obscura-js"
version.workspace = true
edition.workspace = true
[features]
default = []
# Builds obscura-net with its stealth (wreq) HTTP client and lets scripted
# fetch()/XHR be routed through it so JS-level requests carry the same Chrome
# TLS fingerprint and client hints as stealth navigation.
stealth = ["obscura-net/stealth"]
[build-dependencies]
deno_core = "0.350"
[dependencies]
obscura-dom = { workspace = true }
obscura-net = { workspace = true }
deno_core = "0.350"
tokio = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
url = { workspace = true }
tracing = { workspace = true }
thiserror = { workspace = true }
anyhow = { workspace = true }
reqwest = { workspace = true }
html5ever = { workspace = true }
deno_error = "0.6"
base64 = { workspace = true }
sha1 = "0.10"
sha2 = "0.10"
# WebCrypto (crypto.subtle) primitives. RustCrypto, pure Rust, no CMake/OpenSSL,
# and they unify on the digest 0.10 / cipher 0.4 stack already in the tree.
hmac = "0.12"
aes = "0.8"
aes-gcm = "0.10"
cbc = { version = "0.1", features = ["alloc"] }
ctr = "0.9"
pbkdf2 = { version = "0.12", default-features = false, features = ["hmac"] }
hkdf = "0.12"
# CSPRNG for getRandomValues / randomUUID (replaces Math.random).
getrandom = "0.2"