2012-06-12 21 views
12

के साथ आरएसए-SHA1 (sha1WithRSAEncryption) मान की गणना कैसे करें I RSA-SHA1 के बारे में उलझन में हूं, मैंने सोचा कि यह RSA_private_encrypt (SHA1 (संदेश)) है। लेकिन मुझे सही हस्ताक्षर मूल्य नहीं मिल रहा है। क्या कुछ गलत है?ओपनएसएसएल

उत्तर

8

हां, पीकेसीएस # 1 एन्क्रिप्शन और पीकेसीएस # 1 हस्ताक्षर different हैं। एन्क्रिप्शन केस (जिसकी आपने कोशिश की थी) में, इनपुट संदेश को एक्सपोनेंटिएटेड होने से पहले पैड किया जाता है।

PKCS # दूसरी ओर 1 signagtures पहले

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

यह तब फिर से गद्देदार है इनकोडिंग संदेश ईएम

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

जहां के रूप में फार्म की एक ASN.1 डीईआर संरचना की गणना करेगा पीएस पर्याप्त लंबाई के 0xff की एक पैडिंग स्ट्रिंग है। यदि आप इस ईएम को पुन: उत्पन्न करते हैं और RSA_private_encrypt का उपयोग करते हैं, तो आपको सही पीकेसीएस # 1 v1.5 हस्ताक्षर एन्कोडिंग मिल जाएगी, वही आपको RSA_sign या इससे भी बेहतर, सामान्य EVP_PKEY_sign का उपयोग करके मिलेगा। इस देता है -

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

dec_signedRSA_sign सार्वजनिक कुंजी के साथ फिर से decrypted का परिणाम है:

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 हैश प्रिंट बाहर इस प्रकार है:

यहाँ रूबी में एक छोटे से प्रदर्शन है हम पैडिंग को हटाकर आरएसए फ़ंक्शन में वास्तव में इनपुट वापस लेते हैं, और जैसा कि यह निकलता है, यह बिल्कुल ऊपर उल्लिखित 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/...">]> 

जैसा कि आप देख सकते हैं, DigestInfo का क्षेत्र SHA-256 हैश जैसा है जिसे हमने स्वयं गणना की है।

+0

विस्तृत उत्तर के लिए धन्यवाद। मुझे NID_sha1 (NID_sha1WithRSA गलत है) के साथ RSA_sign का उपयोग करके सही हस्ताक्षर मिला है, और मुझे लगता है कि मैं एन्कोडेड मान प्राप्त कर सकता हूं जो ओपनएसएसएल के RSA_sign फ़ंक्शन को संशोधित करके RSA_private_encrypt का इनपुट है। पुनः आपका बहुत - बहुत धन्यवाद! –

+0

क्षमा करें, एक और सवाल, मैं ओपनएसएसएल के साथ ईएम कैसे प्राप्त कर सकता हूं?मैंने RSA_sign() का पता लगाया और पाया i = RSA_private_encrypt (i, s, sigret, rsa, RSA_PKCS1_PADDING); जो एक फंक्शन rsa_priv_enc की ओर जाता है जो मुझे कहीं और नहीं मिल सकता है। धन्यवाद –

+1

और, RSA_PKCS1_PADDING क्या करता है? –

3

मुझे लगता है कि आप गलत ओपनएसएसएल अमूर्त स्तर पर काम कर रहे हैं; आपको शायद rsa.h - घोषित फ़ंक्शन RSA_sign() और RSA_verify() का उपयोग करना चाहिए, जिसका उपयोग PKCS#1 -compliant हस्ताक्षर पर किया जाना था।

+0

उत्तर देने के लिए धन्यवाद। मुझे अभी भी समझ में नहीं आता है कि RSA_sign() क्या हैश और आरएसए एन्क्रिप्शन कार्यों की अपेक्षा करता है? क्या इन दोनों को पर्याप्त नहीं होना चाहिए? –

+0

यह पीकेसीएस # 1 पैडिंग और एएसएन .1 एन्कोडिंग को भी संभालता है; यदि आप पैडिंग के बिना सामग्री पर हस्ताक्षर कर रहे हैं तो यह आरएसए में कमजोरियों का कारण बन सकता है, और एन्कोडिंग विश्वसनीय रूप से अन्य कार्यक्रमों के साथ अंतःक्रिया करना है। – sarnold

+0

मैंने RSA_sign (NID_SHA1, ...) का उपयोग किया, लेकिन परिणाम xmlsec (xml हस्ताक्षर API) के साथ मिला है। मुझे आश्चर्य है कि क्या RSA_sign (NID_SHA1, ...) RSASSA-PKCS1-v1_5 कर रहा है? –

संबंधित मुद्दे