def encrypt(self, plaintext): """ Generate a random IV and encrypt the plaintext with the given key Note that IV (initialization vector) must never be used twice. From Wikipedia: An initialization vector has different security requirements than a key, so the IV usually does not need to be secret. However, in most cases, it is important that an initialization vector is never reused under the same key. For CBC and CFB, reusing an IV leaks some information about the first block of plaintext, and about any common prefix shared by the two messages. For OFB and CTR, reusing an IV completely destroys security. Parameters ---------- plaintext : bytes Returns: ---------- bytes : The IV concatenated with the ciphertext """ iv = urandom(self.IV_SIZE) return iv + cfb_encrypt(self.ciph.encrypt, 16, plaintext, iv)
def test_cfb_symmetric(self): for _ in range(100): pt = urandom(randint(0, 16 * 2)) iv = urandom(8 * 2) ciph = GOST3412Magma(urandom(32)) ct = cfb_encrypt(ciph.encrypt, 8, pt, iv) self.assertSequenceEqual(cfb_decrypt(ciph.encrypt, 8, ct, iv), pt)
def test_cfb_vectors(self): iv = self.iv[:16] ciphtext = "" ciphtext += "db37e0e266903c83" ciphtext += "0d46644c1f9a089c" ciphtext += "24bdd2035315d38b" ciphtext += "bcc0321421075505" self.assertSequenceEqual( hexenc( cfb_encrypt(self.ciph.encrypt, 8, hexdec(self.plaintext), iv)), ciphtext, ) self.assertSequenceEqual( hexenc(cfb_decrypt(self.ciph.encrypt, 8, hexdec(ciphtext), iv)), self.plaintext, )
def test_cfb_vectors(self): ciphtext = "" ciphtext += "81800a59b1842b24ff1f795e897abd95" ciphtext += "ed5b47a7048cfab48fb521369d9326bf" ciphtext += "79f2a8eb5cc68d38842d264e97a238b5" ciphtext += "4ffebecd4e922de6c75bd9dd44fbf4d1" self.assertSequenceEqual( hexenc( cfb_encrypt(self.ciph.encrypt, 16, hexdec(self.plaintext), self.iv)), ciphtext, ) self.assertSequenceEqual( hexenc( cfb_decrypt(self.ciph.encrypt, 16, hexdec(ciphtext), self.iv)), self.plaintext, )
512 24.900s 1024 48.612s ''' iterations = 32 keysize = 32 salt = urandom(32) password = "******" key = pbkdf2(password.encode(), salt, iterations, keysize) ciph = GOST3412Kuznechik(key) # An initialization vector has different security requirements than a key, # so the IV usually does not need to be secret. However, in most cases, # it is important that an initialization vector is never reused # under the same key. # For CBC and CFB, reusing an IV leaks some information about # the first block of plaintext, and about any common prefix shared by # the two messages. # For OFB and CTR, reusing an IV completely destroys security. # iv: blocksize-sized initialization vector IV_SIZE = 32 iv = urandom(IV_SIZE) plaintext = "this is a plaintext".encode() encrypted = iv + cfb_encrypt(ciph.encrypt, 16, plaintext, iv) decrypted = cfb_decrypt(ciph.encrypt, 16, encrypted[IV_SIZE:], encrypted[:IV_SIZE]).decode("utf-8") print(decrypted)
def encrypt(self, text): buffer = self.padding(text) res = gost3413.cfb_encrypt(self.enc, self.blen, buffer, self.iv) return res