Skip to footer content
.NET HELP

RandomNumberGenerator C#

Sometimes, when working with PDF documents, you might find yourself needing to generate random numbers or random strings. Whether you're generating random numbers and passwords for PDF encryption, creating unique file names, avoiding predictable sequences, or need to generate numbers for any other reason, using the RandomNumberGenerator C# class can help take your PDF generation and editing projects to the next level.

Unlike a basic random object created from the Random class, this cryptographic random number generator produces cryptographically strong random values suitable for cryptographic operations in secure applications.

In this article, we'll explore:

  • What RandomNumberGenerator is and why it matters.

  • How to use a cryptographic random number generator in C# to generate random numbers, random strings, and other random data for cryptographic purposes.

  • Practical examples of integrating RandomNumberGenerator with IronPDF to create secure, unique PDFs using the generated numbers and strings.

  • Tips and best practices to boost security and professionalism in your PDF applications.

What is the RandomNumberGenerator Class

Before diving into IronPDF integration, let's briefly revisit what makes RandomNumberGenerator special.

  • It is part of the System.Security.Cryptography namespace.

  • It generates cryptographically strong random values as random byte, much more secure than the typical Random class.

  • It's ideal for scenarios requiring unpredictability, such as generating secure tokens, keys, salts, and unique identifiers.

  • Uses Cryptographic algorithms like AES-CTR DRBG, Fortuna, or OS-provided CSPRNGs. Making it resistant to prediction.

  • Best used for tasks such as creating cryptographic keys, password generation, secure tokens, unique document IDs.

This strength comes from relying on the operating system’s underlying secure random number generators, making it resistant to prediction or reverse-engineering attacks. Unlike pseudo random number generators that may produce the same sequence with the same seed value, this class is designed for true randomness and cryptographic purposes.

Why Use RandomNumberGenerator Instead of C#'s Random Class?

Many developers start with C#’s Random class for generating random integers, but it’s not designed for high-security scenarios. Patterns in its output can be predicted, especially if the same seed value or system time is used, meaning the numbers generated could be guessed. This happens because the method generates values using simple modular arithmetic operations that can repeat with the same input.

In contrast, RandomNumberGenerator produces truly random numbers, derived from cryptographic random number generators in the .NET Framework or underlying OS. This ensures no low value bias and often uses a discard and retry strategy to maintain uniform distribution between a lower bound (e.g., int minValue) and an exclusive upper bound (e.g., int maxValue). The illustration below highlights the difference between a weak RNG and a secure one.

Weak vs. Secure RNG

Why Use RandomNumberGenerator with IronPDF

IronPDF is a robust .NET PDF library, enabling developers to create, edit, and secure PDF documents. Common use cases where randomness matters includes:

  • Unique Document Identifiers: Attach cryptographically secure IDs to PDFs for tracking or validation.

  • Secure Watermarks: Embed random watermarks or codes that deter forgery.

  • Encryption Keys or Passwords: Generate secure keys or passwords for PDF encryption.

  • Random Content: Add random unique tokens or salts to PDF documents for integrity verification.

How to Generate Secure Random Data in C

Here's a simple example of generating a 128-bit (16-byte) secure random token.

using System;
using System.Security.Cryptography;

public static string GenerateSecureToken(int size = 16)
{
    byte[] randomBytes = new byte[size];
    RandomNumberGenerator.Fill(randomBytes);
    return Convert.ToBase64String(randomBytes);
}
using System;
using System.Security.Cryptography;

public static string GenerateSecureToken(int size = 16)
{
    byte[] randomBytes = new byte[size];
    RandomNumberGenerator.Fill(randomBytes);
    return Convert.ToBase64String(randomBytes);
}
Imports System
Imports System.Security.Cryptography

Public Shared Function GenerateSecureToken(Optional ByVal size As Integer = 16) As String
	Dim randomBytes(size - 1) As Byte
	RandomNumberGenerator.Fill(randomBytes)
	Return Convert.ToBase64String(randomBytes)
End Function
$vbLabelText   $csharpLabel

This method creates a secure byte array and returns it as a Base64 string — perfect for embedding or tracking in unit tests, filenames, or secure IDs.

Practical Example: Adding Unique Document IDs to PDF Documents

Let's combine the power of RandomNumberGenerator and IronPDF to generate a PDF with a unique, secure document ID stamped on each page.

Step 1: Generate a Secure Document ID

