{% extends 'core/Cryptographic Failures/cryptographic_failures.html' %}
{% load static %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
{% block inside-content %}
    <div class="bg-white nav-item flex-grow bg-opacity-20 backdrop-filter backdrop-blur-md w-4/5 problems-container">
         <h1 class="text-center text-white font-bold pb-5">Implementing encryption</h1>

         <p class="text-white">
             This website uses PBKDF2 with SHA256 hashing and salting for its general purposes, as we have no internet
             communication with another server. For hashing and encrypting, many already done libraries exist we can use
             instead of writing our own. But for the sake of explanation, I will explain in general how we can implement
             our own data encryption. Let's start by picking an algorithm. We will use RSA for the explanation, as it's
             easier to understand. The explanation is done with python language.<br><br>
             For starters, we must import the libraries we will be using.
        </p>

        <div class="flex flex-grow pt-3 pb-3">
            <pre><code class="python rounded-lg">import string
import unidecode
import random
from sympy import *</code></pre>
        </div>

        <p class="text-white">
             Then we need to generate our keys. So let's make a function for it.
        </p>

        <div class="flex flex-grow pt-3 pb-3">
            <pre><code class="python rounded-lg">def Generate_Keys():
	'''
	Generating random prime numbers with randprime function
	from sympy library.
	'''
	p = randprime(0,99999999999999)
	q = randprime(0,99999999999999)

	'''
	All necessary calculations for the key generation, a loop
    is used for finding the greatest common divider equal to one.
	'''
	n = p * q
	fi = (p - 1) * (q - 1)
	e = random.randint(2,fi + 1)
	for _ in iter(int,1):
		if gcd(e,fi) == 1:
			break
		else:
			e += 1

	d = pow(e, -1, fi)

	return p,q,e,n,d</code></pre>
        </div>
        </p>

        <p class="text-white">
            We use this function to generate our private key <span class="font-bold">d</span> and public modulus <span class="font-bold">n</span>
            and exponent <span class="font-bold">e</span>. A private key is something we need to keep ourselves. Public
            modulus and exponent can be sent to people that will, in return, be sending us encrypted messages. Since
            only we have the private key, we can decrypt this communication. In my example, I use 14-digit keys.
            However, in the case of safe encryption, using at least a 2048-digit number is recommended. For more
            information on keys and their generation, you can visit:
            <a href="https://en.wikipedia.org/wiki/RSA_(cryptosystem)" class="font-bold underline">RSA_(cryptosystem)</a>.
            <br><br>
            Since RSA encryption works with binary values, we need a way to convert plaintext into its binary representation.
        </p>

        <div class="flex flex-grow pt-3 pb-3">
            <pre><code class="python rounded-lg">def to_Bin(input):
	'''
	Converting characters to their Unicode representation with
	ord() function
	'''
	my_ascii = []
	for i in range(len(input)):
		my_ascii.append(ord(input[i]))

	'''
	First, splitting the values into parts of equal length,
    in this case, 7. Then converting the Unicode values into
    binary strings using the format() function. Then joining
    the list of lists into one big list
	'''
	to_bin = []
	x = 7
	to_bin += [my_ascii[i: i + x] for i in range(0, len(my_ascii), x)]

	for i in range(len(to_bin)):
		for j in range(len(to_bin[i])):
			to_bin[i][j] = format(to_bin[i][j], "011b")

	for i in range(len(to_bin)):
		to_bin[i] = ''.join(to_bin[i])
	return to_bin</code></pre>
        </div>

        <p class="text-white">
            You don't have to follow precisely when implementing yourself, as some choices were my preference, such as
            splitting the characters by seven and giving the binary numbers length 11. We can encrypt the data now that
            we have both keys and data prepared.
        </p>

        <div class="flex flex-grow pt-3 pb-3">
            <pre><code class="python rounded-lg">def Encrypt(input,e,n):
	'''
    First, we convert input as a string into its binary representation. Then
    we turn the binary input into Integers, using [2:] to slice off the 0b
    part of the binary. Then we parse the integer number through the formula
    using public keys e and n.
	'''
	input = to_Bin(input)
	for i in range(len(input)):
		input[i] = int(input[i][2:],2)
		input[i] = pow(input[i],e,n)
	return input</code></pre>
        </div>

        <p class="text-white">
            Now we have encrypted data that can be sent to the person who owns the private key. But what happens when
            he receives the message?
        </p>

        <div class="flex flex-grow pt-3 pb-3">
            <pre><code class="python rounded-lg">def Decrypt(input,n,d):
	'''
	First, we use the decryption formula with our public and
	private key.
	'''

	for i in range(len(input)):
		input[i] = pow(input[i],d,n)

	output = ''
	actuall_output = ''

	'''
	We start by changing the input into its binary values.
    Once that is done, we reverse the binary because how
    the format returns our binary would break our code. Then
    we count until we reach the eight-bit and convert it back
    to Unicode and then to its corresponding character. In the end,
    we need to reverse it once again, as the text is backward.
    All the reversing is due to how the python compiler works
    and interprets binary.
	'''

	for i in range(len(input)):
		bin_value = format(input[i], "011b")
		reverse_input = bin_value[::-1]
		reverse_input = str(reverse_input)
		j = 0
		itter = 0
		holder = ''
		while j < len(reverse_input):
			holder += reverse_input[j]
			if len(holder) == 8:
				j = j + 4
				holder = holder[::-1]
				reverse = int(holder,2)
				output += chr(reverse)
				holder = ''
				continue
			j += 1
		holder = holder[::-1]
		reverse = int(holder,2)
		output += chr(reverse)
		actuall_output += output[::-1]
		output = ''
	return actuall_output</code></pre>
        </div>

        <p class="text-white">
            We now have everything we need to try encryption and decryption, so let's see how that looks.
        </p>

        <div class="flex flex-grow pt-3 pb-3">
            <pre><code class="python rounded-lg">string = Normalize_Data('This is my testing string')

p,q,e,n,d = Generate_Keys()

encrypted_message = Encrypt(string,e,n)

decrypted_message = Decrypt(encrypted_message,n,d)

OUTPUT:
public key e:  986992929925166792117763447
public key n:  3784143317985393602170635019
Testing string:  This is my testing string
Encrypted string:  [6201854851823893170291, 2365112509239765706867, 8563074209913585768564, 979693170791]
Decrypted string:  This is my testing string</code></pre>
        </div>

        <p class="text-white pb-3">
            This is the showcase of an <span class="font-bold">EXEMPLARY</span> code for RSA encryption.
            I don't recommend using this code as it is not optimized for production use and was written only to help get
            a better understanding of encryption itself. If you need encryption algorithms, use already-done libraries.
            <br><br> Mixing algorithms together and combining encryption with hashing, salting, and peppering is always
            the best way to keep your data safe. Once you encrypt any plaintext using these algorithms, it is virtually
            impossible for the attacker to decrypt the data. That is what we use for our passwords. We save only
            encrypted passwords into the database, and every time a user logs in, his password is encrypted using the
            same methods. If these passwords match, we know to log him in. If an attacker gets their hands on the
            passwords, the only thing he can see is unusable gibberish. And without knowing what keys, and hashing,
            salting we used, he won't be able to decipher the data.<br>
        </p>

        <p class="text-white pt-3">
            Example of hashing a password using SHA256:
        </p>

        <div class="flex flex-grow pt-3 pb-3">
            <pre><code class="python rounded-lg">from hashlib import sha256

input_ = 'superSecretPassword'
print(sha256(input_.encode('utf-8')).hexdigest())

Hashed password:  ab5c39620a81e237b66bd49554fc94e8eb23a60e99d01c5f3f0b30e8daee230e</code></pre>
        </div>

        <h1 class="text-white font-bold pt-3">Script Download:</h1>

         <p class="text-white pb-3">
            Feel free to try the code yourself.
        </p>

        <div class="bg-gray-700 hover:bg-gray-900 text-white font-bold py-2 px-4 rounded-full inline-flex items-center font-medium">
            <svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"
                 xmlns="http://www.w3.org/2000/svg">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                      d="M9 13.5l3 3m0 0l3-3m-3 3v-6m1.06-4.19l-2.12-2.12a1.5 1.5 0 00-1.061-.44H4.5A2.25 2.25 0 002.25 6v12a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9a2.25 2.25 0 00-2.25-2.25h-5.379a1.5 1.5 0 01-1.06-.44z"></path>
            </svg>
            <button type="submit" class="pl-3"
                    onclick="location.href='{% url 'download_script_rsa' %}'" name='download'>
                RSA
            </button>

        </div>

        <p class="text-white pb-3">
            If you want to better understand RSA encryption you can watch this video from
            <a href="https://www.youtube.com/watch?v=wXB-V_Keiu8" class="font-bold underline">Art of the Problem</a>:
        </p>

        <div class="aspect-w-16 aspect-h-9">
            <iframe width="1263" height="480" src="https://www.youtube.com/embed/wXB-V_Keiu8" title="Public Key Cryptography: RSA Encryption Algorithm" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
        </div>

    </div>
{% endblock %}
</html>