👨‍💻
Application Security Handbook
  • Application Security Handbook
  • Web Application
    • Authentication
      • Authentication with Login and Password
      • Authentication with Phone Number
      • OAuth 2.0 Authentication
      • Multi-factor Authentication
      • Default Passwords
      • Password Change
      • Password Policy
      • Password Reset
      • Password Storage
      • One Time Password (OTP)
      • Email Address Confirmation
    • Authorization
    • Concept of Trusted Devices
    • Content Security Policy (CSP)
    • Cookie Security
    • Cryptography
      • Cryptographic Keys Management
      • Encryption
      • Hash-based Message Authentication Code (HMAC)
      • Hashing
      • Random Generators
      • Universal Unique Identifier (UUID)
    • Error and Exception Handling
    • File Upload
    • Input Validation
    • JSON Web Token (JWT)
    • Logging and Monitoring
    • Output Encoding
    • Regular Expressions
    • Sensitive Data Management
    • Session Management
    • Transport Layer Protection
    • Vulnerability Mitigation
      • Brute-force
      • Command Injection
      • Cross-Site Request Forgery (CSRF)
      • Cross-Site Scripting (XSS)
      • Mass Parameter Assignment
      • Parameter Pollution
      • Path Traversal
      • Regular Expression Denial of Service (ReDoS)
      • SQL Injection (SQLi)
      • XML External Entity (XXE) Injection
Powered by GitBook
On this page
  • Overview
  • General
  • Cryptographically strong random generators
  1. Web Application
  2. Cryptography

Random Generators

PreviousHashingNextUniversal Unique Identifier (UUID)

Last updated 1 year ago

Overview

This page contains recommendations for generating random values.

General

  • Do not use standard pseudo-random number generators, such as those used in mathematics to generate pseudo-random numbers.

Clarification

Standard pseudo-random number generators can not withstand cryptographic attacks because such generators are based on functions that produce predictable values.

  • Make sure the seed that is used to initialize a generator has enough entropy.

  • Periodically reinitialize seeds.

Cryptographically strong random generators

import "crypto/rand"

func GetRandomBytes(length int) ([]byte, error) {
    r := make([]byte, length)
    if _, err := rand.Read(r); err != nil {
        return nil, err
    }
    return r, nil
}

func GetRandomString(length int) (string, error) {
    const alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    r := make([]byte, length)
    for i := 0; i < length; i++ {
        num, err := rand.Int(rand.Reader, big.NewInt(int64(len(alphabet))))
        if err != nil {
            return "", err
        }
        r[i] = alphabet[num.Int64()]
    }
    return string(ret), nil
}
// JDK8+
try {
    // UNIX-like and Windows
    // possible thread blocking for a UNIX-like OS
    SecureRandom secureRandomStrong = SecureRandom.getInstanceStrong();
    byte[] bytes = new byte[16];
    secureRandomStrong.nextBytes(bytes);
    // UNIX-like (without thread blocking)
    SecureRandom secureRandomNative = SecureRandom.getInstance("NativePRNGNonBlocking");
    byte[] bytes = new byte[16];
    secureRandomNative.nextBytes(bytes);
} catch(NoSuchAlgorithmException e) {
    throw new RuntimeException("Failed to instantiate random number generator", e);
}
// JDK <= 7
try {
    // Unix-like
    SecureRandom secureRandom = new SecureRandom();
    byte[] bytes = new byte[16];
    secureRandom.nextBytes(bytes);
    // Windows
    SecureRandom secureRandomWindows = SecureRandom.getInstance("Windows-PRNG");
    byte[] bytes = new byte[16];
    secureRandomWindows.nextBytes(bytes);
} catch(NoSuchAlgorithmException e) {
    throw new RuntimeException("Failed to instantiate random number generator", e);
}

Avoid using the SHA1PRNG generation algorithm. If it is necessary to use SHA1PRNG:

  1. Generate random values of length <= 20 bytes.

  2. Create a new instance of SecureRandom for each generation.

try {
    SecureRandom sha1Random = SecureRandom.getInstance("SHA1PRNG");
    byte[] bytes = new byte[20];
    sha1Random.nextBytes(bytes);
    // new instance for new generation
    sha1Random = SecureRandom.getInstance("SHA1PRNG");
    sha1Random.nextBytes(bytes); 
} catch(NoSuchAlgorithmException e) {
    throw new RuntimeException("Failed to instantiate random number generator", e);
}
const { randomBytes } = await import('node:crypto');
const buf = randomBytes(16);
const randomHex = buf.toString('hex');
import secrets

secrets.token_bytes(16)
# => b'\x1aQ\xd7\xb7\xad\t\x8aa[\xf5\xa6\x12\x89\xf5\x86\xa1'
secrets.token_hex(16)
# => '213c584a849a43da689ec65ac4f05518'
secrets.token_urlsafe(16)
# => 'KdZYoev-7aY7zpmDh_uz_w'

Use only cryptographically strong random generators to produce random values, see the section.

Use the package to generate cryptographically strong random values in Go.

Use the class to generate cryptographically strong random values.

Starting with JDK8, use SecureRandom.getInstanceStrong() to get a SecureRandom instance that implements a strong generation algorithm. For a UNIX-like OS, the default strong generation algorithm is , which is based on /dev/random. As a result, SecureRandom.getInstanceStrong() will return a SecureRandom implementation that can block a thread when the generateSeed or nextBytes methods are called. Use to avoid possible thread blocking.

For older versions of the JDK for UNIX-like OS, create a SecureRandom instance using the default constructor. However, in this case, calling the generateSeed method may cause thread blocking. For Windows, use .

Use the package to generate cryptographically strong random values.

Use the package to generate cryptographically strong random values.

crypto/rand
java.security.SecureRandom
NativePRNGBlocking
NativePRNGNonBlocking
Windows-PRNG
crypto
secrets
Cryptographically strong random generators