CSR作成プロセスを再度実行せずに、CAに転送される前にCSRを変更したいと思います。そのためには、CSRを変更した後、CSRの署名を計算する方法を知る必要があります。残念ながら、ハッシュされたCSRのバイト数を正確に知ることができませんでした。
私はこのようにCSRを作成しました:
openssl req -out certrequest.csr -new -newkey rsa:2048 -nodes -keyout private.key
後
sed -e '1d' -e '$d' certrequest.csr | openssl enc -base64 -d > certrequest-stripped
certrequest-strippedの最後の256バイト(sha256WithRSAEncryption)は、signature1です。秘密鍵を使用してハッシュに署名するために、certrequest-strippedの最初のバイトのうち、ハッシュがいくつあるかを知りたいのですが。
つまり、次のコマンドで「?」の値を探して、両方の署名(signature1とsignature2)が一致するようにします:
head -c <?> certrequest-stripped | openssl dgst -sha256 > hash
openssl rsautl -sign -inkey private.key -keyform PEM -in hash > signature2
カットは指数のASN1フィールドの後ろのどこかにある必要があることはわかっていますが、CSRのバイトをバイト単位で増やす試みが失敗したため、ここで基本的な何かが欠けているのではないかと心配しています。
質問の答えを見つけて、参照用にここに投稿します。
新しいキーペアとCSRを生成
openssl req -out csr.der -new -newkey rsa:2048 -nodes -keyout privateKey.der -outform DER
csr.derをmodified_csr.derに変更します
署名用にハッシュされたCSRのシーケンス(オフセット4で始まる)を抽出します
openssl asn1parse -in modified_csr.der -inform der -strparse 4 -out part_of_CSR_thats_hashed
新しい署名を作成
openssl dgst -sha256 -sign privateKey.der -out new_signature part_of_CSR_thats_hashed
modified_csr.derとnew_signatureをnew_csr.derにマージ
head -c $(( $(stat -c '%s' modified_csr.der) - 256 )) modified_csr.der > new_csr.der
cat new_signature >> new_csr.der
新しいCSRを確認
openssl req -in new_csr.der -inform DER -noout -text -verify
CSRをPEMに変換
openssl req -outform PEM -inform DER -in new_csr.der -out new_csr.pem
余談ですが、手動でバイナリ(DER)に変換する必要はありません、openssl req -in req.pem -out req.der -outform der
が代行します。または、-outform der
最初の作成時。また、256バイトの署名サイズは、署名アルゴリズムでのSHA256の使用に何らかの関係があると示唆していますが、これは事実ではありません。また、本文はDERである必要があるため、本文の長さを変更する場合は、影響を受けるすべてのASN.1長さフィールドを変更する必要があることを理解していると思います。
密接に関連したX.509 SIGNED-macroオブジェクト(certおよびCRL)のようなCSRは、次のASN.1シーケンスです。
openssl asn1parse -in req.der -inform der
は、各パーツのオフセット、ヘッダー長、および本体長を含むデコードを示します。追加-i
は構造をより明確にします(レベルに基づいてデータをインデントします)。公開鍵は、CSR組織の最後のものではないことに注意してください。また、CSR形式はRSA以外のキータイプを処理できます。その場合、「指数」はありません。
ただし、ハッシュしてからrsautl -sign
は正しいPKCS#1署名を提供しません。必要に応じてダイジェストAlgIdをエンコードしません。 rsa暗号化ハッシュ== rsa署名 を参照してください。あなたはそれを手動で行うことができます(OpenSSL FIPSモジュールは、コストのかかる検証の対象となるコードを節約するために行います)または
openssl dgst -sha256 -sign rsaprivatekey.pem -in actual_data_not_hash -out sigvalue
編集:または私が覚えている別のオプション。 1.0.0以降:
openssl pkeyutl -sign -inkey rsapriv -pkeyopt digest:sha256 -in hashval -out sigval
ハッシュを実行できますが、ASN.1エンコード(実際のハッシュに使用したのと同じハッシュをエンコードするように指定してください)、パディング、およびmodexpを実行します。
ハッシュ中にCSRの全体的な部分が考慮されるため、CSRのいずれかの部分を変更すると、ポップ検証が失敗します。CSRを再作成する方が適切です。