4

First, a warm welcome to the python language! None of this is in any particular order. argparse There is a really nice argument parsing library available out of the box which makes parsing command line args much less clunky. I'd set up your parser like this: # Maybe put this into cli.py from argparse import ArgumentParser def setup_parser(): parser = ...


4

That is a lot of code to review, so this review will only touch on more superficial things. I'm not familiar with the pattern of modifying __all__, but it seems like using an underscore at the start of names which should not be available from the outside would be a less "magic" way of achieving the same thing. black and isort can help make the ...


3

This looks quite good already. However, some improvements can be made: Avoid unnecessary use of stringstreams String streams are quite heavy, so using it to build small strings is perhaps not the way to go. Instead of: std::ostringstream errorMsg; errorMsg << name << " is not a valid hash algorithm"; throw std::runtime_error(errorMsg....


3

Is that just for type hints? Correct, everything in the typing module is used for type hints. These are useful when using something like mypy, but the python interpreter will just ignore all of these. Would it be faster to use numpy arrays instead of python lists of lists? Theoretically, yes but it depends on the size of the data. numpy is really meant ...


3

You're diffing msg_frqs with FREQUENCIES. The latter's sum is 1, the former's isn't, because you're counting the upper case letters in msg_length but not in msg_frqs. That seems inappropriate. So better start getGoodness with msg = msg.lower(). And I wouldn't round. Why throw away information? Especially using extra code and time.


3

The shift() function was fairly easy to understand, in no small part because you've chosen reasonable and clear variable names. Here are a few relatively minor suggestions regarding the function. (1) Strings are iterable, so you can convert to characters directly. (2) Python makes iteration so easy that looping over data via an index is usually not needed. ...


2

The padding step is unnecessary - CFB works out of the box on any plaintext length since it XORS the plaintext with the AES output. Lack of authentication means that the scheme is vulnerable to a bit flipping attack, where you can flip bits in the ciphertext and cause a corresponding bit flip in the plaintext. Other nitpicks: str.encode(url) should be url....


2

Yes, it has [serious issues]. For instance, because the salt is not unique, the code is fully deterministic. That means that you directly leak information if you encrypt strings with the same password (similar to how ECB leaks information). The resulting ciphertext is not authenticated either, so supplying a wrong password may result in successful decryption....


2

private static byte[] getSaltFromPassword(byte[] passwordByteArray) { byte[] bytes = sha256.digest(passwordByteArray); for (int i = 0; i < SALT_ITERATIONS; i++) { bytes = sha256.digest(bytes); } return bytes; } this part is an NO NO. salt has to be random. please refer this old question The salt has to be independent and random ...


2

First lets discuss the class and method naming: StudingClassFirstTime First of all, the word Studing is not in my vocabulary. But please just name classes after what they are supposed to do, and don't include the word class; we know it is a class. load_key: this loads a 32 byte key from file, which is fine, however it doesn't include file in the identifier ...


2

My concern is that the passphrase is 4 sets of "diceware" words (like here: https://diceware.dmuth.org/) and therefore could be brute forced. The diceware password is about 51 bits in strength, so it should indeed be run through a password based key derivation function, especially if you use it to encrypt messages - because encryption can be ...


2

Consider adding PEP484 type hints. I needed to go through this to make some sense of the values you're passing around. not being OS specific - indeed. Your call to cls has dubious security value, and if you deem it to have such value, it's better to call into a cross-platform library that will accomplish the same thing. Currently you're pegged to Windows ...


1

When using something that needs clean-up and implements java.lang.AutoCloseable, make it a habit to use try-with-resources: public void TransformFile(String inputFilename, String outputFilename, Enums.Mode mode) throws IOException { final int buffersize = i << 16; try ( InputStream input = new FileInputStream(inputFilename); ...


1

Basically, I don't see too many C# - Java issues other than the method naming and the enum, where you seemed to have gone from namespace to class while the class is unnecessary in Java. Unfortunately I see a lot of problems that would be equally bad in C# as well as in Java, or any other programming language for that matter. C# -> Java BusinessLogic class ...


1

Write as little code as possible inside a try I see you are writing some of your code in a EAFP (easier to ask for forgiveness than permission) style, as opposed to a LBYL style (look before you leap). This means that you are using try: ... except: ... blocks, which is perfectly fine and often encouraged in Python (article on EAFP vs LBYL in Python). However,...


1

Short comments as docstrings Docstrings are triple-quoted strings that come immediately after you define a class or function, and they are special in the sense that Python can tell those strings are to be seen as comments that document the code. For most of your methods you have a short comment immediately before the function, which is great. My suggestion ...


1

Your part goodness = [] shifted = [] for i in range(26): goodness.append(getGoodness(shift(msg, i))) shifted.append(shift(msg, i)) gdict = dict(zip(goodness, shifted)) print(gdict.get(min(gdict.keys()))) is rather complicated. You could just use min-by-goodness: shifts = (shift(msg, i) for i in range(26)) print(min(shifts, key=getGoodness)) Also ...


1

Just a quick note on how you generate the key: key = "testing" # Will of course be another password IMO, password would be a more descriptive variable name there is no need to write a password in your source code. You can either read it from a file or from the console via the getpass module private_key = hashlib.sha256(key.encode()).digest() ...


1

Advanced Encryption Standard. Please simply include a well defined reference to the standard (it's FIPS 197 by NIST). If you do use any of the standard notations in there, indicate that as well, it will make your code much easier to understand. 'MODE_ECB', 'MODE_CBC', 'MODE_CFB', 'MODE_OFB', 'MODE_CTR' Modes of operation are not part of the block cipher ...


1

void hash(std::string const& password, std::string const& salt, long iter, DigestStore& digest) ... for (int loop = 1; loop < iter; ++loop) ... for (std::size_t loop = 0; loop < digestSize; ++loop) "A long an int and a std::size_t all walked into a bar..." couldn't they all be std::size_t? Also, overriding the ...


1

What I'm not mostly unhappy here is the whole conversions between str, bin and back. You can avoid this by first using digest() (instead of hexdigest()) to format the digest as bytes instead of a string, then converting the bytes directly to an integer: hasvalue = hashlib.sha1(random.getrandbits(128).to_bytes(16, byteorder='big', signed=False)).digest() ...


1

The logic here was kind of hard to understand, but I think this is an equivalent refactoring with comments inlined: open System open System.Security.Cryptography module Chars = let numbers = ['0'..'9'] let lower = ['a'..'z'] let upper = ['A'..'Z'] let special = ['!' .. '/'] @ ['@'] // First parse the arguments separately. Use a DU to let ...


1

Instead of choosing an e, you can randomize it z = coprimes(phi) e = random.choice(z)


Only top voted, non community-wiki answers of a minimum length are eligible