PyCrypto AES 256 का उपयोग करके एन्क्रिप्ट और डिक्रिप्ट करें


171

मैं PyCrypto का उपयोग करके दो कार्यों का निर्माण करने की कोशिश कर रहा हूं जो दो मापदंडों को स्वीकार करते हैं: संदेश और कुंजी, और फिर संदेश को एन्क्रिप्ट / डिक्रिप्ट करें।

मुझे मेरी मदद करने के लिए वेब पर कई लिंक मिले, लेकिन उनमें से प्रत्येक में दोष हैं:

कोडकोला में यह एक os.urandom का उपयोग करता है, जिसे PyCrypto द्वारा हतोत्साहित किया जाता है।

इसके अलावा, मैं फ़ंक्शन को जो कुंजी देता हूं, उसकी सटीक लंबाई की उम्मीद करने की गारंटी नहीं है। मैं ऐसा करने के लिए क्या कर सकता हूं?

इसके अलावा, कई मोड हैं, जो एक की सिफारिश की है? मुझे नहीं पता कि क्या उपयोग करना है: /

अंत में, वास्तव में IV क्या है? क्या मैं एन्क्रिप्ट और डिक्रिप्टिंग के लिए एक अलग IV प्रदान कर सकता हूं, या क्या यह एक अलग परिणाम में लौटेगा?

संपादित करें : यह सुरक्षित नहीं था, क्योंकि कोड हिस्सा निकाल दिया।


12
os.urandom को PyCrypto वेबसाइट पर प्रोत्साहित किया गया है। यह Microsoft के CryptGenRandom फ़ंक्शन का उपयोग करता है जो एक CSPRNG है
जोएल वरूम

5
या /dev/urandomयूनिक्स पर
जोएल वरूम

2
बस स्पष्ट करने के लिए, इस उदाहरण में पदबंध है कुंजी जो 128, 192, या 256 बिट्स (16, 24, या 32 बाइट्स) हो सकता है
मार्क

4
यह उल्लेखनीय है कि PyCrypto एक मृत परियोजना है । अंतिम प्रतिबद्धता 2014 से है। PyCryptodome प्रतिस्थापन में एक अच्छी बूंद की तरह दिखता है
Overdrivr

1
यह प्रश्न पुराना है, लेकिन मैं (2020 तक) इंगित करना चाहूंगा कि pycrypto पुराने होने की संभावना है और अब समर्थित नहीं है। उनके github पृष्ठ ( github.com/pycrypto/pycrypto ) को देखते हुए, यह प्रतीत होता है कि 2014 में उनकी अंतिम प्रतिबद्धता थी। मैं क्रिप्टोग्राफ़िक सॉफ़्टवेयर का उपयोग करने का अधिकार प्राप्त करूंगा जो अब विकास के अधीन नहीं है
चिड़चिड़ा_phd_syryptrom

जवाबों:


151

यहाँ मेरा कार्यान्वयन है और कुछ सुधारों के साथ मेरे लिए काम करता है और 32 बाइट्स और iv से 16 बाइट्स के साथ कुंजी और गुप्त वाक्यांश के संरेखण को बढ़ाता है:

import base64
import hashlib
from Crypto import Random
from Crypto.Cipher import AES

class AESCipher(object):

    def __init__(self, key): 
        self.bs = AES.block_size
        self.key = hashlib.sha256(key.encode()).digest()

    def encrypt(self, raw):
        raw = self._pad(raw)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return base64.b64encode(iv + cipher.encrypt(raw.encode()))

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        iv = enc[:AES.block_size]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return self._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')

    def _pad(self, s):
        return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)

    @staticmethod
    def _unpad(s):
        return s[:-ord(s[len(s)-1:])]

14
मुझे पता है कि यह कुछ समय के लिए है, लेकिन मुझे लगता है कि यह प्रतिक्रिया कुछ भ्रम फैला सकती है। यह फ़ंक्शन इनपुट डेटा को पैड करने के लिए 32 बाइट (256 बाइट) के एक block_size का उपयोग करता है लेकिन AES 128 बिट ब्लॉक आकार का उपयोग करता है। AES256 में कुंजी 256 बिट है, लेकिन ब्लॉक आकार में नहीं।
तानिन

