Crypto-View

matrix-org/matrix-js-sdk

Cryptographic posture

15 cryptographic locations: 4 quantum-vulnerable, 4 reduced-margin, 1 undetermined, 6 quantum-safe

2 establish keys, so traffic protected by them and recorded today becomes readable once the algorithm falls. 467 files analysed.

Quantum-vulnerable 4 Reduced margin 4 Could not be determined 1 Quantum-safe 6
To address3
Key establishment2
Inventory only0
Total findings15
What was analysed
Branch develop
Commit a953e24ba6559d5fb48de31f2f6bf82b5794cf4a Fix receipt accumulation across receipt types (#5541)
Committed 2026-09-18 14:34 UTC
Scanned 2026-09-21 10:59 UTC 9 hours ago
Coverage 467 files, 2 python, 411 javascript

List of cryptographic assets

ECDH Quantum-vulnerable Recorded traffic 2 places See details

TLS cipher suite named in source

A cipher suite written into the code rather than into a configuration file - `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256`, or the OpenSSL spelling `ECDHE-RSA-AES128-GCM-SHA256`. The key exchange is reported, and the bulk cipher separately when it is one of the broken ones.

This code names the exact cryptography its TLS connections may use. Because the list is in the program rather than in a settings file, changing it needs a new release - which is the thing that makes a migration slow.

What to do. A hardcoded suite list ships with the binary and cannot be changed without a release, so move it to configuration first. The key exchange changes when the TLS library offers a hybrid group, not before.

  1. spec/test-utils/webrtcReports.ts:564 test path dtlsCipher: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
  2. spec/test-utils/webrtcReports.ts:1097 test path dtlsCipher: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
config.cipher-suite · CWE-757
RSA4096-bit Quantum-vulnerable 1 place See details

X.509 certificate

A PEM certificate. The subject public-key algorithm and key size are read from the SubjectPublicKeyInfo structure, and the not-after date is reported so certificates that outlive the migration window are visible.

This is a digital identity document. Its expiry date matters: one valid for many years locks in today's algorithms for that long.

What to do. Shorten certificate lifetimes so re-issuing with a post-quantum key is routine.

  1. spec/integ/crypto/rust-crypto.spec.ts:125 test path -----BEGIN CERTIFICATE-----
pem.certificate
AES Reduced margin 2 places See details

AES block cipher

`algorithms.AES(key)`. Symmetric encryption is not broken by a quantum computer; the key length is what matters. The key size is reported where it can be read.

This is the kind of encryption that quantum computers do not break. Using a longer key is enough.

What to do. Use a 256-bit key. No change of algorithm is required.

  1. spec/test-utils/crypto-test-data/generate-test-data.py:519 test path cipher = Cipher(algorithms.AES(aes_key), modes.CBC(iv))
  2. spec/test-utils/crypto-test-data/generate-test-data.py:589 test path cipher = Cipher(algorithms.AES(aes_key), modes.CBC(aes_iv))
py.cryptography.aes
SHA-256 Reduced margin 2 places See details

Hash function in use

`createHash()` or `subtle.digest()`. The digest is read from the argument, so one rule covers the family: MD5 and SHA-1 are reported as broken, SHA-256 as a reduced margin, SHA-384 and above as inventory.

A quantum computer weakens this but does not break it. Increasing the key or digest size restores the margin. Pre-image resistance falls to about 128 bits of quantum work. Adequate for most uses; SHA-384 restores the full margin where a signature must last decades.

What to do. SHA-256 as the floor, SHA-384 where the digest protects something long-lived.

  1. spec/integ/crypto/verification.spec.ts:1718 test path return encodeUnpaddedBase64(createHash("sha256").update(commitmentStr, "utf8").digest());
  2. src/digest.ts:31 const digest = await globalThis.crypto.subtle.digest("SHA-256", utf8);
js.hash · CWE-328
CSPRNG Quantum-safe 5 places See details

Random number generation

`crypto.randomBytes()`, `randomUUID()` or `getRandomValues()`. A platform CSPRNG is not a quantum exposure; it is recorded because an inventory that omits the randomness source is incomplete. `Math.random()` is a separate, present-day defect.

This is where the software gets its random numbers. Quantum computers do not weaken it.

What to do. No action.

  1. src/matrixrtc/RTCEncryptionManager.ts:505 globalThis.crypto.getRandomValues(key);
  2. src/randomstring.ts:40 globalThis.crypto.getRandomValues(key);
  3. src/rust-crypto/rust-crypto.ts:1100 globalThis.crypto.getRandomValues(key);
  4. src/utils/encryptAESSecretStorageItem.ts:45 globalThis.crypto.getRandomValues(iv);
  5. src/webrtc/call.ts:2492 [ToDeviceMessageId]: globalThis.crypto.randomUUID(),
js.rng
HMAC Quantum-safe 1 place See details

Keyed hash in use

`hmac.new()` or `hmac.digest()`. Not broken by Shor and only marginally affected by Grover. Recorded so the inventory is complete.

This is a fingerprint proving a message was not altered. Quantum computers do not break it.

What to do. No action, unless the digest is MD5 or SHA-1.

  1. spec/test-utils/crypto-test-data/generate-test-data.py:453 test path h = hmac.HMAC(ri3, hashes.SHA256())
py.hmac

Cryptographic assets

Algorithm Assessment What it means Occurrences
CSPRNG Quantum-safe A cryptographically secure random number generator provided by the platform. Not weakened by a quantum computer. 5
AES Reduced margin Grover's algorithm halves the effective strength; the parameter, not the design, is the problem. The key size was not visible at this call site, so the weaker case is assumed. 2
RSA Quantum-vulnerable Broken by Shor's algorithm on a cryptographically relevant quantum computer. 2
ECDH Quantum-vulnerable Broken by Shor's algorithm on a cryptographically relevant quantum computer. 2
SHA-256 Reduced margin Pre-image resistance falls to about 128 bits of quantum work. Adequate for most uses; SHA-384 restores the full margin where a signature must last decades. 2
HMAC Quantum-safe A keyed MAC is not affected by Shor and only marginally by Grover. 1
unknown Could not be determined The algorithm could not be established from the source - chosen at runtime, or decided somewhere this scan does not reach. 1

Imported cryptographic libraries

Library Files
cryptography pyca/cryptography 1
node:crypto the Node crypto module 1