Putting extensions in a certificate in OpenSSL - linux

I need to put extensions in a certificate like this in the picture, I tried many ways, but I can not.
I'm running:
"#openssl req -new -keyout $nomerepre.key -out $nomerepre.csr -passin pass:$senha -config myconfig.cnf"
"#openssl x509 -req -days 365 -in $nomerepre.csr -CA ca.crt -CAkey ca.key -set_serial 10102014 -out $nomerepre.crt -passin pass:$senha -extfile myconfig.cnf -extensions v3_req"
My configuration file is thus below
myconfigssl.conf
oid_section = OIDs
[ req ]
default_bits = 2048
prompt = no
encrypt_key = no
default_md = sha1
distinguished_name = dn
req_extensions = v3_req
[ OIDs ]
MyOID=2.16.76.1.3.4
[ dn ]
CN = John Smith
emailAddress = john.smith#quovadisglobal.com
O = QuoVadis Group
C = US
[v3_req]
1.2.3.4.5.6.7.8=ASN1:UTF8String:Something
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
#subjectAltName = #alt_names
[alt_names]
MyOID = 00000000111111111112222222222233333333333444444
2.16.76.1.3.4 = 00000000111111111112222222222233333333333444444
Unfortunately the result that this is going:

I don't understand why you got no extensions as shown in EG2Oa.jpg. You should have extension 1.2.3.4.5.6.7.8 there. SubjectAltName is commented so it should not be in the certificate.
I tried using xca which uses OpenSSL 1.0.2d as show in the picture
I used this config
# if it should be a separate extension
2.16.76.1.3.4=ASN1:UTF8String:Some random data
#if it should be a part of subjectAltName
subjectAltName=#subject_alt_section
[subject_alt_section]
otherName=2.16.76.1.3.4;UTF8:Some random data
And I got this certificate
Now some theory. I don't know where this extension should be placed. If it is a separate extension or if it should be a part of SubjectAltName. I don't know if the extension should be an UTF8String or OctetString or a Sequence of something.
If you want a separate extension you can use 2.16.76.1.3.4=ASN1:UTF8String:Some random data as you already tried. More on arbitrary extensions can be found here.
This extension can be part of subjectAltName according to the description of the oid. Definition of otherName can be found in RFC5280 in section 4.2.1.6. If so then this config worked for me
subjectAltName=#subject_alt_section
[subject_alt_section]
otherName=2.16.76.1.3.4;UTF8:Some random data
Using the above mentioned config I've got structure of the certificate as shown in the picture below. ASN1Editor was used to show the structure.

Related

Export RSA Keys to stunnel.key [duplicate]

I followed this url to create a X509 certificate. And the code is:
from OpenSSL import crypto, SSL
from socket import gethostname
from pprint import pprint
from time import gmtime, mktime
CERT_FILE = "selfsigned.crt"
KEY_FILE = "private.key"
def create_self_signed_cert():
# create a key pair
k = crypto.PKey()
k.generate_key(crypto.TYPE_<wbr>RSA, 1024)
# create a self-signed cert
cert = crypto.X509()
cert.get_subject().C = "UK"
cert.get_subject().ST = "London"
cert.get_subject().L = "London"
cert.get_subject().O = "Dummy Company Ltd"
cert.get_subject().OU = "Dummy Company Ltd"
cert.get_subject().CN = gethostname()
cert.set_serial_number(1000)
cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(10*<wbr>365*24*60*60)
cert.set_issuer(cert.get_<wbr>subject())
cert.set_pubkey(k)
cert.sign(k, 'sha1')
open(CERT_FILE, "wt").write(
crypto.dump_certificate(<wbr>crypto.FILETYPE_PEM, cert))
open(KEY_FILE, "wt").write(
crypto.dump_privatekey(crypto.<wbr>FILETYPE_PEM, k))
create_self_signed_cert()
But there is something wrong with the code when I run it. Could someone tell me what the meaning of <wbr>? There is a SyntaxError in cert.gmtime_adj_notAfter(10*<wbr>365*24*60*60). Thx.
A version which works with python3
from OpenSSL import crypto, SSL
def cert_gen(
emailAddress="emailAddress",
commonName="commonName",
countryName="NT",
localityName="localityName",
stateOrProvinceName="stateOrProvinceName",
organizationName="organizationName",
organizationUnitName="organizationUnitName",
serialNumber=0,
validityStartInSeconds=0,
validityEndInSeconds=10*365*24*60*60,
KEY_FILE = "private.key",
CERT_FILE="selfsigned.crt"):
#can look at generated file using openssl:
#openssl x509 -inform pem -in selfsigned.crt -noout -text
# create a key pair
k = crypto.PKey()
k.generate_key(crypto.TYPE_RSA, 4096)
# create a self-signed cert
cert = crypto.X509()
cert.get_subject().C = countryName
cert.get_subject().ST = stateOrProvinceName
cert.get_subject().L = localityName
cert.get_subject().O = organizationName
cert.get_subject().OU = organizationUnitName
cert.get_subject().CN = commonName
cert.get_subject().emailAddress = emailAddress
cert.set_serial_number(serialNumber)
cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(validityEndInSeconds)
cert.set_issuer(cert.get_subject())
cert.set_pubkey(k)
cert.sign(k, 'sha512')
with open(CERT_FILE, "wt") as f:
f.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert).decode("utf-8"))
with open(KEY_FILE, "wt") as f:
f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, k).decode("utf-8"))
cert_gen()
Just remove <wbr>. So stupid I am.
This is a really useful question; as the referenced link is now dead; and this is one of the first results for searching for "python create ssl certificate".
I would add to it though, that "open(xxx, "wt").write()" is asking for problems later. By not explicitly closing the file, you may find that the garbage collector hasn't run when you try to actually use the file - resulting in a failure.
it's better to use:
with open(xxx, "w") as f:
f.write()
which will ensure that the file is closed when you're done.

Openssl: error 20 at 0 depth lookup:unable to get local issuer certificate

I created 3 certificates using Python: rootca.crt, intermediateca.crt and server.crt.
I used the rootca.crt to sign intermediateca.crt, which works as expected:
openssl verify -CAfile rootca.crt intermediateca.crt
intermediateca.crt: OK
Then I signed the server.crt with the intermediate ca, but verification fails:
openssl verify -CAfile rootca.crt -untrusted intermediateca.crt server.crt
server.crt: C = DE, ST = mein Bundesland, L = meine Stadt, O = meine Firma, CN = server.example.com, emailAddress = info#meine-firma.de
error 20 at 0 depth lookup:unable to get local issuer certificate
When I parse the certificates, the server.crt authority key identifier matches the intermediateca subject key identifier. Can anyone give me a hint what could be wrong? If I generate the same certificates with the openssl command line tool it works. The parsed content is identical, apart from the fact that the authority key identifier also contains a serial and a cn for the openssl generated certificate.
The intermediate CA cannot be used to verify the server certificate because its subject name does not match the issuer name specified in the server certificate.
Let's have openssl dump the subject and issuer names. The -xx_hash shows the hash that openssl uses to build up the certificate chain:
$ openssl x509 -subject -subject_hash -noout -in rootca.crt
subject=C = DE, ST = mein Bundesland, L = meine Stadt, O = meine Firma, OU = meine Abteilung, CN = serviceserver.example.com, emailAddress = info#meine-firma.de
347e2056
$ openssl x509 -issuer -issuer_hash -noout -in intermediateca.crt
issuer=C = DE, ST = mein Bundesland, L = meine Stadt, O = meine Firma, OU = meine Abteilung, CN = serviceserver.example.com, emailAddress = info#meine-firma.de
347e2056
Great, the intermediate's Issuer name matches the root's Subject name. That part of the chain works.
$ openssl x509 -subject -subject_hash -noout -in intermediateca.crt
subject=C = DE, ST = mein Bundesland, L = meine Stadt, O = meine Firma, CN = serviceserver.example.com, emailAddress = info#meine-firma.de
c4dff14c
$ openssl x509 -issuer -issuer_hash -noout -in server.crt
issuer=C = DE, ST = mein Bundesland, L = meine Stadt, O = meine Firma, OU = meine Abteilung, CN = serviceserver.example.com, emailAddress = info#meine-firma.de
347e2056
Oops: the hash is different, so openssl cannot connect the intermediate CA to the server certificate. The difference is that the intermediate's subject name contains a OU field whereas the server's issuer name does not. openssl was correct when it told you that it could not find an issuer.
I'm not sure how you got it in this state, my guess would be some misconfiguration of the subject or issuer name.

Get cert & key for python signxml from a PKS file

I used following command to get cert & key from a pks file.
openssl pkcs12 -in ../my.pfx -nocerts -out my.key
openssl pkcs12 -in ~/my.pfx -clcerts -nokeys -out cert.pem
However I keep getting error. I suspect my.key is not correct. How to generate the correct key and cert to feed signxml? I use python3.5 on Ubuntu 16.04. Thank you in advance!
File "/home/ubuntu/.local/lib/python3.5/site-packages/signxml/__init__.py", line 362, in sign
key = load_pem_private_key(key, password=passphrase, backend=default_backend())
File "/home/ubuntu/.local/lib/python3.5/site-packages/cryptography/hazmat/primitives/serialization/base.py", line 16, in load_pem_private_key
return backend.load_pem_private_key(data, password)
File "/home/ubuntu/.local/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1025, in load_pem_private_key
password,
File "/home/ubuntu/.local/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1218, in _load_key
mem_bio = self._bytes_to_bio(data)
File "/home/ubuntu/.local/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 454, in _bytes_to_bio
data_ptr = self._ffi.from_buffer(data)
TypeError: from_buffer() cannot return the address of a unicode object
The sample code from xml page:
cert = open("example.pem").read()
key = open("example.key").read()
root = ElementTree.fromstring(data_to_sign)
signed_root = XMLSigner().sign(root, key=key, cert=cert)
verified_data = XMLVerifier().verify(signed_root).signed_xml
I guess it is Python2 vs Python3 thing. All I needed is
key = open("example.key").read().encode('ascii')

Different results when encrypting with OpenSSL

