2012-06-12 14 views

答えて

8

はい、PKCS#1暗号化とPKCS#1署名はdifferentです。暗号化の場合(試したもの)、入力メッセージは単に累乗される前に埋められます。再び埋め込まれこれは符号化されたメッセージEM

EM = 0x00 || 0x01 || PS || 0x00 || T 

形成する

DigestInfo ::= SEQUENCE { 
    digestAlgorithm AlgorithmIdentifier, 
    digest OCTET STRING 
} 

のPKCS#一方、1 signagturesは、最初の形式のASN.1のDER構造を計算しますPSは十分な長さの0xffのパディングストリングです。このEMを再現してRSA_private_encryptを使用すると、適切なPKCS#1 v1.5シグネチャエンコーディングが得られます。これは、RSA_signと同じ、またはより一般的なEVP_PKEY_signを使用した場合と同じです。次のように

require 'openssl' 
require 'pp' 

data = "test" 
digest = OpenSSL::Digest::SHA256.new 
hash = digest.digest("test") 
key = OpenSSL::PKey::RSA.generate 512 

signed = key.sign(digest, data) 
dec_signed = key.public_decrypt(signed) 

p hash 
pp OpenSSL::ASN1.decode dec_signed 

SHA-256ハッシュプリントアウト: - これは、与え

"\x9F\x86\xD0\x81\x88L}e\x9A/..." 

dec_signedは、公開鍵で再び暗号化解除RSA_signの結果であり、ここで

はRubyで少しのデモンストレーションですパディングが取り除かれたRSA関数への入力を正確に返します。これはまさに前述のDigestInfo構造です:

#<OpenSSL::ASN1::Sequence:0x007f60dc36b250 
@infinite_length=false, 
@tag=16, 
@tag_class=:UNIVERSAL, 
@tagging=nil, 
@value= 
    [#<OpenSSL::ASN1::Sequence:0x007f60dc36b318 
    @infinite_length=false, 
    @tag=16, 
    @tag_class=:UNIVERSAL, 
    @tagging=nil, 
    @value= 
    [#<OpenSSL::ASN1::ObjectId:0x007f60dc36b390 
     @infinite_length=false, 
     @tag=6, 
     @tag_class=:UNIVERSAL, 
     @tagging=nil, 
     @value="SHA256">, 
     #<OpenSSL::ASN1::Null:0x007f60dc36b340 
     @infinite_length=false, 
     @tag=5, 
     @tag_class=:UNIVERSAL, 
     @tagging=nil, 
     @value=nil>]>, 
    #<OpenSSL::ASN1::OctetString:0x007f60dc36b2a0 
    @infinite_length=false, 
    @tag=4, 
    @tag_class=:UNIVERSAL, 
    @tagging=nil, 
    @value="\x9F\x86\xD0\x81\x88L}e\x9A/...">]> 

ご覧のとおり、digestフィールドの値はDigestInfoです。私たちが計算したSHA-256ハッシュと同じです。

+0

詳細な回答ありがとうございます。私はNID_sha1(NID_sha1WithRSAは間違ったもの)でRSA_signを使って正しい署名を得ています。そして、私はOpenSSLのRSA_sign関数を変更してRSA_private_encryptの入力である符号化された値を得ることができると思います。再度ありがとう! –

+0

申し訳ありませんが、別の質問、私はOpenSSLでEMを手に入れることができますか?私はRSA_sign()をトレースして見つけました。 i = RSA_private_encrypt(i、s、sigret、rsa、RSA_PKCS1_PADDING); これは、他にどこにも見つからない関数rsa_priv_encにつながります。ありがとうございます –

+1

そして、ここでRSA_PKCS1_PADDINGは何をしますか? –

3

あなたは間違ったOpenSSL抽象化レベルで作業していると思います。おそらくrsa.h - 宣言された関数​​とRSA_verify()を使用していて、これはPKCS#1準拠の署名で使用することを想定しているはずです。

+0

ありがとうございます。私はまだ、RSA_sign()がハッシュとRSA暗号化機能を期待していることは何かを理解していませんか?これらの2つで十分ではありませんか? –

+0

また、PKCS#1パディングとASN.1エンコードを処理します。パディングなしでコンテンツに署名するだけであれば、RSAの弱点につながり、エンコーディングは他のプログラムと確実に相互運用できます。 – sarnold

+0

私はRSA_sign(NID_SHA1、...)を使用しましたが、結果はxmlsec(xml signature API)の場合と同じではありません。私はRSA_sign(NID_SHA1、...)がRSASSA-PKCS1-v1_5をやっているのだろうか? –

関連する問題