DEV Community

foxgem
foxgem

Posted on

3 1

Quick notes on cryptography for js devs

Principles of Encryption API Selection

  • The standard library first.
  • Prefer well-known and audited libraries.
  • Before choosing a third-party library, do some investigation first.

Basics

  • Encode / Decode: Buffer Class.
  • Random numbers
    • The basis of cryptography.
    • It is extremely difficult to obtain true random numbers, commonly, pseudo-random numbers are used.
    • Don't use Math.random!
    • Use the random functions in the crypto module, e.g. crypto.randomBytes.
  • Hash
    • Irreversible.
    • The output is a fixed-length string.
    • Same input, same output.
    • Different inputs, different outputs.
    • Typical applications
      • Data integrity verification
      • Passphrase hashing
      • Derived Keys
  • Key
    • Derived Key: A key generated from a master key.
    • Key Encapsulation: encrypt and export the key.
    • Key Decapsulation: decrypts and imports the key
  • Authenticated Encryption: encryption and tamper-proof
  • Symmetric Encryption
    • Use the same key for encryption and decryption
    • Fast
    • Suitable for large data blocks
    • Key exchange is difficult
  • Asymmetric encryption
    • Public key + Private key
      • Encryption: public key encryption, private key decryption
      • Signing: private key encryption, public key decryption
    • Slow
    • Not suitable for large data blocks
    • Typical applications
      • Key exchange
      • Digital certificates
      • Digital signatures
  • Hybrid encryption
    • Combination of the above two
      • Asymmetric encryption for key exchange
      • Symmetric encryption for data manipulation
  • Encryption modes
    • Block encryption, grouping before encryption.
      • Never use ECB mode.
    • Stream encryption, dealing with continuous or unknown length byte streams, advantageous when the plaintext is small.

Hash

  • Don't use:
    • MD5
    • SHA-1
    • PBKDF2
    • bcrypt
  • Message digest: SHA-256
    • crypto.createHash('sha256')
    • Use stream mode for large data
    • Do not use for sensitive data such as passphrases
  • Message Authentication Code (HMAC)
    • hash and key (key to be known by both parties)
    • crypto.createHmac('sha256', 'secret')
  • Password hashing and KDF (Key Derivation Function)
    • Features.
      • salt built-in
      • Deliberated slow algorithms to offset the computational power boost caused by newer hardware.
    • argon2 (recommended)
    • scrypt
      • crypto.scrypt

Symmetric Encryption

  • Don't use:
    • DES, including 3DES.
    • Blowfish
      • TWofish is its successor, but not popular.
    • AES-ECB
      • No ECB mode, please.
  • AES
    • Common modes.
      • AES-CBC, when authentication is not required
        • crypto.createCipheriv('aes-256-cbc', ...)
        • crypto.createDecipheriv('aes-256-cbc', ...)
      • AES-GCM, when authentication is required
        • crypto.createCipheriv('aes-256-gcm', ...)
        • crypto.createDecipheriv('aes-256-gcm', ...)
    • For big data use stream mode
  • ChaCha20-Poly1305
    • ChaCha20 encryption + Poly1305 hashing
    • Equivalent to AES-GCM
    • Suitable for environments without AES hardware acceleration support
    • crypto.createCipheriv('chacha20-poly1305', ...)
    • crypto.createDecipheriv('chacha20-poly1305', ...)

Asymmetric Encryption

  • ASN.1 Data Structure
  • Key encoding format: PEM format

    • Public key: SPKI

      // import
      crypto.createPrivateKey(fs.readFileSync("public.pem"));
      
    • Private key.

      • PKCS #1 (old, RSA only)
      • PKCS #8 (new, for multiple algorithms)
      // import
      crypto.createPrivateKey(fs.readFileSync("private.pem"));
      
    • Export: crypto.KeyObject.export(option)

  • RSA

    • key
      • crypto.generateKeyPair('rsa', ...)
    • encryption and decryption

      • padding: add random data to the plaintext before encryption to improve the security of RSA.
        • Always used if no special reasons.
        • crypto.constants.RSA_PKCS1_OAEP_PADDING (recommended)
        • crypto.constants.RSA_PKCS1_PADDING (not recommended)
      • encryption

        crypto.publicEncrypt(
            {
                key: publicKey,
                padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
                oaepHash: "sha256",
            },
            plaintext
        );
        
      • decryption

        crypto.privateDecrypt(
            {
                key: privateKey,
                padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
                oaepHash: "sha256",
            },
            message
        );
        
    • Digital signature

      • padding:
        • crypto.constants.RSA_PKCS1_PADDING (default)
        • crypto.constants.RSA_PKCS1_PSS_PADDING (new version, recommended)
      • signing
      crypto.sign("sha256", message, {
          key: privateKey,
          padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
      });
      
      • verification
      crypto.verify(
          "sha256",
          message,
          {
              key: publicKey,
              padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
          },
          signature
      );
      
  • Elliptic Curve

    • Equivalent security to RSA
    • Shorter keys, faster and cheaper
    • Unlike RSA, its key pair does not support asymmetric encryption, i.e.: the public key decrypts the message encrypted by the private key, or vice versa.
    • Commonly used curves
      • P-256: secp256r1 / prime256v1, NIST standard
      • Curve25519
        • X25519 for key exchange
        • Ed25519 for digital signatures
      • secp256k1, used by Bitcoin
    • Typical Applications
      • Key exchange (ECDH)
      • Digital signatures
    • key
      • crypto.generateKeyPair('ec', ...)
    • ECDH
      • Unlike RSA (where party A encrypts the key with party B's public key and then sends it to party B to decrypt).
      • DH protocol
        • Alice and Bob each generate a key pair
        • They exchange the public keys
        • Combine their private keys to generate a shared key, i.e.
          • shareSecret(A public key, B private key) = shareSecret(B public key, A private key)
      • crypto.diffieHellman({A public key, B private key})
      • A reference implementation of shared keys.
        • crypto.diffieHellman gets shareSecret
        • Generate a random salt
        • sha256(shareSecret, salt) is the shared key, note: remember to pass the salt to the other side with the ciphertext.
    • Digital signatures
      • ECDSA (using prime256v1)
        • crypto.sign('sha256', message, privateKey)
        • crypto.verify('sha256', message, publicKey, signature)
      • EdDSA (using Ed25519), which does not require an externally configured hash function as it already has a built-in digital signature algorithm.
        • crypto.sign(null, message, privateKey)
        • crypto.verify(null, message, publicKey, signature)

Web Crypto

  • Used in the browser environment
  • Encoding
    • ArrayBuffer
    • atob and btoa
    • TextEncoder
  • Random numbers.
    • Window.crypto.getRandomValues
    • Window.crypto.randomUUID
  • keys
    • window.crypto.subtle.generateKey(algorithm, extractable, usages)
    • window.crypto.subtle.importKey(format, data, algorithm, extractable, usages)
    • window.crypto.subtle.exportKey(format, key)
    • window.crypto.subtle.wrapKey
    • window.crypto.subtle.unwrapKey
    • window.crypto.subtle.deriveKey
  • Hash
  • Encryption and decryption (both symmetric and asymmetric)
    • crypto.subtle.encrypt(algorithm, key, data)
    • crypto.subtle.decrypt(algorithm, key, data)
  • Digital signatures
    • window.crypto.subtle.sign
    • window.crypto.subtle.verify

References

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

đź‘‹ Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay