Pular para conteúdo

RSA

Source code in rsa/core/RSA.py
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
class RSA:
    def __init__(self, key_size: int = 1024):
        self.key_size = key_size

    def __generate_private_exp(self, phi: int, public_exp: int) -> int:
        """
        Método privado para calcular o valor do expoente privado.

        Arguments:
            phi (int): O valor do Totiente de Euler para 'n'
            public_exp (int): O expoente público

        Returns:
            O valor do expoente privado
        """
        jbr = JBR(mod=phi)
        d = jbr.invMod(num=public_exp)
        return d

    def der_public_key(self, public_infos: Dict[str, int]) -> str:
        """
        Método estático utilizado para converter as informações da chave pública par o formato DER

        Arguments:
            public_infos (Dict[str, int]): Um dicionário com as informações da chave pública

        Returns:
            Um hexadecimal com a chave codificada com DER
        """
        pub_key = PublicKey()

        pub_key['modulus'] = public_infos['n']
        pub_key['public_expoent'] = public_infos['e']

        public_key_encode = encode(pub_key)

        return public_key_encode.hex()

    def der_private_key(self, private_infos: Dict[str, int]) -> str:
        """
        Método estático utilizado para converter as informações da chave privada para o formato DER

        Arguments:
            private_infos (Dict[str, int]): Um dicionário com as informações da chave privada

        Returns:
           Um hexadecimal com a chave codificada com DER
        """
        priv_key = PrivateKey()

        priv_key['modulus'] = private_infos['n']
        priv_key['private_expoent'] = private_infos['d']
        priv_key['p'] = private_infos['p']
        priv_key['q'] = private_infos['q']
        priv_key['phi'] = private_infos['phi']

        private_key_encode = encode(priv_key)

        return private_key_encode.hex()

    def generate_keys(self, public_exp: int = 65537) -> Tuple[str, str]:
        """
        Método utilizado para gerar as chaves pública e privada do RSA.

        Arguments:
            public_exp (int): O valor para o expoente público

        Returns:
            Tuple[str, str]: Os pares de chaves pública e privada, codificadas em hexadecimal.
        """

        # Gera números primos
        p = generate_prime(nbit=self.key_size)
        q = generate_prime(nbit=self.key_size)

        n = p * q  # Calcula o módulo
        phi = (p - 1) * (q - 1)

        e = public_exp  # TODO: Adicionar verificação via MDC;

        d = self.__generate_private_exp(
            phi=phi, public_exp=e
        )  # Calcula o expoente privado

        # Converte chaves para o formato DER
        public_key = self.der_public_key(public_infos={'e': e, 'n': n})
        private_key = self.der_private_key(
            private_infos={'d': d, 'n': n, 'p': p, 'q': q, 'phi': phi}
        )

        # TODO: estudar o retorno de um dict ao invés de tupla
        return private_key, public_key

    def cript(self, public_key: str, msg: str) -> int:
        """
        Método utilizado para realizar a cifração de uma mensagem

        Attributes:
            public_key (str): Uma string hexadecimal com a chave codificada em DER
            msg (str): A mensagem que se deseja cifrar

        Returns:
            O Criptograma resultante da cifração
        """
        # Converte a mensagem para hexadecimal
        msg_to_hex = msg.encode().hex()
        _pub_key = bytes.fromhex(public_key)

        try:
            pub_key, _ = decode(_pub_key, asn1Spec=PublicKey())
        except PyAsn1Error:
            log.error('A chave não está no formato DER esperado!')
            raise PyAsn1Error('A chave não está no formato DER esperado!')

        public_exp, mod = (
            int(pub_key['public_expoent']),
            int(pub_key['modulus']),
        )

        return pow(base=int(msg_to_hex, 16), exp=public_exp, mod=mod)

    def dcript(self, private_key: str, criptogram: int) -> str:
        """
        Método utilizado para realizar a decifração de um criptograma

        Attributes:
            private_key (str): Uma string hexadecimal com a chave codificada em DER
            criptogram (int): O Criptograma que se deseja decifrar

        Returns:
            O texto plano
        """
        _priv_key = bytes.fromhex(private_key)

        try:
            priv_key, _ = decode(_priv_key, asn1Spec=PrivateKey())
        except PyAsn1Error:
            log.error('A chave não está no formato DER esperado!')
            raise PyAsn1Error('A chave não está no formato DER esperado!')

        private_exp, mod = (
            int(priv_key['private_expoent']),
            int(priv_key['modulus']),
        )

        msg_dcript = pow(base=criptogram, exp=private_exp, mod=mod)
        msg_to_hex = hex(msg_dcript)[2:]

        return bytes.fromhex(msg_to_hex).decode()

__generate_private_exp(phi, public_exp)

Método privado para calcular o valor do expoente privado.

Parameters:

Name Type Description Default
phi int

O valor do Totiente de Euler para 'n'

required
public_exp int

O expoente público

required

Returns:

Type Description
int

O valor do expoente privado

Source code in rsa/core/RSA.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def __generate_private_exp(self, phi: int, public_exp: int) -> int:
    """
    Método privado para calcular o valor do expoente privado.

    Arguments:
        phi (int): O valor do Totiente de Euler para 'n'
        public_exp (int): O expoente público

    Returns:
        O valor do expoente privado
    """
    jbr = JBR(mod=phi)
    d = jbr.invMod(num=public_exp)
    return d

cript(public_key, msg)

Método utilizado para realizar a cifração de uma mensagem

Attributes:

Name Type Description
public_key str

Uma string hexadecimal com a chave codificada em DER

msg str

A mensagem que se deseja cifrar

