def test_unaligned_data_64(self): plaintexts = [ b"7777777" ] * 100 cipher = DES3.new(self.key_192, DES3.MODE_OPENPGP, self.iv_64) ciphertexts = [ cipher.encrypt(x) for x in plaintexts ] cipher = DES3.new(self.key_192, DES3.MODE_OPENPGP, self.iv_64) self.assertEqual(b"".join(ciphertexts), cipher.encrypt(b"".join(plaintexts)))
def test_des3(self): # The following test vectors have been generated with gpg v1.4.0. # The command line used was: # gpg -c -z 0 --cipher-algo 3DES --passphrase secret_passphrase \ # --disable-mdc --s2k-mode 0 --output ct pt # For an explanation, see test_AES.py . plaintext = 'ac1762037074324fb53ba3596f73656d69746556616c6c6579' ciphertext = '9979238528357b90e2e0be549cb0b2d5999b9a4a447e5c5c7d' key = '7ade65b460f5ea9be35f9e14aa883a2048e3824aa616c0b2' iv='cd47e2afb8b7e4b0' encrypted_iv='6a7eef0b58050e8b904a' plaintext = unhexlify(plaintext) ciphertext = unhexlify(ciphertext) key = unhexlify(key) iv = unhexlify(iv) encrypted_iv = unhexlify(encrypted_iv) cipher = DES3.new(key, DES3.MODE_OPENPGP, iv) ct = cipher.encrypt(plaintext) self.assertEqual(ct[:10], encrypted_iv) self.assertEqual(ct[10:], ciphertext) cipher = DES3.new(key, DES3.MODE_OPENPGP, encrypted_iv) pt = cipher.decrypt(ciphertext) self.assertEqual(pt, plaintext)
def test_des3(self): # The following test vectors have been generated with gpg v1.4.0. # The command line used was: # gpg -c -z 0 --cipher-algo 3DES --passphrase secret_passphrase \ # --disable-mdc --s2k-mode 0 --output ct pt # For an explanation, see test_AES.py . plaintext = 'ac1762037074324fb53ba3596f73656d69746556616c6c6579' ciphertext = '9979238528357b90e2e0be549cb0b2d5999b9a4a447e5c5c7d' key = '7ade65b460f5ea9be35f9e14aa883a2048e3824aa616c0b2' iv = 'cd47e2afb8b7e4b0' encrypted_iv = '6a7eef0b58050e8b904a' plaintext = unhexlify(plaintext) ciphertext = unhexlify(ciphertext) key = unhexlify(key) iv = unhexlify(iv) encrypted_iv = unhexlify(encrypted_iv) cipher = DES3.new(key, DES3.MODE_OPENPGP, iv) ct = cipher.encrypt(plaintext) self.assertEqual(ct[:10], encrypted_iv) self.assertEqual(ct[10:], ciphertext) cipher = DES3.new(key, DES3.MODE_OPENPGP, encrypted_iv) pt = cipher.decrypt(ciphertext) self.assertEqual(pt, plaintext)
def test_unaligned_data_64(self): plaintexts = [b("7777777")] * 100 cipher = DES3.new(self.key_192, DES3.MODE_CFB, self.iv_64, segment_size=8) ciphertexts = [cipher.encrypt(x) for x in plaintexts] cipher = DES3.new(self.key_192, DES3.MODE_CFB, self.iv_64, segment_size=8) self.assertEqual( b("").join(ciphertexts), cipher.encrypt(b("").join(plaintexts))) cipher = DES3.new(self.key_192, DES3.MODE_CFB, self.iv_64, segment_size=64) ciphertexts = [cipher.encrypt(x) for x in plaintexts] cipher = DES3.new(self.key_192, DES3.MODE_CFB, self.iv_64, segment_size=64) self.assertEqual( b("").join(ciphertexts), cipher.encrypt(b("").join(plaintexts)))
def test_loopback_64(self): cipher = DES3.new(self.key_192, self.des3_mode, self.iv_64) pt = get_tag_random("plaintext", 8 * 100) ct = cipher.encrypt(pt) cipher = DES3.new(self.key_192, self.des3_mode, self.iv_64) pt2 = cipher.decrypt(ct) self.assertEqual(pt, pt2)
def test_loopback_64(self): cipher = DES3.new(self.key_192, DES3.MODE_EAX, nonce=self.nonce_96) pt = get_tag_random("plaintext", 8 * 100) ct = cipher.encrypt(pt) cipher = DES3.new(self.key_192, DES3.MODE_EAX, nonce=self.nonce_96) pt2 = cipher.decrypt(ct) self.assertEqual(pt, pt2)
def test_loopback_64(self): cipher = DES3.new(self.key_192, DES3.MODE_CTR, counter=self.ctr_64) pt = get_tag_random("plaintext", 8 * 100) ct = cipher.encrypt(pt) cipher = DES3.new(self.key_192, DES3.MODE_CTR, counter=self.ctr_64) pt2 = cipher.decrypt(ct) self.assertEqual(pt, pt2)
def test_unaligned_data_64(self): cipher = DES3.new(self.key_192, self.des3_mode, self.iv_64) for wrong_length in range(1, 8): self.assertRaises(ValueError, cipher.encrypt, b"5" * wrong_length) cipher = DES3.new(self.key_192, self.des3_mode, self.iv_64) for wrong_length in range(1, 8): self.assertRaises(ValueError, cipher.decrypt, b"5" * wrong_length)
def test_unaligned_data_64(self): plaintexts = [b"7777777"] * 100 cipher = DES3.new(self.key_192, DES3.MODE_OPENPGP, self.iv_64) ciphertexts = [cipher.encrypt(x) for x in plaintexts] cipher = DES3.new(self.key_192, DES3.MODE_OPENPGP, self.iv_64) self.assertEqual(b"".join(ciphertexts), cipher.encrypt(b"".join(plaintexts)))
def test_unaligned_data_64(self): cipher = DES3.new(self.key_192, self.des3_mode, self.iv_64) for wrong_length in xrange(1,8): self.assertRaises(ValueError, cipher.encrypt, b("5") * wrong_length) cipher = DES3.new(self.key_192, self.des3_mode, self.iv_64) for wrong_length in xrange(1,8): self.assertRaises(ValueError, cipher.decrypt, b("5") * wrong_length)
def setup_cipher(self): if self.mode == cipherMODE.ECB: self._cipher = _pyCryptodomeTDES.new(self.key, _pyCryptodomeTDES.MODE_ECB) elif self.mode == cipherMODE.CBC: self._cipher = _pyCryptodomeTDES.new(self.key, _pyCryptodomeTDES.MODE_CBC, iv=self.IV) else: raise Exception('Unknown cipher mode!')
def test_loopback_64(self): cipher = DES3.new(self.key_192, DES3.MODE_OPENPGP, self.iv_64) pt = get_tag_random("plaintext", 8 * 100) ct = cipher.encrypt(pt) eiv, ct = ct[:10], ct[10:] cipher = DES3.new(self.key_192, DES3.MODE_OPENPGP, eiv) pt2 = cipher.decrypt(ct) self.assertEqual(pt, pt2)
def test_unaligned_data_64(self): plaintexts = [ b("7777777") ] * 100 cipher = DES3.new(self.key_192, DES3.MODE_CFB, self.iv_64, segment_size=8) ciphertexts = [ cipher.encrypt(x) for x in plaintexts ] cipher = DES3.new(self.key_192, DES3.MODE_CFB, self.iv_64, segment_size=8) self.assertEqual(b("").join(ciphertexts), cipher.encrypt(b("").join(plaintexts))) cipher = DES3.new(self.key_192, DES3.MODE_CFB, self.iv_64, segment_size=64) ciphertexts = [ cipher.encrypt(x) for x in plaintexts ] cipher = DES3.new(self.key_192, DES3.MODE_CFB, self.iv_64, segment_size=64) self.assertEqual(b("").join(ciphertexts), cipher.encrypt(b("").join(plaintexts)))
def test_unaligned_data_64(self): plaintexts = [ b("7777777") ] * 100 cipher = DES3.new(self.key_192, AES.MODE_CTR, counter=self.ctr_64) ciphertexts = [ cipher.encrypt(x) for x in plaintexts ] cipher = DES3.new(self.key_192, AES.MODE_CTR, counter=self.ctr_64) self.assertEqual(b("").join(ciphertexts), cipher.encrypt(b("").join(plaintexts))) cipher = DES3.new(self.key_192, AES.MODE_CTR, counter=self.ctr_64) ciphertexts = [ cipher.encrypt(x) for x in plaintexts ] cipher = DES3.new(self.key_192, AES.MODE_CTR, counter=self.ctr_64) self.assertEqual(b("").join(ciphertexts), cipher.encrypt(b("").join(plaintexts)))
def test_unaligned_data_64(self): plaintexts = [ b"7777777" ] * 100 cipher = DES3.new(self.key_192, AES.MODE_CTR, counter=self.ctr_64) ciphertexts = [ cipher.encrypt(x) for x in plaintexts ] cipher = DES3.new(self.key_192, AES.MODE_CTR, counter=self.ctr_64) self.assertEqual(b"".join(ciphertexts), cipher.encrypt(b"".join(plaintexts))) cipher = DES3.new(self.key_192, AES.MODE_CTR, counter=self.ctr_64) ciphertexts = [ cipher.encrypt(x) for x in plaintexts ] cipher = DES3.new(self.key_192, AES.MODE_CTR, counter=self.ctr_64) self.assertEqual(b"".join(ciphertexts), cipher.encrypt(b"".join(plaintexts)))
def run_3DES(): while True: try: key = DES3.adjust_key_parity(Random.get_random_bytes(24)) break except ValueError: pass nonce = Random.get_random_bytes(16) print("=================") print("Encrypting with 3DES") print("Key: ", to_hex(key)) print("Nonce: ", to_hex(nonce)) cipher = DES3.new(key, DES3.MODE_EAX, nonce) ciphertext = cipher.encrypt(data) #print("Cleartext: ", to_hex(data)) #print("Ciphertext: ", to_hex(ciphertext)) file_out = open("des3.bin", "wb") [file_out.write(x) for x in (cipher.nonce, ciphertext)] file_out.close() file_in = open("des3.bin", "rb") decrypt_nonce, decrypt_ciphertext = [file_in.read(x) for x in (16, -1)] file_in.close() print("=================") print("Decrypting with 3DES") print("Key: ", to_hex(key)) print("Nonce: ", to_hex(decrypt_nonce)) #print("Ciphertext: ", to_hex(decrypt_ciphertext)) decipher = DES3.new(key, DES3.MODE_EAX, decrypt_nonce) cleartext = decipher.decrypt(decrypt_ciphertext) #print("Cleartext: ", to_hex(cleartext)) print("=================") if cleartext == data: print("Decryption successful\n") else: print("Decryption failed\n") return
def _do_tdes_test(self, file_name): test_vectors = load_tests(("Cryptodome", "SelfTest", "Cipher", "test_vectors", "TDES"), file_name, "TDES CBC KAT", { "count" : lambda x: int(x) } ) assert(test_vectors) direction = None for tv in test_vectors: # The test vector file contains some directive lines if isinstance(tv, basestring): direction = tv continue self.description = tv.desc if hasattr(tv, "keys"): cipher = DES.new(tv.keys, self.des_mode, tv.iv) else: if tv.key1 != tv.key3: key = tv.key1 + tv.key2 + tv.key3 # Option 3 else: key = tv.key1 + tv.key2 # Option 2 cipher = DES3.new(key, self.des3_mode, tv.iv) if direction == "[ENCRYPT]": self.assertEqual(cipher.encrypt(tv.plaintext), tv.ciphertext) elif direction == "[DECRYPT]": self.assertEqual(cipher.decrypt(tv.ciphertext), tv.plaintext) else: assert False
def card_encrypt(data, cardid): t = datetime.date.today().strftime('%Y%m%d') tdeskey = hashlib.sha1((cardid + t).encode('ascii')).digest() + KEY_SUFFIX cipher = DES3.new(tdeskey, DES3.MODE_ECB) data = cipher.encrypt(pkcs5_pad(data)) return TDesLKey1.encrypt(iv_pad(data))
def shared_key_decrypt(ciphertext, key): alg = key['alg'] mode = key['mode'] k = key['key'] decrypt_kwargs = {'mode': BLOCK_MODES[alg][mode]} preamble_length = BLOCK_SIZES[alg] if mode in IV_MODES: #print("SYM_DECRYPT: Generating an IV", flush = True) decrypt_kwargs['iv'] = ciphertext[0:BLOCK_SIZES[alg]] elif mode == 'ctr': #print('SYM_DECRYPT: Generating a Counter', flush = True) preamble_length = preamble_length // 2 n = ciphertext[0:(BLOCK_SIZES[alg] // 2)] decrypt_kwargs['nonce'] = n if alg == 'aes': #print('SYM_DECRYPT: USING AES') decrypter = AES.new(k, **decrypt_kwargs) elif alg == 'des3': #print('SYM_DECRYPT: USING DES3') decrypter = DES3.new(k, **decrypt_kwargs) elif alg == 'blowfish': #print('SYM_DECRYPT: USING Blowfish') decrypter = Blowfish.new(k, **decrypt_kwargs) serial_pt = decrypter.decrypt(ciphertext[preamble_length:]) if mode in PAD_MODES: serial_pt = unpad(serial_pt, BLOCK_SIZES[alg]) if serial_pt[0]: return pickle.loads(serial_pt[1:]) else: return serial_pt[1:] return pt
def decode(self, data): if data == '': return data key_handle = DES3.new(self.uniq_id(), DES3.MODE_CBC, iv=b'\0\0\0\0\0\0\0\0') decrypted = unpad(key_handle.decrypt(b64decode(data)), DES3.block_size) return decrypted.decode('utf-8')
def encrypt(self,data): print("DES3 key " , self.key) #Padding data to block size data = pad(data,self.block_size); iv = Random.new().read(self.block_size) byte_data = bytes(data, 'utf-8') cipher = DES3.new(self.key,DES3.MODE_CBC,iv) return bytes(iv + cipher.encrypt(byte_data))
def decrypt_json(encrypted_data, secret_bytes_key, cipher_type='AES'): dct = serialization.BytesToDict( encrypted_data, encoding='utf-8', keys_to_text=True, values_to_text=True, ) if cipher_type == 'AES': cipher = AES.new( key=secret_bytes_key, mode=AES.MODE_CBC, iv=base64.b64decode(dct['iv'].encode('utf-8')), ) elif cipher_type == 'DES3': cipher = DES3.new( key=secret_bytes_key, mode=DES3.MODE_CBC, iv=base64.b64decode(dct['iv'].encode('utf-8')), ) else: raise Exception('unsupported cipher type') padded_data = cipher.decrypt(base64.b64decode(dct['ct'].encode('utf-8'))) if cipher_type == 'AES': raw_data = Padding.unpad( padded_data=padded_data, block_size=AES.block_size, ) elif cipher_type == 'DES3': raw_data = Padding.unpad( padded_data=padded_data, block_size=DES3.block_size, ) # TODO: remove salt from raw_data return raw_data
def _do_tdes_test(self, file_name, segment_size): test_vectors = load_tests(("Cryptodome", "SelfTest", "Cipher", "test_vectors", "TDES"), file_name, "AES CFB%d KAT" % segment_size, { "count" : lambda x: int(x) } ) assert(test_vectors) direction = None for tv in test_vectors: # The test vector file contains some directive lines if is_string(tv): direction = tv continue self.description = tv.desc if hasattr(tv, "keys"): cipher = DES.new(tv.keys, DES.MODE_CFB, tv.iv, segment_size=segment_size) else: if tv.key1 != tv.key3: key = tv.key1 + tv.key2 + tv.key3 # Option 3 else: key = tv.key1 + tv.key2 # Option 2 cipher = DES3.new(key, DES3.MODE_CFB, tv.iv, segment_size=segment_size) if direction == "[ENCRYPT]": self.assertEqual(cipher.encrypt(tv.plaintext), tv.ciphertext) elif direction == "[DECRYPT]": self.assertEqual(cipher.decrypt(tv.ciphertext), tv.plaintext) else: assert False
def _do_tdes_test(self, file_name): test_vectors = load_test_vectors(("Cipher", "TDES"), file_name, "TDES CBC KAT", {"count": lambda x: int(x)}) if test_vectors is None: return direction = None for tv in test_vectors: # The test vector file contains some directive lines if is_string(tv): direction = tv continue self.description = tv.desc if hasattr(tv, "keys"): cipher = DES.new(tv.keys, self.des_mode, tv.iv) else: if tv.key1 != tv.key3: key = tv.key1 + tv.key2 + tv.key3 # Option 3 else: key = tv.key1 + tv.key2 # Option 2 cipher = DES3.new(key, self.des3_mode, tv.iv) if direction == "[ENCRYPT]": self.assertEqual(cipher.encrypt(tv.plaintext), tv.ciphertext) elif direction == "[DECRYPT]": self.assertEqual(cipher.decrypt(tv.ciphertext), tv.plaintext) else: assert False
def decryptData(self, decryptKey, privParameters, encryptedData): if DES3 is None: raise error.StatusInformation( errorIndication=errind.decryptionError ) snmpEngineBoots, snmpEngineTime, salt = privParameters if len(salt) != 8: raise error.StatusInformation( errorIndication=errind.decryptionError ) des3Key, iv = self.__getDecryptionKey(decryptKey, salt) if len(encryptedData) % 8 != 0: raise error.StatusInformation( errorIndication=errind.decryptionError ) des3Obj = DES3.new(des3Key, DES3.MODE_CBC, iv) ciphertext = encryptedData.asOctets() plaintext = des3Obj.decrypt(ciphertext) return plaintext
def encrypt_json(raw_data, secret_bytes_key, cipher_type='AES'): # TODO: add salt to raw_data padded_data = Padding.pad( data_to_pad=raw_data, block_size=AES.block_size, ) if cipher_type == 'AES': cipher = AES.new( key=secret_bytes_key, mode=AES.MODE_CBC, ) elif cipher_type == 'DES3': cipher = DES3.new( key=secret_bytes_key, mode=DES3.MODE_CBC, ) else: raise Exception('unsupported cipher type') ct_bytes = cipher.encrypt(padded_data) dct = { 'iv': base64.b64encode(cipher.iv).decode('utf-8'), 'ct': base64.b64encode(ct_bytes).decode('utf-8'), } encrypted_data = serialization.DictToBytes(dct, encoding='utf-8') return encrypted_data
def runTest(self): # Encrypt/Decrypt data and test output parameter cipher = DES3.new(b'4'*8 + b'G'*8 + b'T'*8, DES3.MODE_ECB) pt = b'5' * 16 ct = cipher.encrypt(pt) output = bytearray(16) res = cipher.encrypt(pt, output=output) self.assertEqual(ct, output) self.assertEqual(res, None) res = cipher.decrypt(ct, output=output) self.assertEqual(pt, output) self.assertEqual(res, None) import sys if sys.version[:3] != '2.6': output = memoryview(bytearray(16)) cipher.encrypt(pt, output=output) self.assertEqual(ct, output) cipher.decrypt(ct, output=output) self.assertEqual(pt, output) self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0'*16) self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0'*16) shorter_output = bytearray(7) self.assertRaises(ValueError, cipher.encrypt, pt, output=shorter_output) self.assertRaises(ValueError, cipher.decrypt, ct, output=shorter_output)
def _do_tdes_test(self, file_name, segment_size): test_vectors = load_tests(("Cryptodome", "SelfTest", "Cipher", "test_vectors", "TDES"), file_name, "AES CFB%d KAT" % segment_size, { "count" : lambda x: int(x) } ) assert(test_vectors) direction = None for tv in test_vectors: # The test vector file contains some directive lines if isinstance(tv, str): direction = tv continue self.description = tv.desc if hasattr(tv, "keys"): cipher = DES.new(tv.keys, DES.MODE_CFB, tv.iv, segment_size=segment_size) else: if tv.key1 != tv.key3: key = tv.key1 + tv.key2 + tv.key3 # Option 3 else: key = tv.key1 + tv.key2 # Option 2 cipher = DES3.new(key, DES3.MODE_CFB, tv.iv, segment_size=segment_size) if direction == "[ENCRYPT]": self.assertEqual(cipher.encrypt(tv.plaintext), tv.ciphertext) elif direction == "[DECRYPT]": self.assertEqual(cipher.decrypt(tv.ciphertext), tv.plaintext) else: assert False
def get_result(result, secretKey, date): des3 = DES3.new(key=secretKey.encode(), mode=DES3.MODE_CBC, iv=date.encode()) decrypted_data = des3.decrypt(base64.b64decode(result)) plain_text = unpad(decrypted_data, DES3.block_size).decode() return plain_text
def encode(self, data): key_handle = DES3.new(self.uniq_id(), DES3.MODE_CBC, iv=b'\0\0\0\0\0\0\0\0') encrypted = key_handle.encrypt( pad(data.encode('utf-8'), DES3.block_size)) return b64encode(encrypted)
def encrypt(key, filename): chunk_size = 64 * 1024 output_file = "encrypted" + filename file_size = os.path.getsize(filename) iv = Random.new().read(DES3.block_size) cipher = DES3.new(key=key, mode=DES3.MODE_CBC, iv=iv) with open(filename, 'rb') as in_file: with open(output_file, 'wb') as out_file: out_file.write(struct.pack('<Q', file_size)) out_file.write(iv) while True: chunk = in_file.read(chunk_size) if len(chunk) == 0: break elif len(chunk) % 8 != 0: chunk += b' ' * (8 - len(chunk) % 8) out_file.write(cipher.encrypt(chunk)) output_key = filename + '.key' with open(output_key, 'wb') as out_key: out_key.write(key)
def _cryptodome_cipher(key, iv): """Build a Pycryptodome DES3 Cipher object. :param bytes key: Encryption key :param bytes iv: Initialization vector :returns: DES3 Cipher instance """ return DES3.new(key, DES3.MODE_CBC, iv)
def __init__(self, key): self.key = key # 初始化密钥 self.iv = b'01234567' # 偏移量 self.length = DES3.block_size # 初始化数据块大小 self.des3 = DES3.new(self.key, DES3.MODE_CBC, self.iv) # 初始化AES,CBC模式的实例 # 截断函数,去除填充的字符 self.unpad = lambda date: date[0:-ord(date[-1])]
def decryptTripleDES(data, key): #des3 = DES3.new(key, DES3.MODE_ECB) _DES3 = DES3.new(key, DES3.MODE_CBC, iv) decryptedText = unpad(_DES3.decrypt(data), DES3.block_size) return decryptedText
def decrypt(self, ciphertext): iv = ciphertext[:DES3.block_size] cipher = DES3.new(self.key,DES3.MODE_CFB,iv) plaintext = cipher.decrypt(ciphertext[DES3.block_size:-1]) padding_size = ciphertext[-1]*(-1) if(padding_size == 0): return plaintext else: return plaintext[:padding_size]
def test_segment_size_64(self): for bits in xrange(8, 65, 8): cipher = DES3.new(self.key_192, DES3.MODE_CFB, self.iv_64, segment_size=bits) for bits in 0, 7, 9, 63, 65: self.assertRaises(ValueError, DES3.new, self.key_192, AES.MODE_CFB, self.iv_64, segment_size=bits)
def test_segment_size_64(self): for bits in range(8, 65, 8): cipher = DES3.new(self.key_192, DES3.MODE_CFB, self.iv_64, segment_size=bits) for bits in 0, 7, 9, 63, 65: self.assertRaises(ValueError, DES3.new, self.key_192, AES.MODE_CFB, self.iv_64, segment_size=bits)
def des_encrypt(data, key): # align to 8 bytes data_len = len(data) if data_len % 8 != 0: data += b'\x03' * (8 - data_len % 8) cipher = DES3.new(key, DES3.MODE_ECB) return cipher.encrypt(data)
def three_des_encode(code): key = 'Sixteen byte key' key = key.encode() msg = code.encode() iv = Random.new().read(DES3.block_size) cipher = DES3.new(key, DES3.MODE_OFB, iv) msg = iv + cipher.encrypt(msg) msg = binascii.b2a_hex(msg) return "3DEs_encode", msg.decode()
def test_nonce_attribute(self): # Nonce attribute is the prefix passed to Counter (DES3) cipher = DES3.new(self.key_192, DES3.MODE_CTR, counter=self.ctr_64) self.assertEqual(cipher.nonce, self.nonce_32) # Nonce attribute is the prefix passed to Counter (AES) cipher = AES.new(self.key_128, AES.MODE_CTR, counter=self.ctr_128) self.assertEqual(cipher.nonce, self.nonce_64) # Nonce attribute is not defined if suffix is used in Counter counter = Counter.new(64, prefix=self.nonce_32, suffix=self.nonce_32) cipher = AES.new(self.key_128, AES.MODE_CTR, counter=counter) self.failIf(hasattr(cipher, "nonce"))
def encode(data, marker, passphrase=None, randfunc=None): """Encode a piece of binary data into PEM format. Args: data (byte string): The piece of binary data to encode. marker (string): The marker for the PEM block (e.g. "PUBLIC KEY"). Note that there is no official master list for all allowed markers. Still, you can refer to the OpenSSL_ source code. passphrase (byte string): If given, the PEM block will be encrypted. The key is derived from the passphrase. randfunc (callable): Random number generation function; it accepts an integer N and returns a byte string of random data, N bytes long. If not given, a new one is instantiated. Returns: The PEM block, as a string. .. _OpenSSL: https://github.com/openssl/openssl/blob/master/include/openssl/pem.h """ if randfunc is None: randfunc = get_random_bytes out = "-----BEGIN %s-----\n" % marker if passphrase: # We only support 3DES for encryption salt = randfunc(8) key = PBKDF1(passphrase, salt, 16, 1, MD5) key += PBKDF1(key + passphrase, salt, 8, 1, MD5) objenc = DES3.new(key, DES3.MODE_CBC, salt) out += "Proc-Type: 4,ENCRYPTED\nDEK-Info: DES-EDE3-CBC,%s\n\n" %\ tostr(hexlify(salt).upper()) # Encrypt with PKCS#7 padding data = objenc.encrypt(pad(data, objenc.block_size)) elif passphrase is not None: raise ValueError("Empty password") # Each BASE64 line can take up to 64 characters (=48 bytes of data) # b2a_base64 adds a new line character! chunks = [tostr(b2a_base64(data[i:i + 48])) for i in range(0, len(data), 48)] out += "".join(chunks) out += "-----END %s-----" % marker return out
def test_block_size_64(self): cipher = DES3.new(self.key_192, self.des3_mode, self.iv_64) self.assertEqual(cipher.block_size, DES3.block_size)
def decode(pem_data, passphrase=None): """Decode a PEM block into binary. Args: pem_data (string): The PEM block. passphrase (byte string): If given and the PEM block is encrypted, the key will be derived from the passphrase. Returns: A tuple with the binary data, the marker string, and a boolean to indicate if decryption was performed. Raises: ValueError: if decoding fails, if the PEM file is encrypted and no passphrase has been provided or if the passphrase is incorrect. """ # Verify Pre-Encapsulation Boundary r = re.compile(r"\s*-----BEGIN (.*)-----\s+") m = r.match(pem_data) if not m: raise ValueError("Not a valid PEM pre boundary") marker = m.group(1) # Verify Post-Encapsulation Boundary r = re.compile(r"-----END (.*)-----\s*$") m = r.search(pem_data) if not m or m.group(1) != marker: raise ValueError("Not a valid PEM post boundary") # Removes spaces and slit on lines lines = pem_data.replace(" ", '').split() # Decrypts, if necessary if lines[1].startswith('Proc-Type:4,ENCRYPTED'): if not passphrase: raise ValueError("PEM is encrypted, but no passphrase available") DEK = lines[2].split(':') if len(DEK) != 2 or DEK[0] != 'DEK-Info': raise ValueError("PEM encryption format not supported.") algo, salt = DEK[1].split(',') salt = unhexlify(tobytes(salt)) if algo == "DES-CBC": # This is EVP_BytesToKey in OpenSSL key = PBKDF1(passphrase, salt, 8, 1, MD5) objdec = DES.new(key, DES.MODE_CBC, salt) elif algo == "DES-EDE3-CBC": # Note that EVP_BytesToKey is note exactly the same as PBKDF1 key = PBKDF1(passphrase, salt, 16, 1, MD5) key += PBKDF1(key + passphrase, salt, 8, 1, MD5) objdec = DES3.new(key, DES3.MODE_CBC, salt) elif algo == "AES-128-CBC": key = PBKDF1(passphrase, salt[:8], 16, 1, MD5) objdec = AES.new(key, AES.MODE_CBC, salt) else: raise ValueError("Unsupport PEM encryption algorithm (%s)." % algo) lines = lines[2:] else: objdec = None # Decode body data = a2b_base64(''.join(lines[1:-1])) enc_flag = False if objdec: data = unpad(objdec.decrypt(data), objdec.block_size) enc_flag = True return (data, marker, enc_flag)
def test_block_size_64(self): cipher = DES3.new(self.key_192, DES3.MODE_CTR, counter=self.ctr_64) self.assertEqual(cipher.block_size, DES3.block_size)
def test_block_size_64(self): cipher = DES3.new(self.key_192, AES.MODE_EAX, nonce=self.nonce_96) self.assertEqual(cipher.block_size, DES3.block_size)
def basic_encrypt(cls, key, plaintext): assert len(plaintext) % 8 == 0 des3 = DES3.new(key.contents, AES.MODE_CBC, b'\0' * 8) return des3.encrypt(bytes(plaintext))
def basic_decrypt(cls, key, ciphertext): assert len(ciphertext) % 8 == 0 des3 = DES3.new(key.contents, AES.MODE_CBC, b'\0' * 8) return des3.decrypt(bytes(ciphertext))