I'm thinking whether the following way is a good way to completely and totally prevent ddos on my server. My idea is to use the same mechanism of cryptocurrency mining (bitcoin, with sha256 or any other hash) to prevent DDOS.
Note: I'm not suggesting to mine cryptocurrency per se. I'm suggesting to use the same mechanism to avoid Sybil attacks.
Why does idea look appealing to me? Because creating a mined hash is expensive, but verifying it is super-cheap. it costs only calculating a hash once.
What does mining mean, in a nutshell? It means that there's a specific chunk of data (say a session id, or a JWT token, that can be stored in the server in a performant NoSQL server), and the user (or the miner in cryptocurrency) has to create a hash that matches certain criteria. For example, if we use SHA256, we can define the difficulty as the required number of the leading zeros in the 256-bit resulting number from the hash. More zeros make the probability of finding that hash more difficult.
How does it work?: A user would take the session token (which is created by the server), and combine it with a nonce (number used once), and calculate the hash in their frontend (through WASM, or otherwise with javascript). Since the user cannot reverse-engineer SHA256, all he can do is keep changing the nonce again, and again and again, until he finds a nonce that creates a hash that satisfies the required difficulty.
The graph shows the probability of finding a block (finding the correct nonce) in Bitcoin, where the difficulty is chosen to make it 10 minutes. Changing the difficulty will shift this curve and change its width proportionally.
How long does it take the server to verify? Practically zero. Just calculate the hash once and ensure that it matches the given difficulty, and that authorizes the user to make any anonymous request. Notice that none of this requires authentication with usernames and password. This is all anonymous. Authenticated users don't need to do this as their credentials can be banned from the system. This is all for anonymous users (and possibly attackers).
The result: The user will have to calculate this hash with this difficulty before making any request to the server. Once the user succeeds, the mined authentication token can be stored in a cookie to be reused by the user. If the user fails to provide the requested hash, his connection request will be abruptly reject, and thus preventing a DDOS attack with sock-puppets.
ASIC resistance: Using SHA256 is not recommended because there's specialized hardware that can calculate it very fast, leading to a possible coordinated attack. There are hashes that are hard to print on hardware, such as Scrypt and Argon2.
Choosing the difficulty: The difficulty can be static (which I wouldn't recommend), or can be dynamic to change with the load on the network. When a high network load exists, the required difficulty is increased. This basically will act as a filter and protect the network during DDOS attack times, and never affect the users, as users normally wouldn't care to wait 10 seconds to create a session. In case of really high load, the users can either choose to compute the expensive nonce, or come back later. The hosting company also can decide whether an expansion of the infrastructure is required based on the difficulty chart over time.
Is this a sound plan to protect against DDOS on websocket and similar public protocols? I would like to implement this on my server.
EDIT: Just to be clear, this is not a silver bullet to all kinds of DDOS. But this prevents the users from manipulating the internal functionality of the server + makes it difficult to use the server functionality to exhaust bandwidth. I would be interested in knowing why this may or may not work, more than a summary on whether this is new or old.