2013-10-23 5 views
6

के साथ एक आरएसए सार्वजनिक कुंजी का उपयोग करके डिक्रिप्ट जहां तक ​​मैं समझता हूं, मुझे प्रामाणिकता या गोपनीयता सुनिश्चित करने के लिए आरएसए का उपयोग करने में सक्षम होना चाहिए, जैसा कि मेरी इच्छा है। मेरे मामले में, मैं प्रामाणिकता सुनिश्चित करना चाहता हूं इसलिए मैं निजी कुंजी के साथ डेटा एन्क्रिप्ट करता हूं और किसी को इसे सार्वजनिक कुंजी से डिक्रिप्ट करने की अनुमति देता हूं। डेटा वास्तव में गुप्त नहीं है लेकिन मुझे यह गारंटी देने की आवश्यकता है कि यह सार्वजनिक (और निजी) कुंजी के मालिक द्वारा बनाया गया था।PyCrypto

जब मैं PyCrypto का उपयोग कर डिक्रिप्ट करने के लिए कोशिश मैं PyCrypto से कोई निजी कुंजी त्रुटि मिलती है। कोड यह है:

def _decrypt_rsa(decrypt_key_file, cipher_text): 
    from Crypto.PublicKey import RSA 
    from base64 import b64decode 

    key = open(decrypt_key_file, "r").read() 
    rsakey = RSA.importKey(key) 
    raw_cipher_data = b64decode(cipher_text) 
    decrypted = rsakey.decrypt(raw_cipher_data) 
    return decrypted 

मैं सार्वजनिक कुंजी फ़ाइल का पथ के साथ यह फोन कर रहा हूँ एन्क्रिप्टेड डाटा मुझे द्वारा उत्पन्न नहीं कर रहा है और उस पर Python लेकिन पीएचपी के साथ नहीं किया गया था (OpenSSH प्रारूप में।)। PHP में openssl_public_decrypt फ़ंक्शन है जो इस डेटा को आसानी से डिक्रिप्ट करता है।

क्या यह पिकक्रिप्टो के साथ सार्वजनिक कुंजी का उपयोग करके डिक्रिप्ट करना संभव है?

+1

आपने इसे उलट दिया है। सार्वजनिक कुंजी का उपयोग एन्क्रिप्ट करने के लिए किया जाता है और निजी कुंजी का उपयोग डिक्रिप्ट करने के लिए किया जाता है। – jchysk

+1

सार्वजनिक डिक्रिप्ट एन्क्रिप्ट के समान है। आपकी समस्या इस तरह से निर्धारित किया जा सकता है: 'decrypted = rsakey.encrypt (raw_cipher_data, 0)' – Helio

+0

स्रोत वास्तव में निजी कुंजी के साथ एन्क्रिप्टेड गया है, तो वे प्रभावी रूप से डेटा पर हस्ताक्षर किए गए हैं। जावा जैसे कुछ टूल, आपको ऐसा करने देते हैं। हस्ताक्षर को डिक्रिप्ट करने के लिए आप एक सार्वजनिक कुंजी (या एक निजी कुंजी का सार्वजनिक हिस्सा) का उपयोग कर सकते हैं। देखें: https://stackoverflow.com/questions/48280670/pycrypto-how-to-view-raw-rsa-signature-data –

उत्तर

5

यह पूरी तरह से असुरक्षित है, क्योंकि आप पैडिंग के बिना कच्चे आरएसए का उपयोग कर रहे हैं।

आपके आवेदन को हस्ताक्षर की आवश्यकता है, इसलिए आपको एन्क्रिप्शन और डिक्रिप्शन से निपटना नहीं चाहिए। उदाहरण के लिए, PKCS # 1 v1.5, एक अच्छा प्रोटोकॉल है, भले ही हस्ताक्षर डेटा का एक टुकड़ा है कि आप क्या की प्रामाणिकता साबित करने के लिए चाहते हैं के साथ जोड़ दिया जाना चाहिए।

पायथन में एक PKCS # 1 v1.5 हस्ताक्षर को सत्यापित करने के लिए, आप करते हैं:

from Crypto.PublicKey import RSA 
from Crypto.Signature import PKCS1_v1_5 
from Crypto.Hash import SHA 

rsa_key = RSA.importKey(open(verification_key_file, "rb").read()) 
verifier = PKCS1_v1_5.new(rsa_key) 
h = SHA.new(data_to_verify) 
if verifier.verify(h, signature_received_with_the_data): 
    print "OK" 
else: 
    print "Invalid" 

मैं दृढ़ता से इतना है कि यह इस तरह के एक हस्ताक्षर बनाता है PHP कोड को बदलने के लिए सिफारिश करेंगे।

+0

अपने सुझाव के लिए धन्यवाद, मुझे कोई संदेह नहीं है कि यह विचार करेंगे। क्या आप प्रामाणिकता साबित करने के लिए डेटा के गैर-गुप्त टुकड़े को डिक्रिप्ट करने के लिए सार्वजनिक कुंजी का उपयोग करने के बारे में असुरक्षित चीज़ों पर विस्तार से बता सकते हैं? क्या आप कह रहे हैं कि इसे धोखा दिया जा सकता है क्योंकि मेरे पास पैडिंग नहीं है? – sergiopereira

+0

गुप्त कुंजी के बिना एक व्यक्ति अभी भी कुछ है कि वैध संदेश असली मालिक से आने वाले की तरह दिखता है बनाने के लिए सक्षम है। यह इस तथ्य के कारण है कि आरएसए एक बदनाम एल्गोरिदम है यदि एक सिद्ध पैडिंग के साथ संयुक्त नहीं है। आप जो वर्णन करते हैं वह वास्तव में तथाकथित पूर्ण संदेश पुनर्प्राप्ति के साथ एक हस्ताक्षर है: एक उदाहरण आईएसओ 9 7 9 6-1 मानक है, जो पूरी तरह टूटा हुआ है। – SquareRootOfTwentyThree

+0

"आयात" नहीं होना चाहिए "importKey"? –

0

आपका समारोह सही है। आपकी सार्वजनिक कुंजी की बजाय डिक्रिप्ट करने के लिए आपको बस इसे अपनी निजी कुंजी का मार्ग देना होगा। सार्वजनिक कुंजी एन्क्रिप्टिंग के लिए है, निजी कुंजी डिक्रिप्टिंग के लिए है।

def _decrypt_rsa(decrypt_key_file, cipher_text): 
    ''' 
    Decrypt RSA encrypted package with private key 
    :param decrypt_key_file: Private key 
    :param cipher_text: Base64 encoded string to decrypt 
    :return: String decrypted 
    ''' 
    from Crypto.PublicKey import RSA 
    from base64 import b64decode 

    key = open(decrypt_key_file, "r").read() 
    rsakey = RSA.importKey(key) 
    #optionally could use OAEP 
    #from Crypto.Cipher import PKCS1_OAEP 
    #rsakey = PKCS1_OAEP.new(rsakey) 
    raw_cipher_data = b64decode(cipher_text) 
    decrypted = rsakey.decrypt(raw_cipher_data) 
    return decrypted 
+1

तब मैं यह गारंटी नहीं दे पाऊंगा कि संदेश किसने एन्क्रिप्ट किया था। मैं स्वीकृत उत्तर में सुझाव के बाद समाप्त हुआ और हम इसके बजाय हस्ताक्षर का उपयोग करने के लिए चले गए। इसके अलावा, मेरी समस्या ओथ टोकन से संबंधित थी और आखिरकार हम जेडब्ल्यूटी में चले गए, जो हस्ताक्षर का भी उपयोग करता है। – sergiopereira

+0

सही, आप प्रामाणिकता निर्धारित नहीं कर पाएंगे जब तक कि जिस व्यक्ति ने इसे भेजा है, वह अपनी निजी कुंजी के साथ संदेश पर हस्ताक्षर नहीं करता है और आपके पास उनकी सार्वजनिक कुंजी थी जिसे आपने अलग से सत्यापित किया था। जेडब्ल्यूटी के साथ आप अभी भी आरएस 512 जैसे एल्गोरिदम के साथ हस्ताक्षर करने के लिए आरएसए का उपयोग कर सकते हैं।यदि आप प्रेषक की प्रामाणिकता सुनिश्चित करने पर ध्यान केंद्रित कर रहे हैं तो आपको जारीकर्ता विशेषता पर ध्यान देना चाहिए। – jchysk

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