How to Generate a CSR with Interactive SANs Prompt in OpenSSL Correctly


2 views

When generating a Certificate Signing Request (CSR) with OpenSSL, you might want to dynamically prompt for Subject Alternative Names (SANs) rather than hardcoding them in the configuration file. The standard approach of adding subjectAltName = Alternative subject names to the [req_attributes] section results in malformed CSRs, as OpenSSL fails to properly encode the attribute.

The problem occurs because OpenSSL treats the interactively entered SANs as an opaque attribute rather than a properly formatted X.509v3 extension. The output shows X509v3 Subject Alternative Name:unable to print attribute, indicating the data wasn't parsed correctly.

To correctly handle interactive SANs, you need to modify your openssl.cnf with these sections:

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
attributes = req_attributes

[req_distinguished_name]
# Your standard DN fields here
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name (full name)
localityName = Locality Name (eg, city)
organizationName = Organization Name (eg, company)
commonName = Common Name (e.g. server FQDN)

[req_attributes]
subjectAltName = Alternative subject names (e.g. DNS:example.com)

[v3_req]
subjectAltName = @alt_names

[alt_names]
# This will be dynamically replaced
DNS.1 = $ENV::SAN_DNS_1

Use this bash script approach to properly handle interactive SANs:

#!/bin/bash
read -p "Enter SANs (format: DNS:example.com,DNS:alt.example.com): " sans

# Split SANs and prepare environment variables
IFS=',' read -ra SAN_ARRAY <<< "$sans"
for i in "${!SAN_ARRAY[@]}"; do
  export "SAN_DNS_$((i+1))"="${SAN_ARRAY[$i]#*:}"
done

openssl req -new -key server.key -out server.csr -config openssl.cnf

After generation, verify the CSR contains proper SANs:

openssl req -text -noout -in server.csr | grep -A1 "Subject Alternative Name"

The output should now correctly display:

X509v3 Subject Alternative Name:
    DNS:example.com, DNS:alt.example.com

For newer OpenSSL versions (1.1.1+), you can use the -addext flag:

openssl req -new -key server.key -out server.csr \
  -addext "subjectAltName = DNS:example.com,DNS:alt.example.com"

This approach is cleaner but requires newer OpenSSL versions and doesn't provide interactive prompting.

1. Always verify your CSR with openssl req -text -noout -in file.csr before submission
2. Different CAs might have specific requirements for SAN formatting
3. For production environments, consider automating the process rather than interactive input


When working with OpenSSL's certificate signing requests (CSRs), many developers want to interactively specify Subject Alternative Names (SANs) during CSR generation rather than hardcoding them in the configuration file. While adding subjectAltName = Alternative subject names to the [req_attributes] section prompts for SANs, the resulting CSR often shows formatting issues:

$ openssl req -text -in ./test.csr
[...]
Attributes:
    X509v3 Subject Alternative Name:unable to print attribute

To correctly handle interactive SANs, we need to modify both the configuration and the command-line arguments:

[ req ]
distinguished_name = req_distinguished_name
req_extensions = v3_req
attributes = req_attributes

[ req_distinguished_name ]
[...]

[ req_attributes ]
subjectAltName = Alternative subject names

[ v3_req ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = placeholder.example.com  # Required for proper structure

Here's how to properly generate a CSR with interactive SANs:

#!/bin/bash
# Prompt for SANs
read -p "Enter Subject Alternative Names (comma-separated DNS: entries): " sans

# Generate temporary config
cat > /tmp/openssl.cnf <

After generation, verify the CSR contains proper SANs:

openssl req -in request.csr -noout -text | grep -A1 "Subject Alternative Name"
X509v3 Subject Alternative Name:
    DNS:alt1.example.com, DNS:alt2.example.com

For more complex scenarios, consider using OpenSSL's environment variables:

export OPENSSL_CONF=./custom_openssl.cnf
openssl req -new -key server.key -out server.csr \
  -subj "/C=US/ST=California/L=San Francisco/O=Example Inc/CN=example.com" \
  -addext "subjectAltName = DNS:www.example.com, DNS:test.example.com"