Returns:

Type Description
int

O Criptograma resultante da cifração

Source code in rsa/core/RSA.py
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
def cript(self, public_key: str, msg: str) -> int:
    """
    Método utilizado para realizar a cifração de uma mensagem

    Attributes:
        public_key (str): Uma string hexadecimal com a chave codificada em DER
        msg (str): A mensagem que se deseja cifrar

    Returns:
        O Criptograma resultante da cifração
    """
    # Converte a mensagem para hexadecimal
    msg_to_hex = msg.encode().hex()
    _pub_key = bytes.fromhex(public_key)

    try:
        pub_key, _ = decode(_pub_key, asn1Spec=PublicKey())
    except PyAsn1Error:
        log.error('A chave não está no formato DER esperado!')
        raise PyAsn1Error('A chave não está no formato DER esperado!')

    public_exp, mod = (
        int(pub_key['public_expoent']),
        int(pub_key['modulus']),
    )

    return pow(base=int(msg_to_hex, 16), exp=public_exp, mod=mod)

dcript(private_key, criptogram)

Método utilizado para realizar a decifração de um criptograma

Attributes:

Name Type Description
private_key str

Uma string hexadecimal com a chave codificada em DER

criptogram int

O Criptograma que se deseja decifrar

Returns:

Type Description
str

O texto plano

Source code in rsa/core/RSA.py
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
def dcript(self, private_key: str, criptogram: int) -> str:
    """
    Método utilizado para realizar a decifração de um criptograma

    Attributes:
        private_key (str): Uma string hexadecimal com a chave codificada em DER
        criptogram (int): O Criptograma que se deseja decifrar

    Returns:
        O texto plano
    """
    _priv_key = bytes.fromhex(private_key)

    try:
        priv_key, _ = decode(_priv_key, asn1Spec=PrivateKey())
    except PyAsn1Error:
        log.error('A chave não está no formato DER esperado!')
        raise PyAsn1Error('A chave não está no formato DER esperado!')

    private_exp, mod = (
        int(priv_key['private_expoent']),
        int(priv_key['modulus']),
    )

    msg_dcript = pow(base=criptogram, exp=private_exp, mod=mod)
    msg_to_hex = hex(msg_dcript)[2:]

    return bytes.fromhex(msg_to_hex).decode()

der_private_key(private_infos)

Método estático utilizado para converter as informações da chave privada para o formato DER

Parameters:

Name Type Description Default
private_infos Dict[str, int]

Um dicionário com as informações da chave privada

required

Returns:

Type Description
str

Um hexadecimal com a chave codificada com DER

Source code in rsa/core/RSA.py
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
def der_private_key(self, private_infos: Dict[str, int]) -> str:
    """
    Método estático utilizado para converter as informações da chave privada para o formato DER

    Arguments:
        private_infos (Dict[str, int]): Um dicionário com as informações da chave privada

    Returns:
       Um hexadecimal com a chave codificada com DER
    """
    priv_key = PrivateKey()

    priv_key['modulus'] = private_infos['n']
    priv_key['private_expoent'] = private_infos['d']
    priv_key['p'] = private_infos['p']
    priv_key['q'] = private_infos['q']
    priv_key['phi'] = private_infos['phi']

    private_key_encode = encode(priv_key)

    return private_key_encode.hex()

der_public_key(public_infos)

Método estático utilizado para converter as informações da chave pública par o formato DER

Parameters:

Name Type Description Default
public_infos Dict[str, int]

Um dicionário com as informações da chave pública

required

Returns:

Type Description
str

Um hexadecimal com a chave codificada com DER

Source code in rsa/core/RSA.py
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
def der_public_key(self, public_infos: Dict[str, int]) -> str:
    """
    Método estático utilizado para converter as informações da chave pública par o formato DER

    Arguments:
        public_infos (Dict[str, int]): Um dicionário com as informações da chave pública

    Returns:
        Um hexadecimal com a chave codificada com DER
    """
    pub_key = PublicKey()

    pub_key['modulus'] = public_infos['n']
    pub_key['public_expoent'] = public_infos['e']

    public_key_encode = encode(pub_key)

    return public_key_encode.hex()

generate_keys(public_exp=65537)

Método utilizado para gerar as chaves pública e privada do RSA.

Parameters:

Name Type Description Default
public_exp int

O valor para o expoente público

65537

Returns:

Type Description
Tuple[str, str]

Tuple[str, str]: Os pares de chaves pública e privada, codificadas em hexadecimal.

Source code in rsa/core/RSA.py
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
def generate_keys(self, public_exp: int = 65537) -> Tuple[str, str]:
    """
    Método utilizado para gerar as chaves pública e privada do RSA.

    Arguments:
        public_exp (int): O valor para o expoente público

    Returns:
        Tuple[str, str]: Os pares de chaves pública e privada, codificadas em hexadecimal.
    """

    # Gera números primos
    p = generate_prime(nbit=self.key_size)
    q = generate_prime(nbit=self.key_size)

    n = p * q  # Calcula o módulo
    phi = (p - 1) * (q - 1)

    e = public_exp  # TODO: Adicionar verificação via MDC;

    d = self.__generate_private_exp(
        phi=phi, public_exp=e
    )  # Calcula o expoente privado

    # Converte chaves para o formato DER
    public_key = self.der_public_key(public_infos={'e': e, 'n': n})
    private_key = self.der_private_key(
        private_infos={'d': d, 'n': n, 'p': p, 'q': q, 'phi': phi}
    )

    # TODO: estudar o retorno de um dict ao invés de tupla
    return private_key, public_key