Check and Generate Prime Numbers with openssl prime
You will finish with commands that check candidate numbers, generate a prime of a chosen size, and distinguish a safe prime from an ordinary one. The examples use the installed OpenSSL 3.6.1 executable. Allow about ten minutes. You need a shell and the openssl command; none of these steps needs elevated privileges.
The route
Jump straight to the step you need, or tick off Done means at the end.
There is one version trap on this machine: the installed openssl-prime(1ssl) manpage carries an OpenSSL 3.0.13 header, while openssl version reports OpenSSL 3.6.1. The manpage is the contract used here. Check the executable and its own option summary before adapting a script:
$ command -v openssl
/home/linuxbrew/.linuxbrew/bin/openssl
$ openssl version
OpenSSL 3.6.1 27 Jan 2026 (Library: OpenSSL 3.6.1 27 Jan 2026)
$ openssl prime -help
Checkpoint
Continue only if the command you inspected is the one you intend to run. A system may have more than one OpenSSL installation.
1. Check decimal numbers
Pass one or more decimal integers after openssl prime. The command prints the input in hexadecimal, followed by its decimal value in parentheses, and says whether it is prime:
$ openssl prime 2 3 4 17 18
2 (2) is prime
3 (3) is prime
4 (4) is not prime
11 (17) is prime
12 (18) is not prime
This is a read-only test. A status line is not a cryptographic proof for an arbitrary application, and it does not select parameters for a protocol. It is a practical primality check using OpenSSL's implementation.
Capture the exit status immediately if a script needs to stop on an invalid command:
$ openssl prime 17 >/tmp/prime-check.txt
$ status=$?
$ printf 'openssl prime status: %s\n' "$status"
openssl prime status: 0
The temporary file is only for keeping the displayed result. Remove it when you no longer need it with rm -- /tmp/prime-check.txt. Do not use the output text as a substitute for checking the command status.
2. Check numbers from a file or a pipe
For input that does not fit comfortably on the command line, use -in with a file name. Each line is treated as a number:
$ printf '%s\n' 17 18 > /tmp/prime-input.txt
$ openssl prime -in /tmp/prime-input.txt
11 (17) is prime
12 (18) is not prime
The file contains decimal values here because that is the default input form. A pipe works too:
$ printf '%s\n' 17 18 | openssl prime -in /dev/stdin
11 (17) is prime
12 (18) is not prime
Checkpoint
Confirm the base before testing a value. The decimal string 17 means seventeen, not hexadecimal 0x17. Keep temporary test input free of secrets: prime testing does not encrypt the values it reads.
3. Use hexadecimal input deliberately
Add -hex when the numbers supplied to the command are hexadecimal. With -in, the same option changes the interpretation of each input line:
$ printf '%s\n' 11 12 | openssl prime -hex -in /dev/stdin
11 (11) is prime
12 (12) is not prime
In this example, 11 is hexadecimal eleven, which is decimal seventeen. Do not add a 0x prefix unless the installed command explicitly documents it as accepted input. The command's normal output is hexadecimal already, so -hex is most useful when it makes the input base unambiguous or when generating a hexadecimal result.
4. Generate a prime with a fixed bit length
If no numbers are supplied, use -generate. Add -bits to request the size. This example generates a 256-bit prime and writes it to a file without changing any system configuration:
$ openssl prime -generate -bits 256 > /tmp/prime-256.txt
$ tr -d '\n' < /tmp/prime-256.txt | wc -c
64
$ cat /tmp/prime-256.txt
...a 64-character hexadecimal value...
The exact value is random and will differ on every successful run. The output is decimal by default when generating. Request hexadecimal generation explicitly when you want a fixed 64-character representation for a 256-bit result:
$ openssl prime -generate -bits 16 -hex
C365
Do not treat a generated prime as a key, secret, or nonce merely because it is prime. If the value will protect data, use the key-generation operation specified by the protocol or application. Prime generation can also consume noticeable time at larger sizes.
5. Generate a safe prime
Add -safe alongside -generate when you need n to be prime and (n-1)/2 to be prime as well:
$ openssl prime -generate -bits 256 -safe
...a generated hexadecimal value...
The value is random, so verify the property by capturing it and checking both numbers. Keep the shell arithmetic out of this example: ordinary shell integers may be too small for a 256-bit result. OpenSSL can calculate (n-1)/2 with its arbitrary-precision calculator:
$ n=$(openssl prime -generate -bits 256 -safe)
$ half=$(printf '(%s - 1) / 2\n' "$n" | bc)
$ printf '%s\n' "$n" "$half" | openssl prime -in /dev/stdin
...the generated value... (...decimal value...) is prime
...the half value... (...decimal value...) is prime
The two reported prime results independently check the defining property. This verification uses bc, which supports the large decimal integers involved; install or select it according to your operating system's package policy if it is absent. Do not claim that a value is safe because -safe appeared in the command: preserve the generated value and record the command used to produce it.
6. Avoid the misleading options
The manpage lists -checks, but documents it as ignored. It does not increase confidence or make a check more thorough:
$ openssl prime -checks 1 17
11 (17) is prime
$ openssl prime -checks 100 17
11 (17) is prime
Do not build a security decision around a difference between those values. The provider options, -provider, -provider-path and -propquery, are for selecting OpenSSL providers and properties. Leave them at their defaults unless your deployment has a documented provider requirement. Loading an unintended provider can change which implementation is used.
Never paste untrusted text into an option string assembled by a shell script. Quote file names and values, use a fixed argument list, and validate the expected base and bit length before accepting output.
Done means
- You confirmed which OpenSSL executable and version your shell uses.
- You checked decimal input and, where needed, hexadecimal input with an explicit base.
- You generated a requested bit length with
-generate -bits. - You used
-safeonly when the extra(n-1)/2property was required. - You know that
-checksis ignored by this command. - You removed temporary files such as
/tmp/prime-input.txtand/tmp/prime-256.txtwhen finished.