RSA blokový převod – Python – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

RSA blokový převod – Python – Fórum – Programujte.comRSA blokový převod – Python – Fórum – Programujte.com

 

Paragoon20
Newbie
24. 11. 2023   #1
-
0
-

 Potřeboval bych pomoct snažim se pro RSA šifrovaní, aby fungovalo misto šifrovaní po znacích tak bude šifrovat bloky, pro jeden blok mi převod funguje, ale pokud se vytvoří další tak převod nefunguje a nevím jak to opravit

def text_to_numeric_binary_blocks(text):
    block_size = 10
    numeric_decimal_blocks = []

    for i in range(0, len(text), block_size):
        block = text[i:i + block_size]
        numeric_decimal_block = int(''.join(format(ord(char), '010b') for char in block), 2)
        numeric_decimal_blocks.append(numeric_decimal_block)

    numeric_binary_blocks = [format(block, '010b') for block in numeric_decimal_blocks]

    # Join binary blocks into a single string without separators
    binary_representation = ''.join(numeric_binary_blocks)

    return numeric_decimal_blocks, binary_representation

def numeric_to_text_binary_blocks(numeric_decimal_blocks, block_size):
    # Convert each numeric block to a string and then concatenate them
    numeric_representation = ''.join(map(str, numeric_decimal_blocks))

    # Convert the combined string to an integer
    numeric_representation = int(numeric_representation)

    # Convert the integer to binary representation
    binary_representation = format(numeric_representation, 'b')

    # Pad the binary representation to ensure a multiple of block_size for ASCII conversion
    binary_representation = binary_representation.rjust(((len(binary_representation) + block_size - 1) // block_size) * block_size, '0')

    # Split the binary representation into blocks of size block_size
    binary_blocks = [binary_representation[i:i + block_size] for i in range(0, len(binary_representation), block_size)]

    # Convert each block back to an integer and then to its ASCII character
    text = ''.join(chr(int(block, 2)) for block in binary_blocks)

    # Remove any extra null characters at the end
    text = text.rstrip('\x00')

    return text, numeric_decimal_blocks

def test_conversion(message):
    numeric_decimal_blocks, binary_representation = text_to_numeric_binary_blocks(message)
    converted_text, _ = numeric_to_text_binary_blocks(numeric_decimal_blocks, 10)

    print(f"Original message: {message}")
    print(f"Numeric Decimal Blocks: {numeric_decimal_blocks}")
    print(f"ASCII Values: {[ord(char) for char in message]}")
    print(f"Binary Blocks: {binary_representation}")
    print(f"Converted message: {converted_text}")

if __name__ == "__main__":
    test_conversion("1234567890")
    test_conversion("12345678901")


Nahlásit jako SPAM
IP: 178.20.142.–
gna
~ Anonymní uživatel
1864 příspěvků
25. 11. 2023   #2
-
+1
-
Zajímavé

Před spojováním těch bloků musíš zajistit, aby všechny měly stejnou délku, jinak se ti je nepodaří správně rozdělit.

Ty konverze na inty a stringy jsou všechny blbě. Na implementaci samotného RSA můžeš použít inty, ale do ničeho jiného je nemíchej a zpracovávej to jako binární bloky.

Nahlásit jako SPAM
IP: 213.211.51.–
Paragoon20
Newbie
25. 11. 2023   #3
-
0
-

#2 gna

 Už jsem to opravil a přidal prvky šifrovaní, jen někdy výstup se spravně dešifruje a někdy ne. A funguje jen pro 8 bity, ale chtěl bych, aby fungoval i pro č,ě,ř což je 9 bitu ale nevím jak to udělat. Nevíte prosím?

import random
from math import gcd
from sympy import mod_inverse, isprime

class SimpleRSA:
    def __init__(self):
        self.public_key = None
        self.private_key = None

    def generate_keypair(self):
        if self.public_key is not None and self.private_key is not None:
            return

        p = self.generate_large_prime()
        q = self.generate_large_prime()

        n = p * q
        phi = (p - 1) * (q - 1)

        e = random.randint(2, phi - 1)
        while gcd(e, phi) != 1:
            e = random.randint(2, phi - 1)

        d = mod_inverse(e, phi)

        self.public_key = (n, e)
        self.private_key = (n, d)

        return self.public_key, self.private_key

    def generate_large_prime(self):
        lower_limit = 10 ** 11
        upper_limit = 10 ** 12
        potential_prime = random.randint(lower_limit, upper_limit)
        while not isprime(potential_prime):
            potential_prime = random.randint(lower_limit, upper_limit)
        return potential_prime

    def encrypt(self, message):
        n, e = self.public_key
        binary_blocks = self.text_to_numeric_binary_blocks(message)

        print(f"binary_blocks: {binary_blocks}")

        encrypted_blocks = [pow(int(block, 2), e, n) for block in binary_blocks]

        print(f"encrypted_blocks: {encrypted_blocks}")

        return encrypted_blocks

    def decrypt(self, encrypted_blocks):
        n, d = self.private_key

        decrypted_blocks = [format(pow(block, d, n), '0b') for block in encrypted_blocks]

        print(f"decrypted_blocks: {decrypted_blocks}")

        decrypted_message = self.numeric_to_text_binary_blocks(decrypted_blocks)

        print(f"decrypted_message: {decrypted_message}")

        return decrypted_message


    def text_to_numeric_binary_blocks(self, text, block_size=10):
        binary_blocks = [
            ''.join(format(ord(char), '08b') for char in text[i:i + block_size]).rjust(block_size * 8, '0')
            for i in range(0, len(text), block_size)
        ]
        return binary_blocks

    def numeric_to_text_binary_blocks(self, binary_blocks):
        bytes_list = [int(block, 2).to_bytes((len(block) + 7) // 8, 'big') for block in binary_blocks]
        text = b''.join(bytes_list).decode(errors='replace')
        return text


def test_encryption_decryption(message):
    rsa = SimpleRSA()
    public_key, private_key = rsa.generate_keypair()

    print(f"Original message: {message}")

    # Encryption
    encrypted_blocks = rsa.encrypt(message)
    print(f"Encrypted blocks: {encrypted_blocks}")

    # Decryption
    decrypted_message = rsa.decrypt(encrypted_blocks)
    print(f"Decrypted message: {decrypted_message}")

if __name__ == "__main__":

    test_encryption_decryption("Hello Wolr")



Nahlásit jako SPAM
IP: 178.20.142.–
remmidemmi0
Věrný člen
25. 11. 2023   #4
-
0
-

chyba bude asi v tom šifrovacím a dešifrovacím kliči, ne? Umí ten klíč zpracovat 9-bitové znaky? Nebo to je tak, že 9.bit odkazuje na tabulku speciálních 8-bitových znaků kde je č ěř ... ? V tom případě nutno tomu šifrovacímu klíči nejprve říci v které tabulce má hledat.

Viděl jsi někdy slovník japonských kanji znaků? To jsou stovky stran tabulek. Na každé straně je tabulka se znaky. Každý znak (japonsky se nazývají "kanji") má různé čtení a různé významy. Představ si, že je máš dešifrovat. Musíš tomu dešifrátoru říci nejprve v které tabulce má hledat. Potom, když dešifrátor najde tu tabulku, musíš mu říci kód znaku ( to je těch tvých 8 bitů). Potom ten dešifrátor vybere správný znak.

A když už jsem u tohoto, dešifrování po písmenech je hloupost, Šifruj po slovech. Dívej se na slova, že to jsou "znaky" obdoba japonských kanji. Písmen je sotva 30, ale slov, tedy znaků jsou tisíce a mnoho z nich má různý význam. Pravděpodobnost náhodného dešifrování, nalezení klíče, se významně zmenší.

Nahlásit jako SPAM
IP: 37.48.33.–
gna
~ Anonymní uživatel
1864 příspěvků
26. 11. 2023   #5
-
0
-

Ty konverze na binární stringy jsou k ničemu, ale budiž...

Kóduj to po bajtech, ne po znacích, aby se ti to vešlo do těch 8 bitů.

Místo rjust dej ljust, protože s tím pak pracuješ jako big-endian intem, tak ať to zarovnání máš na konci.

Použij kratší bloky, nebo uprav generovaní klíčů pro větší.

def text_to_numeric_binary_blocks(self, text, block_size=8):
    text = text.encode()
    binary_blocks = [
        ''.join(format(byte, '08b') for byte in text[i:i + block_size]).ljust(block_size * 8, '0')
        for i in range(0, len(text), block_size)
    ]
    return binary_blocks

def numeric_to_text_binary_blocks(self, binary_blocks, block_size=8):
    bytes_list = [int(block, 2).to_bytes(block_size, 'big') for block in binary_blocks]
    text = b''.join(bytes_list).decode(errors='replace').rstrip("\x00")
    return text
Nahlásit jako SPAM
IP: 213.211.51.–
Paragoon20
Newbie
26. 11. 2023   #6
-
0
-

#5 gna
zase děkujiii moooc, cele dny jsem na to nemohl přijit, ale už mi to funguje podle toho.

Nahlásit jako SPAM
IP: 178.20.142.–
Paragoon20
Newbie
26. 11. 2023   #7
-
0
-

#6 Paragoon2
#5 gna
Pro délku 8 znaku to funguje.Jen mam striktně zadaný že block_size musí být po 10 a klíč musí mít lower_limit = 10 ** 11 upper_limit = 10 ** 12

Nahlásit jako SPAM
IP: 178.20.142.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 3 hosté

Podobná vlákna

Pomoc s sifrovani RSA — založil C# zacatecnik

C++ prevod z M/s na KM/H — založil defender

C# převod — založil Pavel Suchý

Prevod z VB6 do C# — založil maxpower

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý