Pythonでコマンドを送信するときにbash角かっこを引用符で囲むことができることを読んだ。この例では、シェルで実行されるコマンドを使用してopensslのキーとcsrを生成しようとしていますが、Pythonで実行すると生成しません。いくつかの組み合わせを試しましたが、引き続き別の問題が発生しました。
次のPythonコマンドは失敗します。
import os
os.system('openssl req -nodes -newkey rsa:2048 -sha256 -keyout mynode.key -out mynode.csr -subj "/C=US/ST=Florida/L=St Petersburg/O=MyCompany/OU=MyOU/CN=mynode/[email protected]" -reqexts OPTS -config <(cat /etc/pki/tls/openssl.cnf <(printf "[OPTS]\ basicConstraints = CA:FALSE subjectAltName = DNS:mynode,DNS:myf5 keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = serverAuth, clientAuth"))')
デフォルトのopensslコマンドが成功しました。
openssl req -nodes -newkey rsa:2048 -sha256 -keyout mynode.key -out mynode.csr -subj "/C=US/ST=Florida/L=St Petersburg/O=MyCompany/OU=MyOU/CN=mynode/[email protected]" -reqexts OPTS -config <(cat /etc/pki/tls/openssl.cnf <(printf "[OPTS]\ basicConstraints = CA:FALSE subjectAltName = DNS:mynode,DNS:myf5 keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = serverAuth, clientAuth"))
これは簡単なはずですが、答えが見つかりません。
答え1
<(…)
bash(およびkshとzsh)には存在しますが、通常のshには存在しないプロセスの置き換えです。このsystem
関数は bash ではなく sh を呼び出します。
パイプでプロセス置換を使用し、入れ子にopenssl
なったプロセス置換を簡単なコマンドシーケンスに減らすことができます。
{ cat /etc/pki/tls/openssl.cnf;
printf "[OPTS]\ basicConstraints = CA:FALSE subjectAltName = DNS:mynode,DNS:myf5 keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = serverAuth, clientAuth";
} | openssl req -nodes -newkey rsa:2048 -sha256 -keyout mynode.key -out mynode.csr -subj "/C=US/ST=Florida/L=St Petersburg/O=MyCompany/OU=MyOU/CN=mynode/[email protected]" -reqexts OPTS -config -
(改行オプション)
答え2
ご回答ありがとうございます。私はそれについて考えて、これを行うPythonの基本的な方法を見つけることにしました。十分な情報を持っているPython暗号チートシートウェブサイト他の人と同様に、Pythonコードを組み合わせてCSRを生成できました。
requires pyOpenSSL
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend())
with open('mycert.key', 'wb') as f:
f.write(key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption()))
from OpenSSL import crypto
# load private key
ftype = crypto.FILETYPE_PEM
with open('mycert.key', 'rb') as f: key = f.read()
key = crypto.load_privatekey(ftype, key)
req = crypto.X509Req()
alt_name = [ b"DNS:mynode",
b"DNS:myF5",
b"email:[email protected]" ]
key_usage = [ b"Digital Signature",
b"Key Encipherment" ]
key_usage = [ b"digitalSignature",
b"keyEncipherment" ]
ext_key_usage = [ b"serverAuth",
b"clientAuth" ]
# country (countryName, C)
# state or province name (stateOrProvinceName, ST)
# locality (locality, L)
# organization (organizationName, O)
# organizational unit (organizationalUnitName, OU)
# common name (commonName, CN)
req.get_subject().C = "US"
req.get_subject().ST = "Florida"
req.get_subject().L = "St Petersburg"
req.get_subject().O = "myCompany"
req.get_subject().OU = "MyOU"
req.get_subject().CN = "mynode"
req.add_extensions([
crypto.X509Extension( b"basicConstraints",
False,
b"CA:FALSE"),
crypto.X509Extension( b"keyUsage",
False,
b",".join(key_usage)),
crypto.X509Extension( b"subjectAltName",
False,
b",".join(alt_name))
])
req.set_pubkey(key)
req.sign(key, "sha256")
csr = crypto.dump_certificate_request(ftype, req)
with open("mycert.csr", 'wb') as f: f.write(csr)