string GenerateDocumentId()
{
    byte[] idBytes = new byte[12]; // 96-bit ID
    RandomNumberGenerator.Fill(idBytes);
    return BitConverter.ToString(idBytes).Replace("-", "");
}
string GenerateDocumentId()
{
    byte[] idBytes = new byte[12]; // 96-bit ID
    RandomNumberGenerator.Fill(idBytes);
    return BitConverter.ToString(idBytes).Replace("-", "");
}
Private Function GenerateDocumentId() As String
	Dim idBytes(11) As Byte ' 96-bit ID
	RandomNumberGenerator.Fill(idBytes)
	Return BitConverter.ToString(idBytes).Replace("-", "")
End Function
$vbLabelText   $csharpLabel

This produces a 24-character hex random string (e.g. "4F3A2C9B7D1E8F0A5B6C7D8E").

Step 2: Create the PDF and Stamp the ID

using IronPdf;

void CreatePdfWithSecureId()
{
    var documentId = GenerateDocumentId();

    var renderer = new ChromePdfRenderer();

    // Add a custom footer with the document ID
    renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
    {
        HtmlFragment = $"<div style='text-align: center; font-size: 10px;'>Document ID: {documentId} - Generated on {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} UTC</div>",
        DrawDividerLine = true,
    };
    var pdf = renderer.RenderHtmlAsPdf($"<h1>Secure Document</h1><p>Document ID: {documentId}</p>");

    string outputPath = $"SecurePdf_{documentId}.pdf";
    pdf.SaveAs(outputPath);

    Console.WriteLine($"PDF saved as {outputPath}");
}What this Code Does:
using IronPdf;

void CreatePdfWithSecureId()
{
    var documentId = GenerateDocumentId();

    var renderer = new ChromePdfRenderer();

    // Add a custom footer with the document ID
    renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
    {
        HtmlFragment = $"<div style='text-align: center; font-size: 10px;'>Document ID: {documentId} - Generated on {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} UTC</div>",
        DrawDividerLine = true,
    };
    var pdf = renderer.RenderHtmlAsPdf($"<h1>Secure Document</h1><p>Document ID: {documentId}</p>");

    string outputPath = $"SecurePdf_{documentId}.pdf";
    pdf.SaveAs(outputPath);

    Console.WriteLine($"PDF saved as {outputPath}");
}What this Code Does:
Imports IronPdf

Private Sub CreatePdfWithSecureId()
	Dim documentId = GenerateDocumentId()

	Dim renderer = New ChromePdfRenderer()

	' Add a custom footer with the document ID
	renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
		.HtmlFragment = $"<div style='text-align: center; font-size: 10px;'>Document ID: {documentId} - Generated on {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} UTC</div>",
		.DrawDividerLine = True
	}
	Dim pdf = renderer.RenderHtmlAsPdf($"<h1>Secure Document</h1><p>Document ID: {documentId}</p>")

	Dim outputPath As String = $"SecurePdf_{documentId}.pdf"
	pdf.SaveAs(outputPath)

	Console.WriteLine($"PDF saved as {outputPath}")
End Sub
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'What Me Code Does:
$vbLabelText   $csharpLabel
  • Generates a random number for a cryptographically secure, unique document ID.

  • Renders an HTML to PDF embedding that ID.

  • Adds a footer on every page with the document ID and timestamp.

  • Saves the PDF using the ID in the filename for easy tracking.

Full Working Code Example

using IronPdf;
using IronPdf.Editing;
using System;
using System.Security.Cryptography;

class Program
{
    public static void Main(string[] args)
    {
        // Create an instance of Program to run non-static methods
        var program = new Program();
        program.CreatePdfWithSecureId()
    }

    string GenerateDocumentId()
    {
        byte[] idBytes = new byte[12]; // 96-bit ID
        RandomNumberGenerator.Fill(idBytes);
        return BitConverter.ToString(idBytes).Replace("-", "");
    }

    void CreatePdfWithSecureId()
    {
        var documentId = GenerateDocumentId();

        var renderer = new ChromePdfRenderer();
        // Add a custom footer with the document ID
        renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
        {
            HtmlFragment = $"<div style='text-align: center; font-size: 10px;'>Document ID: {documentId} - Generated on {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} UTC</div>",
            DrawDividerLine = true,
        };
        var pdf = renderer.RenderHtmlAsPdf($"<h1>Secure Document</h1><p>Document ID: {documentId}</p>");

        string outputPath = $"SecurePdf_{documentId}.pdf";
        pdf.SaveAs(outputPath);

        Console.WriteLine($"PDF saved as {outputPath}");
    }
}
using IronPdf;
using IronPdf.Editing;
using System;
using System.Security.Cryptography;