13
इसे दूसरे तरीके से रखने के लिए, "self.bs" को हटा दिया जाना चाहिए और इसे "AES.block_size" द्वारा बदल दिया जाएगा
एलेक्सिस

2
आप हैश की चाबी क्यों ले रहे हैं? यदि आप उम्मीद कर रहे हैं कि यह पासवर्ड जैसा कुछ है, तो आपको SHA256 का उपयोग नहीं करना चाहिए; PBKDF2, जो PyCrypto प्रदान करता है, की तरह एक प्रमुख व्युत्पत्ति फ़ंक्शन का उपयोग करना बेहतर है।
बीस

5
@ क्रिस - SHA256 एक 32-बाइट हैश - AES256 के लिए एक सही आकार की कुंजी देता है। कुंजी की जनरेशन / व्युत्पत्ति को यादृच्छिक / सुरक्षित माना जाता है और एन्क्रिप्शन / डिक्रिप्शन कोड के दायरे से बाहर होना चाहिए - हैशिंग केवल एक गारंटी है कि कुंजी चयनित सिफर के साथ प्रयोग करने योग्य है।
zwer

2
में _pad self.bs का उपयोग आवश्यक है और _unpad में जरूरत नहीं है
mnothic

149

आपको निम्न दो कार्यों की आवश्यकता हो सकती है: pad- पैड से (जब एन्क्रिप्शन कर रहे हैं) और unpad- से अनपैड (जब डिक्रिप्शन कर रहे हैं) जब इनपुट की लंबाई BLOCK_SIZE से अधिक नहीं हो।

BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS) 
unpad = lambda s : s[:-ord(s[len(s)-1:])]

तो आप कुंजी की लंबाई पूछ रहे हैं? आप सीधे उपयोग के बजाय कुंजी के md5sum का उपयोग कर सकते हैं।

अधिक, PyCrypto का उपयोग करने के मेरे छोटे अनुभव के अनुसार, IV का उपयोग इनपुट के समान होने पर एन्क्रिप्शन के आउटपुट को मिलाने के लिए किया जाता है, इसलिए IV को एक यादृच्छिक स्ट्रिंग के रूप में चुना जाता है, और इसे एन्क्रिप्शन आउटपुट के भाग के रूप में उपयोग किया जाता है, और फिर संदेश को डिक्रिप्ट करने के लिए इसका उपयोग करें।

और यहाँ मेरा कार्यान्वयन है, आशा है कि यह आपके लिए उपयोगी होगा:

import base64
from Crypto.Cipher import AES
from Crypto import Random

class AESCipher:
    def __init__( self, key ):
        self.key = key

    def encrypt( self, raw ):
        raw = pad(raw)
        iv = Random.new().read( AES.block_size )
        cipher = AES.new( self.key, AES.MODE_CBC, iv )
        return base64.b64encode( iv + cipher.encrypt( raw ) ) 

    def decrypt( self, enc ):
        enc = base64.b64decode(enc)
        iv = enc[:16]
        cipher = AES.new(self.key, AES.MODE_CBC, iv )
        return unpad(cipher.decrypt( enc[16:] ))

1
यदि आपके पास एक इनपुट है जो बिलकुल BLOCK_SIZE के एक से अधिक है, तो क्या होता है? मुझे लगता है कि अनपेड फ़ंक्शन थोड़ा भ्रमित हो जाएगा ...
काजिर

2
@Kjir, तो लंबाई BLOCK_SIZE में मूल्य chr (BS) का एक अनुक्रम मूल डेटा में जोड़ा जाएगा।
मार्कस

1
@Marcus padफ़ंक्शन टूट गया है (कम से कम Py3 में), s[:-ord(s[len(s)-1:])]इसके लिए इसे संस्करणों में काम करने के लिए बदलें ।
11

2
@Torxed पैड फ़ंक्शन CryptoUtil.Padding.pad () में pycryptodome (pycrypto followup) के साथ उपलब्ध है
comte

