[pycrypto] [PATCH] PEM: Decode AES-192-CBC and AES-256-CBC keys

Alexander Graf mail at agraf.me
Mon Aug 10 06:47:47 PDT 2015


Adds support for AES-192-CBC and AES-256-CBC ciphers to the PEM decode()
function. This also adds a deriveKey() function which stretches the
password to a key as required for decrypting, replacing PBKDF1 for 192
and 256 bits.
---
 lib/Crypto/IO/PEM.py | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/lib/Crypto/IO/PEM.py b/lib/Crypto/IO/PEM.py
index 89a5689..11dd782 100644
--- a/lib/Crypto/IO/PEM.py
+++ b/lib/Crypto/IO/PEM.py
@@ -110,6 +110,27 @@ def decode(pem_data, passphrase=None):
       been provided or if the passphrase is incorrect.
     """
 
+    def deriveKey(password, salt, keySize):
+        """Stretch the password to a key as required for decrypting.
+
+        This algorithm was derived from the Go source, which itself derived it
+        from the OpenSSL source.
+
+        https://golang.org/src/crypto/x509/pem_decrypt.go
+        """
+        out = b''
+        digest = b''
+        i = 0
+        while i < keySize:
+            md5 = MD5.new()
+            md5.update(digest)
+            md5.update(tobytes(password))
+            md5.update(salt)
+            digest = md5.digest()
+            out = out + digest
+            i = i + len(digest)
+        return out[:keySize]
+
     # Verify Pre-Encapsulation Boundary
     r = re.compile("\s*-----BEGIN (.*)-----\n")
     m = r.match(pem_data)
@@ -147,6 +168,12 @@ def decode(pem_data, passphrase=None):
         elif algo == "AES-128-CBC":
             key = PBKDF1(passphrase, salt[:8], 16, 1, MD5)
             objdec = AES.new(key, AES.MODE_CBC, salt)
+        elif algo == "AES-192-CBC":
+            key = deriveKey(passphrase, salt[:8], 24)
+            objdec = AES.new(key, AES.MODE_CBC, salt)
+        elif algo == "AES-256-CBC":
+            key = deriveKey(passphrase, salt[:8], 32)
+            objdec = AES.new(key, AES.MODE_CBC, salt)
         else:
             raise ValueError("Unsupport PEM encryption algorithm.")
         lines = lines[2:]
-- 
2.1.4



More information about the pycrypto mailing list