class Program
{
    public static void Main(string[] args)
    {
        // Create an instance of Program to run non-static methods
        var program = new Program();
        program.CreatePdfWithSecureId()
    }

    string GenerateDocumentId()
    {
        byte[] idBytes = new byte[12]; // 96-bit ID
        RandomNumberGenerator.Fill(idBytes);
        return BitConverter.ToString(idBytes).Replace("-", "");
    }

    void CreatePdfWithSecureId()
    {
        var documentId = GenerateDocumentId();

        var renderer = new ChromePdfRenderer();
        // Add a custom footer with the document ID
        renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
        {
            HtmlFragment = $"<div style='text-align: center; font-size: 10px;'>Document ID: {documentId} - Generated on {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} UTC</div>",
            DrawDividerLine = true,
        };
        var pdf = renderer.RenderHtmlAsPdf($"<h1>Secure Document</h1><p>Document ID: {documentId}</p>");

        string outputPath = $"SecurePdf_{documentId}.pdf";
        pdf.SaveAs(outputPath);

        Console.WriteLine($"PDF saved as {outputPath}");
    }
}
Imports IronPdf
Imports IronPdf.Editing
Imports System
Imports System.Security.Cryptography

Friend Class Program
	Public Shared Sub Main(ByVal args() As String)
		' Create an instance of Program to run non-static methods
'INSTANT VB NOTE: The variable program was renamed since it may cause conflicts with calls to static members of the user-defined type with this name:
		Dim program_Conflict As New Program()
		program_Conflict.CreatePdfWithSecureId()
	End Sub

	Private Function GenerateDocumentId() As String
		Dim idBytes(11) As Byte ' 96-bit ID
		RandomNumberGenerator.Fill(idBytes)
		Return BitConverter.ToString(idBytes).Replace("-", "")
	End Function

	Private Sub CreatePdfWithSecureId()
		Dim documentId = GenerateDocumentId()

		Dim renderer = New ChromePdfRenderer()
		' Add a custom footer with the document ID
		renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
			.HtmlFragment = $"<div style='text-align: center; font-size: 10px;'>Document ID: {documentId} - Generated on {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss} UTC</div>",
			.DrawDividerLine = True
		}
		Dim pdf = renderer.RenderHtmlAsPdf($"<h1>Secure Document</h1><p>Document ID: {documentId}</p>")

		Dim outputPath As String = $"SecurePdf_{documentId}.pdf"
		pdf.SaveAs(outputPath)

		Console.WriteLine($"PDF saved as {outputPath}")
	End Sub
End Class
$vbLabelText   $csharpLabel

Output

PDF with Document ID

Advanced Use Case: Secure PDF Encryption with Random Keys

IronPDF supports PDF encryption, providing strong support for secure PDF creation. You can use RandomNumberGenerator to create strong passwords or keys for encryption:

using IronPdf;
using IronPdf.Editing;
using System;
using System.Security.Cryptography;

class Program
{
    public static void Main(string[] args)
    {
        // Create an instance of Program to run non-static methods
        var program = new Program();
        program.CreateEncryptedPdf();
    }

    string GenerateSecurePassword(int length = 12)
    {
        const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()";
        byte[] data = new byte[length];
        RandomNumberGenerator.Fill(data);

        char[] result = new char[length];
        for (int i = 0; i < length; i++)
        {
            result[i] = chars[data[i] % chars.Length];
        }
        return new string(result);
    }

    void CreateEncryptedPdf()
    {
        string password = GenerateSecurePassword();

        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Confidential PDF</h1><p>Access is restricted.</p>");

        // Set security settings
        pdf.SecuritySettings.UserPassword = password;
        pdf.SecuritySettings.AllowUserAnnotations = false;
        pdf.SecuritySettings.AllowUserCopyPasteContent = false;
        pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.NoPrint;

        string filePath = "EncryptedSecurePdf.pdf";
        pdf.SaveAs(filePath);

        Console.WriteLine($"Encrypted PDF saved to {filePath} with password: {password}");
    }
}
using IronPdf;
using IronPdf.Editing;
using System;
using System.Security.Cryptography;