2
क्यों न सिर्फ एक चरित्र स्थिर है जैसे पैडिंग चार?
इनामाथी

16

मुझे आपके प्रश्नों को "मोड" के बारे में बताएं। AES256 एक प्रकार का ब्लॉक सिफर है । यह एक 32-बाइट कुंजी और 16-बाइट स्ट्रिंग के रूप में इनपुट लेता है , जिसे ब्लॉक कहा जाता है और ब्लॉक को आउटपुट करता है। एन्क्रिप्ट करने के लिए हम एईएस का उपयोग एक मोड में करते हैं । उपरोक्त समाधान सीबीसी का उपयोग करने का सुझाव देते हैं, जो एक उदाहरण है। दूसरे को सीटीआर कहा जाता है, और इसका उपयोग करना कुछ आसान है:

from Crypto.Cipher import AES
from Crypto.Util import Counter
from Crypto import Random

# AES supports multiple key sizes: 16 (AES128), 24 (AES192), or 32 (AES256).
key_bytes = 32

# Takes as input a 32-byte key and an arbitrary-length plaintext and returns a
# pair (iv, ciphtertext). "iv" stands for initialization vector.
def encrypt(key, plaintext):
    assert len(key) == key_bytes

    # Choose a random, 16-byte IV.
    iv = Random.new().read(AES.block_size)

    # Convert the IV to a Python integer.
    iv_int = int(binascii.hexlify(iv), 16) 

    # Create a new Counter object with IV = iv_int.
    ctr = Counter.new(AES.block_size * 8, initial_value=iv_int)

    # Create AES-CTR cipher.
    aes = AES.new(key, AES.MODE_CTR, counter=ctr)

    # Encrypt and return IV and ciphertext.
    ciphertext = aes.encrypt(plaintext)
    return (iv, ciphertext)

# Takes as input a 32-byte key, a 16-byte IV, and a ciphertext, and outputs the
# corresponding plaintext.
def decrypt(key, iv, ciphertext):
    assert len(key) == key_bytes

    # Initialize counter for decryption. iv should be the same as the output of
    # encrypt().
    iv_int = int(iv.encode('hex'), 16) 
    ctr = Counter.new(AES.block_size * 8, initial_value=iv_int)

    # Create AES-CTR cipher.
    aes = AES.new(key, AES.MODE_CTR, counter=ctr)

    # Decrypt and return the plaintext.
    plaintext = aes.decrypt(ciphertext)
    return plaintext

(iv, ciphertext) = encrypt(key, 'hella')
print decrypt(key, iv, ciphertext)

इसे अक्सर एईएस-सीटीआर के रूप में जाना जाता है। मैं PyCrypto के साथ AES-CBC का उपयोग करने में सावधानी बरतने की सलाह दूंगा । कारण यह है कि आपको पेडिंग स्कीम को निर्दिष्ट करने की आवश्यकता है , जैसा कि अन्य समाधानों के अनुसार दिया गया है। सामान्य तौर पर, यदि आप पैडिंग के बारे में बहुत सावधान नहीं हैं , तो ऐसे हमले हैं जो एन्क्रिप्शन को पूरी तरह से तोड़ देते हैं!

अब, यह नोट करना महत्वपूर्ण है कि कुंजी एक यादृच्छिक, 32-बाइट स्ट्रिंग होनी चाहिए ; एक पासवर्ड पर्याप्त नहीं है। आम तौर पर, कुंजी इस तरह उत्पन्न होती है:

# Nominal way to generate a fresh key. This calls the system's random number
# generator (RNG).
key1 = Random.new().read(key_bytes)

एक कुंजी पासवर्ड से भी निकाली जा सकती है :

# It's also possible to derive a key from a password, but it's important that
# the password have high entropy, meaning difficult to predict.
password = "This is a rather weak password."

# For added # security, we add a "salt", which increases the entropy.
#
# In this example, we use the same RNG to produce the salt that we used to
# produce key1.
salt_bytes = 8 
salt = Random.new().read(salt_bytes)

# Stands for "Password-based key derivation function 2"
key2 = PBKDF2(password, salt, key_bytes)

ऊपर दिए गए कुछ समाधान SHA256 को कुंजी को प्राप्त करने के लिए उपयोग करने का सुझाव देते हैं, लेकिन इसे आमतौर पर बुरा क्रिप्टोग्राफिक अभ्यास माना जाता है । ऑपरेशन के तरीकों पर अधिक जानकारी के लिए विकिपीडिया देखें ।


iv_int = int (binascii.hexlify (iv), 16) काम नहीं करता है, इसे iv_int = int (binascii.hexlify (iv), 16) के साथ बदलें और इसके अलावा 'आयात बिन्यासी' और इसे काम करना चाहिए (पायथन 3.x पर) ), अन्यथा महान काम!
वलमंड

ध्यान दें कि Autehnticated एन्क्रिप्शन मोड का उपयोग AES-GCM के रूप में करना बेहतर है। GCM आंतरिक रूप से CTR मोड का उपयोग करता है।
केलालाक

इस कोड के कारण "TypeError: Object type <class 'str'> C कोड को पास नहीं किया जा सकता"
Da Woon Jung

7

किसी ऐसे व्यक्ति के लिए जो urlsafe_b64encode और urlsafe_b64decode का उपयोग करना चाहता है, यहाँ वो संस्करण हैं जो मेरे लिए काम कर रहे हैं (यूनिकोड समस्या के साथ कुछ समय बिताने के बाद)

BS = 16
key = hashlib.md5(settings.SECRET_KEY).hexdigest()[:BS]
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s : s[:-ord(s[len(s)-1:])]

class AESCipher:
    def __init__(self, key):
        self.key = key

    def encrypt(self, raw):
        raw = pad(raw)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return base64.urlsafe_b64encode(iv + cipher.encrypt(raw)) 

    def decrypt(self, enc):
        enc = base64.urlsafe_b64decode(enc.encode('utf-8'))
        iv = enc[:BS]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return unpad(cipher.decrypt(enc[BS:]))

6

आप SHA-1 या SHA-256 जैसे क्रिप्टोग्राफ़िक हैश फ़ंक्शन ( नहीं पायथन के बिल्डिन hash) का उपयोग करके एक मनमाना पासवर्ड से पासफ़्रेज़ प्राप्त कर सकते हैं । पायथन में अपने मानक पुस्तकालय में दोनों के लिए समर्थन शामिल है:

import hashlib

hashlib.sha1("this is my awesome password").digest() # => a 20 byte string
hashlib.sha256("another awesome password").digest() # => a 32 byte string

आप एक क्रिप्टोग्राफ़िक हैश मान को केवल उपयोग करके छोटा कर सकते हैं [:16]या [:24]यह आपकी सुरक्षा को आपके द्वारा निर्दिष्ट लंबाई तक बनाए रखेगा।


13
पासवर्ड से कुंजी बनाने के लिए आपको SHA-family हैश फ़ंक्शन का उपयोग नहीं करना चाहिए - इस विषय पर कोडा हेल का निबंध देखें । इसके बजाय scrypt जैसे वास्तविक कुंजी व्युत्पत्ति फ़ंक्शन का उपयोग करने पर विचार करें । (कोडा हेल के निबंध को स्क्रीप्ट के प्रकाशन से पहले लिखा गया था।)
बेंजामिन बेरेनब्लैट

7
भविष्य के पाठकों के लिए, यदि आप पासफ़्रेज़ से कोई कुंजी प्राप्त करना चाहते हैं, तो PBKDF2 देखें। अजगर ( pypi.python.org/pypi/pbkdf2 ) में इसका उपयोग करना काफी आसान है । यदि आप हैश पासवर्ड देख रहे हैं, हालाँकि, bcrypt एक बेहतर विकल्प है।
सी फेयरवेदर

6

अन्य जवाबों के लिए आभारी जो प्रेरित हुए लेकिन मेरे लिए काम नहीं किया।