I have a strange case when I try to do encryption with OpenSSL
Details:
I try to encrypt file with "Hello World!"
Password (String): "testtesttesttest"
Password (HEX): 74657374746573747465737474657374
Terminal commands to encrypt file:
For plain text password
openssl aes-128-cbc -e -a -nosalt -iv [some vector] -k [password] -in [input file] -out [output file]
openssl aes-128-cbc -e -a -nosalt -iv [some vector] -pass pass:[password] -in [input file] -out [output file]
For password in HEX format
openssl aes-128-cbc -e -a -nosalt -iv [some vector] -K [HEX password] -in [input file] -out [output file]
So the only difference in commands is that one uses plain text password while another uses the same password but in HEX form. So in my opinion the result of encryption should be the same. But the Base64 output is actually different.
Maybe somebody know and can hint what could be the case here?
Another case that now I develop a small application that encrypts files on Blackberry phone and I would that it would be compatible with other encryption software like OpenSSL that are available on PC. So the Base64 output of my application is not the same as OpenSSL produces with the given password.
The sample code looks like this:
String testKey = "testtesttesttest"; (example)
byte[] aesKeyAsBytes = testKey.getBytes();
AESKey aesKey = new AESKey(aesKeyAsBytes);
AESEncryptorEngine engine = new AESEncryptorEngine(aesKey);
CBCEncryptorEngine cengine=new CBCEncryptorEngine(engine, new InitializationVector(_initVector));
PKCS5FormatterEngine fengine = new PKCS5FormatterEngine(cengine);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BlockEncryptor cryptoStream = new BlockEncryptor(fengine, outputStream);
cryptoStream.write(plainText, 0, numOfPlainTextBytes);
cryptoStream.close();
byte[] cipherText = outputStream.toByteArray();
outputStream.close();
return cipherText;
I used the following inputs as test data for this scenario:
Key (Hex): 01010101010101010101010101010101
IV (Hex): 02020202020202020202020202020202
Plaintext: Hello, World!
Using the above inputs with the following command in OpenSSL:
openssl aes-128-cbc -K 01010101010101010101010101010101 -iv 02020202020202020202020202020202 -e -a -in in.txt -out out-openssl.txt
Gave me a result of:
wT6aF/PXrGhxEwyX6mNfXA==
Using the C# System.Security.Cryptography namespace, which has a raw AES implementation that we can test against, I used the following code:
using (AesManaged aes = new AesManaged())
{
aes.KeySize = 128;
aes.Padding = PaddingMode.PKCS7;
aes.Key = new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
aes.IV = new byte[] { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
byte[] plaintext = Encoding.UTF8.GetBytes("Hello, World!");
ICryptoTransform t = aes.CreateEncryptor();
byte[] ciphertext = t.TransformFinalBlock(plaintext, 0, plaintext.Length);
Console.WriteLine(Convert.ToBase64String(ciphertext));
}
To produce the exact same base64 result of:
wT6aF/PXrGhxEwyX6mNfXA==
This demonstrates that the OpenSSL command above is the correct one to use if you wish for the key to be used exactly as provided (e.g. the -K flag with the uppercase K).
As I mentioned in comments, OpenSSL does use a KDF when providing a password as plaintext, as detailed in this answer.
From man page for enc which should be present on any Unixy system (sometimes under a modified section like 1ssl) or current release on the web:
-k password
the password to derive the key from. This is for compatibility with
previous versions of OpenSSL. Superseded by the -pass argument.
-kfile filename
read the password to derive the key from the first line of
filename. This is for compatibility with previous versions of
OpenSSL. Superseded by the -pass argument.
-K key
the actual key to use: this must be represented as a string
comprised only of hex digits. If only the key is specified, the IV ...
Do you see any difference between '(the) password the key is derived from' and 'the actual key'?
PS: since -K does not do key derivation, the arguments related to salt -nosalt -salt -S have no effect on it and are ignored.

Self signed SAN certificate failed to be verifed [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I followed this instruction to create a self-signed certificate
http://apetec.com/support/GenerateSAN-CSR.htm. However, the certificate is always failed to be verified and my tls connection program can't setup connection using this certificate.
Any idea why and how to solve it?
The following is the commands to generate the certificate and result of verification.
$ openssl genrsa -out private.key 2048
$ openssl req -new -out public.csr -key private.key -config openssl.conf
$ openssl req -text -noout -in public.csr
$ openssl x509 -req -days 365 -in public.csr -signkey private.key -out public.crt -extensions v3_req -extfile openssl.conf
$ openssl verify -CAfile public.crt public.crt
public.crt: O = My Company, L = My Town, ST = State or Providence, C = US
error 20 at 0 depth lookup:unable to get local issuer certificate
The following is the openssl.conf. The ip address is partially crossed out.
#
# OpenSSL configuration file.
#
# Establish working directory.
dir = .
[ ca ]
default_ca = CA_default
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
default_bits = 1024 # Size of keys
default_keyfile = key.pem # name of generated keys
default_md = md5 # message digest algorithm
string_mask = nombstr # permitted characters
distinguished_name = req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
# Variable name Prompt string
#------------------------- ----------------------------------
0.organizationName = Organization Name (company)
organizationalUnitName = Organizational Unit Name (department, division)
emailAddress = Email Address
emailAddress_max = 40
localityName = Locality Name (city, district)
stateOrProvinceName = State or Province Name (full name)
countryName = Country Name (2 letter code)
countryName_min = 2
countryName_max = 2
commonName = Common Name (hostname, IP, or your name)
commonName_max = 64
# Default values for the above, for consistency and less typing.
# Variable name Value
#------------------------ ------------------------------
0.organizationName_default = My Company
localityName_default = My Town
stateOrProvinceName_default = State or Providence
countryName_default = US
[ v3_ca ]
basicConstraints = CA:TRUE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
[ v3_req ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = #alt_names
[alt_names]
IP.1 = 1xx.1x.1xx.xxx
What you are generating is a self-signed root certificate. OpenSSL attempts to verify certificates by chaining certificates up to a trusted root that is present in its certificate store. Since yours is (obviously) not in that store it will always fail.
Here are three ways to get rid of the warnings:
Disable certificate verification
This is generally a bad idea because without certificate verification you have completely disabled the identity component of a TLS handshake. Use it only in development (and never let it leak to production!)
Add your root certificate to the trust store
This will work provided you're willing to install the certificate on every machine that needs to talk to this endpoint. (For OpenSSL this is a ca_bundle file that is located in a distribution specific location)
Buy a cert from a CA
The easiest, but also the one that costs $$$. If you do this then the site you're installing this certificate on will be trusted globally.

Resources