class Program
{
    public static void Main(string[] args)
    {
        // Create an instance of Program to run non-static methods
        var program = new Program();
        program.CreateEncryptedPdf();
    }

    string GenerateSecurePassword(int length = 12)
    {
        const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()";
        byte[] data = new byte[length];
        RandomNumberGenerator.Fill(data);

        char[] result = new char[length];
        for (int i = 0; i < length; i++)
        {
            result[i] = chars[data[i] % chars.Length];
        }
        return new string(result);
    }

    void CreateEncryptedPdf()
    {
        string password = GenerateSecurePassword();

        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Confidential PDF</h1><p>Access is restricted.</p>");

        // Set security settings
        pdf.SecuritySettings.UserPassword = password;
        pdf.SecuritySettings.AllowUserAnnotations = false;
        pdf.SecuritySettings.AllowUserCopyPasteContent = false;
        pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.NoPrint;

        string filePath = "EncryptedSecurePdf.pdf";
        pdf.SaveAs(filePath);

        Console.WriteLine($"Encrypted PDF saved to {filePath} with password: {password}");
    }
}
Imports IronPdf
Imports IronPdf.Editing
Imports System
Imports System.Security.Cryptography

Friend Class Program
	Public Shared Sub Main(ByVal args() As String)
		' Create an instance of Program to run non-static methods
'INSTANT VB NOTE: The variable program was renamed since it may cause conflicts with calls to static members of the user-defined type with this name:
		Dim program_Conflict As New Program()
		program_Conflict.CreateEncryptedPdf()
	End Sub

	Private Function GenerateSecurePassword(Optional ByVal length As Integer = 12) As String
		Const chars As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()"
		Dim data(length - 1) As Byte
		RandomNumberGenerator.Fill(data)

		Dim result(length - 1) As Char
		For i As Integer = 0 To length - 1
			result(i) = chars.Chars(data(i) Mod chars.Length)
		Next i
		Return New String(result)
	End Function

	Private Sub CreateEncryptedPdf()
		Dim password As String = GenerateSecurePassword()

		Dim renderer = New ChromePdfRenderer()
		Dim pdf = renderer.RenderHtmlAsPdf("<h1>Confidential PDF</h1><p>Access is restricted.</p>")

		' Set security settings
		pdf.SecuritySettings.UserPassword = password
		pdf.SecuritySettings.AllowUserAnnotations = False
		pdf.SecuritySettings.AllowUserCopyPasteContent = False
		pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.NoPrint

		Dim filePath As String = "EncryptedSecurePdf.pdf"
		pdf.SaveAs(filePath)

		Console.WriteLine($"Encrypted PDF saved to {filePath} with password: {password}")
	End Sub
End Class
$vbLabelText   $csharpLabel

This method uses default implementation from the OS’s RNG, producing a password suitable for cryptographic operations.

This will apply the generated secure password, so only users with access to the passwords will be able to view the document.

Password-protection pop-up

Additionally, we will be left with a encrypted, secure document with our set permissions:

Encrypted PDF settings

Best Practices and Tips

  • Always use RandomNumberGenerator for anything security-related. Avoid Random for IDs, tokens, or passwords.

  • Keep sensitive data out of logs or user-facing messages, but log enough to track and audit.

  • Consider using timestamps and other metadata alongside random IDs for better traceability.

  • Use IronPDF's built-in security features combined with random keys to protect your documents.

  • Validate random data length and encoding to ensure usability in your context (e.g., filenames, URLs, barcodes).

Summary

Integrating C#'s RandomNumberGenerator class with IronPDF empowers you to generate secure, unique PDFs that meet modern security standards. Whether you're stamping unique ID's, generating encryption keys, or embedding secure tokens, this approach helps you:

  • Prevent document forgery

  • Improve traceability

  • Secure sensitive data within your PDFs

By combining the cryptographic strength of this class with IronPDF's versatile PDF tools, your PDF solutions become safer and more professional.

Try It Yourself!

Ready to boost your PDF security? Try the IronPDF free trial and start experimenting with secure random data today!

Chipego
Software Engineer
Chipego has a natural skill for listening that helps him to comprehend customer issues, and offer intelligent solutions. He joined the Iron Software team in 2023, after studying a Bachelor of Science in Information Technology. IronPDF and IronOCR are the two products Chipego has been focusing on, but his knowledge of ...Read More