यह कैसे काम करता है यह जानने की कोशिश करने में घंटों बिताने के बाद, मैं नीचे दिए गए कार्यान्वयन के साथ नवीनतम PyCryptodomex पुस्तकालय के साथ आया (यह एक और कहानी है कि कैसे मैं इसे प्रॉक्सी के पीछे स्थापित करने में कामयाब रहा, विंडोज पर, एक virtualenv में .. पृष्ठ

पर काम करना ) आपका क्रियान्वयन, पैडिंग, एन्कोडिंग, एन्क्रिप्टिंग स्टेप्स (और इसके विपरीत) लिखना न भूलें। आपको ऑर्डर को ध्यान में रखते हुए पैक और अनपैक करना होगा।

आयात base64
आयात हैशलीब
Cryptodome.Cipher आयात AES से
क्रिप्टोडोम से। रैंडम आयात get_random_bytes

__key__ = hashlib.sha256 (b'16-character key ')। पाचन ()

डीईएफ़ एनक्रिप्ट (कच्चा):
    BS = AES.block_size
    पैड = लैम्ब्डा s: s + (बीएस - लेन (एस)% बीएस) * chr (बीएस - लेन (एस)% बीएस)

    कच्ची = आधार ६४.६६०कोड (पैड (कच्ची)। केनकोड ('utf8'))
    iv = get_random_bytes (AES.block_size)
    सिफर = AES.new (कुंजी = __key__, मोड = AES.MODE_CFB, iv = iv)
    वापसी base64.b64encode (iv + cipher.encrypt (कच्चा))

डीक्रिप्ट (डीईसी):
    अनपेड = लंबोदर s: s [: - ord (s [-1:])]

    enc = base64.b64decode (एनको)
    iv = enc [: AES.block_size]
    सिफर = AES.new (__ key__, AES.MODE_CFB, iv)
    वापसी unpad (base64.b64decode (सिफर .ecrypt (एन्क [AES.block_size)]))। डीकोड ('utf8')।

PyCryptodomeX libs के साथ इसके कामकाज के उदाहरण के लिए धन्यवाद। यह काफी मददगार है!
यक्रमुल

5

दूसरों के लाभ के लिए, यहाँ मेरा डिक्रिप्शन कार्यान्वयन है जो मुझे @Cyril और @Marcus के उत्तरों को मिलाकर मिला है। यह मानता है कि यह एन्क्रिप्टेडटेक्स्ट के साथ HTTP रिक्वेस्ट और बेस 64 एनकोडेड के माध्यम से आ रहा है।

import base64
import urllib2
from Crypto.Cipher import AES


def decrypt(quotedEncodedEncrypted):
    key = 'SecretKey'

    encodedEncrypted = urllib2.unquote(quotedEncodedEncrypted)

    cipher = AES.new(key)
    decrypted = cipher.decrypt(base64.b64decode(encodedEncrypted))[:16]

    for i in range(1, len(base64.b64decode(encodedEncrypted))/16):
        cipher = AES.new(key, AES.MODE_CBC, base64.b64decode(encodedEncrypted)[(i-1)*16:i*16])
        decrypted += cipher.decrypt(base64.b64decode(encodedEncrypted)[i*16:])[:16]

    return decrypted.strip()

5

