openssl req utf8 strings - utf-8

as others i'm struggling with utf8 in requests. sure i went through all preciding questions and answers. well here is my workout.
configuration:
[ req ]
default_bits = 2048
default_md = sha256
string_mask = utf8only
utf8 = yes
distinguished_name = DistName
attributes = Attr
[ DistName ]
commonName = Name (your official name)
commonName_default = hans nägli dödüé
stateOrProvinceName = State or Province Name (full name)
countryName = Country Code (2 letter code)
countryName_default = CH
[ Attr ]
subjectAltName = Name (international / latin)
subjectAltName_default = hans nägeli dädü
postalCode = zip code
localityName = Locality Name (eg, city)
emailAddress = Email Address
i verified this config file is utf8 and started thereafter using default values:
openssl req -verbose -config CsrPerson.cfg -new -key HansMuster-ecpem.key -passin pass:gugus -out HansMuster-pem.csr
i then had a look into the request using
openssl req -utf8 -noout -text -in HansMuster-pem.csr
showing
Certificate Request:
Data:
Version: 1 (0x0)
Subject: CN = hans n\C3\A4gli d\C3\B6d\C3\BC\C3\A9, ST = z\C3\BCrich, C = CH
Subject Public Key Info:
...snip...
NIST CURVE: P-384
Attributes:
postalCode :2222
localityName :Dörrhausen
X509v3 Subject Alternative Name:hans nägeli dädü
emailAddress :hans.naegeli#gmx.net
...snip...
using same source, same configuration, same procedure: subject/distinguished name has not been treated as utf8 but worked out well with attributes even with locality name which was entred by keyboard.
ASN1 definition of subject show a possible content as utf8 string. openssl version OpenSSL 1.1.0g 2 Nov 2017.
where have i been mistaken?
have fun

You can try the following:
openssl req -nameopt utf8 -noout -text -in HansMuster-pem.csr
This should only fix the display problem, you have to check if your other requirements are still met.
You can find more details about the "-nameopt" options here in the "NAME OPTIONS" section: https://www.openssl.org/docs/man1.0.2/man1/x509.html
Other related links:
How to create CSR with utf8 subject in openssl?

Related

Self signed certificate not working in Firefox

