web-dev-qa-db-ja.com

署名を作成するために、CSRのどの部分がハッシュされますか?

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のバイトをバイト単位で増やす試みが失敗したため、ここで基本的な何かが欠けているのではないかと心配しています。

5
jhscheer

質問の答えを見つけて、参照用にここに投稿します。

新しいキーペアと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
3
jhscheer

余談ですが、手動でバイナリ(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シーケンスです。

  • 本文(CSRの場合、いくつかのシーケンス)
  • 署名アルゴリズムを識別するAlgorithmIdentifier(理論的にはパラメーターを含めることができますが、含めることはできません。同じ構造がotherの場所にある場合があります);これはOID(ここではOID))とNULLのシーケンスです
  • 署名を含むビット文字列

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を実行します。

1

ハッシュ中にCSRの全体的な部分が考慮されるため、CSRのいずれかの部分を変更すると、ポップ検証が失敗します。CSRを再作成する方が適切です。

0
user45475