एक और इस पर (भारी समाधान ऊपर से प्राप्त होता है) लेकिन

  • गद्दी के लिए अशक्त का उपयोग करता है
  • लैम्ब्डा का उपयोग नहीं करता (कभी प्रशंसक नहीं रहा)
  • अजगर 2.7 और 3.6.5 के साथ परीक्षण किया गया

    #!/usr/bin/python2.7
    # you'll have to adjust for your setup, e.g., #!/usr/bin/python3
    
    
    import base64, re
    from Crypto.Cipher import AES
    from Crypto import Random
    from django.conf import settings
    
    class AESCipher:
        """
          Usage:
          aes = AESCipher( settings.SECRET_KEY[:16], 32)
          encryp_msg = aes.encrypt( 'ppppppppppppppppppppppppppppppppppppppppppppppppppppppp' )
          msg = aes.decrypt( encryp_msg )
          print("'{}'".format(msg))
        """
        def __init__(self, key, blk_sz):
            self.key = key
            self.blk_sz = blk_sz
    
        def encrypt( self, raw ):
            if raw is None or len(raw) == 0:
                raise NameError("No value given to encrypt")
            raw = raw + '\0' * (self.blk_sz - len(raw) % self.blk_sz)
            raw = raw.encode('utf-8')
            iv = Random.new().read( AES.block_size )
            cipher = AES.new( self.key.encode('utf-8'), AES.MODE_CBC, iv )
            return base64.b64encode( iv + cipher.encrypt( raw ) ).decode('utf-8')
    
        def decrypt( self, enc ):
            if enc is None or len(enc) == 0:
                raise NameError("No value given to decrypt")
            enc = base64.b64decode(enc)
            iv = enc[:16]
            cipher = AES.new(self.key.encode('utf-8'), AES.MODE_CBC, iv )
            return re.sub(b'\x00*$', b'', cipher.decrypt( enc[16:])).decode('utf-8')

यह काम नहीं करेगा यदि इनपुट बाइट [] में अशक्त नलिका है क्योंकि डिक्रिप्ट () फ़ंक्शन में आप अपने गद्दी नल को खाएंगे।
बज़ मोर्चेटी

हां, जैसा कि मैं ऊपर बताता हूं, यह तर्क नल के साथ पैड करता है। यदि आप जिन वस्तुओं को एनकोड / डिकोड करना चाहते हैं, उनमें पीछे की ओर
खिसकने

3

मैंने दोनों Cryptoऔर PyCryptodomexपुस्तकालय का उपयोग किया है और यह तेजी से धधक रहा है ...

import base64
import hashlib
from Cryptodome.Cipher import AES as domeAES
from Cryptodome.Random import get_random_bytes
from Crypto import Random
from Crypto.Cipher import AES as cryptoAES

BLOCK_SIZE = AES.block_size

key = "my_secret_key".encode()
__key__ = hashlib.sha256(key).digest()
print(__key__)

def encrypt(raw):
    BS = cryptoAES.block_size
    pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
    raw = base64.b64encode(pad(raw).encode('utf8'))
    iv = get_random_bytes(cryptoAES.block_size)
    cipher = cryptoAES.new(key= __key__, mode= cryptoAES.MODE_CFB,iv= iv)
    a= base64.b64encode(iv + cipher.encrypt(raw))
    IV = Random.new().read(BLOCK_SIZE)
    aes = domeAES.new(__key__, domeAES.MODE_CFB, IV)
    b = base64.b64encode(IV + aes.encrypt(a))
    return b

def decrypt(enc):
    passphrase = __key__
    encrypted = base64.b64decode(enc)
    IV = encrypted[:BLOCK_SIZE]
    aes = domeAES.new(passphrase, domeAES.MODE_CFB, IV)
    enc = aes.decrypt(encrypted[BLOCK_SIZE:])
    unpad = lambda s: s[:-ord(s[-1:])]
    enc = base64.b64decode(enc)
    iv = enc[:cryptoAES.block_size]
    cipher = cryptoAES.new(__key__, cryptoAES.MODE_CFB, iv)
    b=  unpad(base64.b64decode(cipher.decrypt(enc[cryptoAES.block_size:])).decode('utf8'))
    return b

encrypted_data =encrypt("Hi Steven!!!!!")
print(encrypted_data)
print("=======")
decrypted_data = decrypt(encrypted_data)
print(decrypted_data)

2

थोड़ी देर हो गई है लेकिन मुझे लगता है कि यह बहुत मददगार होगा। PKCS # 7 पैडिंग जैसी उपयोग योजना के बारे में किसी ने उल्लेख नहीं किया है। आप पिछले कार्यों के बजाय इसका उपयोग पैड (जब एन्क्रिप्शन करते हैं) और अनपैड (जब डिक्रिप्शन करते हैं) कर सकते हैं। मैं नीचे पूर्ण सेवा प्रदान करेगा।