For quite some time, I am trying to generate a self signed cert for viewing website locally in "real" https mode. It would be very important that this works across all OSes and also all Browsers (at least FF, Chrome and Safari).
Until now I created the cert using this guide: https://medium.com/#tbusser/creating-a-browser-trusted-self-signed-ssl-certificate-2709ce43fd15
Certs using this way work fine in all systems, except with Android (version 8 or greater), so in this case I cannot use some functions correctly (for example the Service Worker) when testing locally.
Now I have stumbled upon this guide, especially the answer here: https://stackoverflow.com/a/57684211/1794480
I have adapted the conf file a bit, and now the generated cert works in Android, but NOT in Firefox. The Error in FF I get is: MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT. I also found an explanation for this error here: https://stackoverflow.com/a/59739121/1794480
Seems like basicConstraints = critical, CA:TRUE is the cuplrit here. However, the problem now is that this exact setting seems to be responsible for making this work on Android. (also see here: https://android.stackexchange.com/questions/237141/how-to-get-android-11-to-trust-a-user-root-ca-without-a-private-key/238859#238859)
Now, the big question is: is it possible to make this work for ALL systems, in this case including Firefox?
Here is the command I use: openssl req -config ./openssl.cnf -new -x509 -days 398 -out myServer.crt and here is the openssl.cnf:
[ req ]
default_bits = 2048
default_keyfile = myServer.key
default_md = sha256
default_days = 398
encrypt_key = yes
distinguished_name = req_distinguished_name
req_extensions = req_ext
x509_extensions = x509_ext
string_mask = utf8only
prompt = no
[ req_distinguished_name ]
commonName = myServer
emailAddress = info#myServer.de
[ x509_ext ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:TRUE
keyUsage = critical, digitalSignature, keyEncipherment, cRLSign, keyCertSign, dataEncipherment
subjectAltName = #alt_names
extendedKeyUsage = serverAuth
[ req_ext ]
authorityKeyIdentifier = keyid,issuer
basicConstraints = CA:FALSE
extendedKeyUsage = serverAuth
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = #alt_names
[ alt_names ]
DNS.1 = sub1.myServer
DNS.2 = sub2.myServer
Any help is greatly appreciated!

OpenSSL Subca and SAN Website Certificate

currently in my work, we have a PKI made with Microsoft Certificate Authority Role.
Root CA: Out of domain and turned off.
Sub CA: Domain connected, provides CRL (using IIS) and sign certificates for domain computers.
My idea is to reproduce the environment with Linux and Openssl. At least my first objective is for the internal webs.
I followed this tutorial https://jamielinux.com/docs/openssl-certificate-authority/ and everything works fine.
I create the Root CA and self-sign it.
I create the Subca, I sign it with the Root and verify that the certification chain is correct -> OK
The problem is when I try to create a website certificate with SAN (Subject Alternative Name) field. This is the way I create the csr and key files.
openssl req -nodes -new -newkey rsa:4096 \
-keyout test3.psc.local.key \
-out test3.psc.local.csr \
-addext "subjectAltName = DNS:test3.psc.local" \
-subj "/C=ES/ST=Barcelona/L=Barcelona/O=GRG-CA/OU=GRG-CA/emailAddress=your#email.dot/CN=test3.psc.local/"
If I check the CSR with OpenSSL command openssl x509 -noout -text -in test3.psc.local.csr the SAN field exist and has the value that I set in generation command (test3.psc.local).
Certificate Request:
Data:
Version: 1 (0x0)
Subject: C = ES, ST = Barcelona, L = Barcelona, O = GRG-CA, OU = GRG-CA, emailAddress = your#email.dot, CN = test3.psc.local
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (4096 bit)
Modulus:
00:dc:17:8c:c1:90:26:16:67:4e:16:b3:0c:9b:2b:
3d:ec:8e:94:47:b9:8c:b8:14:ac:be:09:b8:bb:f5:
d8:f2:79:26:a6:9d:2f:73:5b:48:64:cb:3a:c2:f6:
bd:6d:7f:fd:7e:f2:... bla bla bla
Exponent: 65537 (0x10001)
Attributes:
Requested Extensions:
X509v3 Subject Alternative Name:
DNS:test3.psc.local
Signature Algorithm: sha256WithRSAEncryption
b5:f0:7f:ba:ab:dc:f6:ee:37:c5:fa:14:27:6b:09:a8:b8:08:
0b:4f:ed:2a:44:72:cd:8d:50:47:79:7d:69:e3:73:cc:14:89:
b6:69:ff:61:bb:79:0a:41:12:32:c7:d1:6f:1d:a4:e4:cb:ef:
16:56:35:fd:44:0a:0c:70:fc:45:1f:7d:c2:d7:4c:ca:bd:66:
6d:e6:41:74:56:2c:... bla bla bla
When I try to sign the certificate with OpenSSL Subca I execute with this command.
openssl ca -config intermediate/sub-ca-openssl.cnf \
-extensions server_cert \
-days 375 -notext -md sha512 \
-in /root/ca/test3.psc.local.csr \
-out /root/ca/test3.psc.local.crt
But the SAN field isn't present, so Firefox, Chrome and others dont trust in certificate. Only IE11 trust.
Using configuration from intermediate/sub-ca-openssl.cnf
Enter pass phrase for /root/ca/intermediate/private/intermediate.key.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 4099 (0x1003)
Validity
Not Before: Oct 12 20:58:53 2022 GMT
Not After : Oct 22 20:58:53 2023 GMT
Subject:
countryName = ES
stateOrProvinceName = Barcelona
localityName = Barcelona
organizationName = GRG-CA
organizationalUnitName = GRG-CA
commonName = test3.psc.local
emailAddress = your#email.dot
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Cert Type:
SSL Server
Netscape Comment:
OpenSSL Generated Server Certificate
X509v3 Subject Key Identifier:
BC:11:0C:2E:08:FA:7D:91:16:1E:AC:0E:12:DA:80:69:64:F7:F1:58
X509v3 Authority Key Identifier:
keyid:7D:B8:7B:9E:59:4F:70:7B:F8:2C:1F:2B:0C:A2:E9:90:3C:D1:7A:71
DirName:/C=ES/ST=Barcelona/L=Barcelona/O=GRG-CA/OU=GRG-CA/CN=GRG Root CA
serial:10:00
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 CRL Distribution Points:
Full Name:
URI:http://pki.dominio.com/intermediate.crl
Certificate is to be certified until Oct 22 20:58:53 2023 GMT (375 days)
Sign the certificate? [y/n]:
Content of SUB CA config:
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = /root/ca/intermediate
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/subordinate-ca-database.txt
serial = $dir/serial
RANDFILE = $dir/private/.rand
private_key = $dir/private/intermediate.key.pem
certificate = $dir/certs/intermediate.cert.pem
crlnumber = $dir/crlnumber
crl = $dir/crl/intermediate.crl.pem
crl_extensions = crl_ext
default_crl_days = 365
default_md = sha512
name_opt = ca_default
cert_opt = ca_default
default_days = 5840
preserve = no
policy = subca_policy
[ subca_policy ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
string_mask = utf8only
default_md = sha512
x509_extensions = v3_ca
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
commonName = Common Name
emailAddress = Email Address
# Optionally, specify some defaults.
countryName_default = ES
stateOrProvinceName_default = Barcelona
localityName_default = Barcelona
0.organizationName_default = GRG-CA
organizationalUnitName_default = GRG-CA
#emailAddress_default =
[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical,CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection
[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
crlDistributionPoints = URI:http://pki.dominio.com/intermediate.crl
[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning
[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier=keyid:always
[ crl_info ]
URI.0 = http://pki.dominio.com/sub-ca.crl
URI.1 = https://www.dominio.com/pki/sub-ca.crl
I've read that I need a SAN.conf with alternate names in SUBCA server for sign... and change all Alternate Names for every CSR (website) that I want to sign... but in Microsoft Subca I dont need to tell that fields when I sign the CSR (only on generation, same command as I write before).
There is a way to do that?
From the man page for OpenSSL's CA command:
copy_extensions
determines how extensions in certificate requests should be handled.
If set to none or this option is not present then extensions are
ignored and not copied to the certificate. If set to copy then any
extensions present in the request that are not already present are
copied to the certificate. If set to copyall then all extensions in
the request are copied to the certificate: if the extension is already
present in the certificate it is deleted first. See the WARNINGS
section before using this option.
The main use of this option is to allow a certificate request to
supply values for certain extensions such as subjectAltName.
Also, you should understand that using OpenSSL as a CA isn't the best idea. There is no logging, no multi-person control etc. - basically no security. Read the WARNINGS section of the same man page.

How to generate csr and crt files using openssl in ruby

So i'm using AWS Iot and have a server running ruby on rails in the backend. i need to generate some certs for the client and the example on the AWS website only provides a way to do it using the openssl command line. If possible i would like to use the open ssl library in ruby to do this to avoid making ruby run commands in the terminal which may cause issues.
These are the commands i want to replicate using ruby
openssl genrsa -out deviceCert.key 2048
openssl req -new -key deviceCert.key -out deviceCert.csr
openssl x509 -req -in deviceCert.csr -CA sampleCACertificate.pem -CAkey sampleCACertificate.key -CAcreateserial -out deviceCert.crt -days 99999 -sha256
The first line i found and think i can do
require 'openssl'
rsa_key = OpenSSL::PKey::RSA.new(2048)
but i'm stuck on the last 2 lines. Any ideas?
Here is an example to generate a self signed certificate.
require 'rubygems'
require 'openssl'
key = OpenSSL::PKey::RSA.new(1024)
public_key = key.public_key
subject = "/C=BE/O=Test/OU=Test/CN=Test"
cert = OpenSSL::X509::Certificate.new
cert.subject = cert.issuer = OpenSSL::X509::Name.parse(subject)
cert.not_before = Time.now
cert.not_after = Time.now + 365 * 24 * 60 * 60
cert.public_key = public_key
cert.serial = 0x0
cert.version = 2
ef = OpenSSL::X509::ExtensionFactory.new
ef.subject_certificate = cert
ef.issuer_certificate = cert
cert.extensions = [
ef.create_extension("basicConstraints","CA:TRUE", true),
ef.create_extension("subjectKeyIdentifier", "hash"),
# ef.create_extension("keyUsage", "cRLSign,keyCertSign", true),
]
cert.add_extension ef.create_extension("authorityKeyIdentifier",
"keyid:always,issuer:always")
cert.sign key, OpenSSL::Digest::SHA1.new
puts cert.to_pem
Source for Example
was able to eventually figure it out using this rdoc example
http://ruby-doc.org/stdlib-2.0.0/libdoc/openssl/rdoc/OpenSSL/X509/Certificate.html#method-c-new

Decrypt PKCS7 in Ruby on Rails

I try to decrypt PKCS7 data, but always receive error OpenSSL::PKCS7::PKCS7Error - wrong content type on method "pkcs7.decrypt(key, cer)".
example:
cer = OpenSSL::X509::Certificate.new(File.read("path/cert.cer"))
key = OpenSSL::PKey::RSA.new(File.read("path/private.key"), "111111")
crypted_data = File.read('path/pkcs7') # contains xml-file and signature "-----BEGIN PKCS7----- ... -----END PKCS7-----"
pkcs7 = OpenSSL::PKCS7.new(crypted_data)
decrypted_data = pkcs7.decrypt(key, cer) # error is here
need help! how to get data from the encrypted string?
updated:
on bash I can solve this task by following code:
openssl smime -verify -noverify -inform PEM -nointern -certfile "path/cert.cer" -CAfile "path/cert.cer" < path/pkcs7
returns xml file.
Solution founded!!!
cert_store = OpenSSL::X509::Store.new
my_cert = OpenSSL::X509::Certificate.new(File.read("remote.cer"))
signature = OpenSSL::PKCS7.new(File.read('pkcs7-resp.file'))
signature.verify([my_cert], cert_store, nil, OpenSSL::PKCS7::NOVERIFY)
signature.data

How to create CSR with utf8 subject in openssl?

I am trying to generate Certificate Signing Request with UTF-8 subject.
$ openssl req -utf8 -nodes -newkey rsa:2048 -keyout my.private_key.pem -out my.csr.pem -text
Generating a 2048 bit RSA private key
......................................................................................................................................................................+++
......+++
writing new private key to 'my.private_key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [PL]:
State or Province Name (full name) []:Zażółć gęślą jaźń
problems making Certificate Request
12376:error:0D07A07C:asn1 encoding routines:ASN1_mbstring_ncopy:illegal characters:a_mbstr.c:162:
Terminal encoding is UTF-8, I get the same problem when I use command line subject
(...) -subj /C=PL/ST=zażółć\ gęślą\ jaźń/O=my-company/CN=ThisIsMeForSure
When I skip the -utf8 switch, the CSR is generated with all the non-ascii characters replaced with hex notation (eg ó becomes \xC3\xB3). Such CSR cannot be read properly with php (openss_x509_parse) - the original ó is read as four bytes, representing two weird characters...
What am I doing wrong?
I've been successful with command
openssl req -new -utf8 -nameopt multiline,utf8 -config example.com.cnf -newkey rsa:2048 -nodes -keyout example.com.key -out example.com.csr
Where example.com.cnf is a configuration file in UTF-8:
[req]
prompt = no
distinguished_name = dn
req_extensions = ext
[dn]
CN = Описание сайта # Site description
emailAddress = envek#envek.name
O = Моя компания # My company
OU = Моё подразделение # My dept
L = Москва # Moscow
C = RU
[ext]
subjectAltName = DNS:example.com,DNS:*.example.com
Displayed correctly in Chrome, Firefox, and Safari.
Try using the string_mask option:
string_mask
This option masks out the use of certain string types in certain fields. Most users will not need to change this option.
It can be set to several values default which is also the default option uses PrintableStrings, T61Strings and BMPStrings if the pkix value is used then only PrintableStrings and BMPStrings will be used. This follows the PKIX recommendation in RFC2459. If the utf8only option is used then only UTF8Strings will be used: this is the PKIX recommendation in RFC2459 after 2003. Finally the nombstr option just uses PrintableStrings and T61Strings: certain software has problems with BMPStrings and UTF8Strings: in particular Netscape.
Any unicode work for me, from php file.
<? shell_exec('openssl req -new -md5 -utf8 -key C:/Temp/1.key -out C:/Temp/1.csr -subj "/C=MD/ST=ff/O=Religie/OU=Cen/CN=中国/emailAddress=test#religiasatanista.ro" -config C:/Temp/openssl.cnf'); ?>

Resources