import base64
import hashlib
from Crypto import Random
from Crypto.Cipher import AES
import pkcs7
class Encryption:

    def __init__(self):
        pass

    def Encrypt(self, PlainText, SecurePassword):
        pw_encode = SecurePassword.encode('utf-8')
        text_encode = PlainText.encode('utf-8')

        key = hashlib.sha256(pw_encode).digest()
        iv = Random.new().read(AES.block_size)

        cipher = AES.new(key, AES.MODE_CBC, iv)
        pad_text = pkcs7.encode(text_encode)
        msg = iv + cipher.encrypt(pad_text)

        EncodeMsg = base64.b64encode(msg)
        return EncodeMsg

    def Decrypt(self, Encrypted, SecurePassword):
        decodbase64 = base64.b64decode(Encrypted.decode("utf-8"))
        pw_encode = SecurePassword.decode('utf-8')

        iv = decodbase64[:AES.block_size]
        key = hashlib.sha256(pw_encode).digest()

        cipher = AES.new(key, AES.MODE_CBC, iv)
        msg = cipher.decrypt(decodbase64[AES.block_size:])
        pad_text = pkcs7.decode(msg)

        decryptedString = pad_text.decode('utf-8')
        return decryptedString

import StringIO
import binascii


def decode(text, k=16):
    nl = len(text)
    val = int(binascii.hexlify(text[-1]), 16)
    if val > k:
        raise ValueError('Input is not padded or padding is corrupt')

    l = nl - val
    return text[:l]


def encode(text, k=16):
    l = len(text)
    output = StringIO.StringIO()
    val = k - (l % k)
    for _ in xrange(val):
        output.write('%02x' % val)
    return text + binascii.unhexlify(output.getvalue())


मुझे नहीं पता कि किसने उत्तर को अस्वीकार कर दिया है लेकिन मैं यह जानने के लिए उत्सुक हूं कि क्यों। शायद यह तरीका सुरक्षित नहीं है? एक स्पष्टीकरण बहुत अच्छा होगा।
सिरिल एन।

1
@CyrilN। यह उत्तर बताता है कि SHA-256 के एकल आह्वान के साथ पासवर्ड हैशिंग पर्याप्त है। यह नहीं है। आपको वास्तव में PBKDF2 या एक बड़े पुनरावृत्ति गणना का उपयोग करके पासवर्ड से कुंजी व्युत्पत्ति के लिए समान उपयोग करना चाहिए।
आर्टजोम बी

विस्तार के लिए धन्यवाद @ArtjomB!
सिरिल एन।

मेरे पास एक कुंजी है और 44 लंबाई के साथ iv कुंजी भी है। मैं आपके कार्यों का उपयोग कैसे कर सकता हूं? इंटरनेट के सभी एल्गोरिदम जो मुझे मिले, मेरी वेक्टर कुंजी की लंबाई के साथ समस्या है
mahshid.r।


1
from Crypto import Random
from Crypto.Cipher import AES
import base64

BLOCK_SIZE=16
def trans(key):
     return md5.new(key).digest()

def encrypt(message, passphrase):
    passphrase = trans(passphrase)
    IV = Random.new().read(BLOCK_SIZE)
    aes = AES.new(passphrase, AES.MODE_CFB, IV)
    return base64.b64encode(IV + aes.encrypt(message))

def decrypt(encrypted, passphrase):
    passphrase = trans(passphrase)
    encrypted = base64.b64decode(encrypted)
    IV = encrypted[:BLOCK_SIZE]
    aes = AES.new(passphrase, AES.MODE_CFB, IV)
    return aes.decrypt(encrypted[BLOCK_SIZE:])

10
कृपया न केवल कोड प्रदान करें, बल्कि यह भी बताएं कि आप क्या कर रहे हैं और यह क्यों बेहतर है / मौजूदा उत्तरों में क्या अंतर है।
फ्लोरियन कोच

Md5.new (कुंजी) .digest () को md5 (कुंजी) .digest () द्वारा प्रतिस्थापित करें, और यह एक आकर्षण की तरह काम करता है!
एक STEFANI
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.