secure-credentials-roan 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- secure_credentials_roan-0.1.0/PKG-INFO +55 -0
- secure_credentials_roan-0.1.0/README.md +33 -0
- secure_credentials_roan-0.1.0/pyproject.toml +39 -0
- secure_credentials_roan-0.1.0/secure_credentials/__init__.py +33 -0
- secure_credentials_roan-0.1.0/secure_credentials/crypto.py +150 -0
- secure_credentials_roan-0.1.0/secure_credentials/parser.py +44 -0
- secure_credentials_roan-0.1.0/secure_credentials_roan.egg-info/PKG-INFO +55 -0
- secure_credentials_roan-0.1.0/secure_credentials_roan.egg-info/SOURCES.txt +11 -0
- secure_credentials_roan-0.1.0/secure_credentials_roan.egg-info/dependency_links.txt +1 -0
- secure_credentials_roan-0.1.0/secure_credentials_roan.egg-info/requires.txt +1 -0
- secure_credentials_roan-0.1.0/secure_credentials_roan.egg-info/top_level.txt +1 -0
- secure_credentials_roan-0.1.0/setup.cfg +4 -0
- secure_credentials_roan-0.1.0/tests/test_secure_credential.py +23 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: secure-credentials-roan
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Paquete sencillo para cifrar y descifrar archivos de credenciales
|
|
5
|
+
Author: Angel Rogelio Argonza Roblero
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/TU_USUARIO/secure_credentials_roan
|
|
8
|
+
Project-URL: Repository, https://github.com/TU_USUARIO/secure_credentials_roan
|
|
9
|
+
Project-URL: Issues, https://github.com/TU_USUARIO/secure_credentials_roan/issues
|
|
10
|
+
Keywords: python,credentials,encryption,security,fernet
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Security
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
Requires-Dist: cryptography>=42.0.0
|
|
22
|
+
|
|
23
|
+
# Secure Credentials Roan
|
|
24
|
+
|
|
25
|
+
Paquete de Python para cifrar y descifrar archivos de credenciales con formato clave=valor.
|
|
26
|
+
|
|
27
|
+
## Instalación
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install secure-credentials-roan
|
|
31
|
+
|
|
32
|
+
## Uso básico
|
|
33
|
+
from secure_credentials import create_key_file, encrypt_file, load_credentials
|
|
34
|
+
|
|
35
|
+
create_key_file("secret.key")
|
|
36
|
+
|
|
37
|
+
encrypt_file(
|
|
38
|
+
input_path="credentials.txt",
|
|
39
|
+
output_path="credentials.enc",
|
|
40
|
+
key_path="secret.key",
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
credentials = load_credentials(
|
|
44
|
+
encrypted_path="credentials.enc",
|
|
45
|
+
key_path="secret.key",
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
print(credentials)
|
|
49
|
+
|
|
50
|
+
## Formato del archivo de credenciales
|
|
51
|
+
user=root
|
|
52
|
+
password=mysql_5
|
|
53
|
+
database=automcae
|
|
54
|
+
host=localhost
|
|
55
|
+
port=3306
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Secure Credentials Roan
|
|
2
|
+
|
|
3
|
+
Paquete de Python para cifrar y descifrar archivos de credenciales con formato clave=valor.
|
|
4
|
+
|
|
5
|
+
## Instalación
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install secure-credentials-roan
|
|
9
|
+
|
|
10
|
+
## Uso básico
|
|
11
|
+
from secure_credentials import create_key_file, encrypt_file, load_credentials
|
|
12
|
+
|
|
13
|
+
create_key_file("secret.key")
|
|
14
|
+
|
|
15
|
+
encrypt_file(
|
|
16
|
+
input_path="credentials.txt",
|
|
17
|
+
output_path="credentials.enc",
|
|
18
|
+
key_path="secret.key",
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
credentials = load_credentials(
|
|
22
|
+
encrypted_path="credentials.enc",
|
|
23
|
+
key_path="secret.key",
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
print(credentials)
|
|
27
|
+
|
|
28
|
+
## Formato del archivo de credenciales
|
|
29
|
+
user=root
|
|
30
|
+
password=mysql_5
|
|
31
|
+
database=automcae
|
|
32
|
+
host=localhost
|
|
33
|
+
port=3306
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "secure-credentials-roan"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Paquete sencillo para cifrar y descifrar archivos de credenciales"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
authors = [
|
|
8
|
+
{ name = "Angel Rogelio Argonza Roblero" }
|
|
9
|
+
]
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
keywords = ["python", "credentials", "encryption", "security", "fernet"]
|
|
12
|
+
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 3 - Alpha",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.10",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Topic :: Security",
|
|
21
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
dependencies = [
|
|
25
|
+
"cryptography>=42.0.0"
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
Homepage = "https://github.com/TU_USUARIO/secure_credentials_roan"
|
|
30
|
+
Repository = "https://github.com/TU_USUARIO/secure_credentials_roan"
|
|
31
|
+
Issues = "https://github.com/TU_USUARIO/secure_credentials_roan/issues"
|
|
32
|
+
|
|
33
|
+
[build-system]
|
|
34
|
+
requires = ["setuptools>=68.0.0", "wheel"]
|
|
35
|
+
build-backend = "setuptools.build_meta"
|
|
36
|
+
|
|
37
|
+
[tool.setuptools.packages.find]
|
|
38
|
+
include = ["secure_credentials*"]
|
|
39
|
+
exclude = ["securevenv*", "venv*", ".venv*", "env*", "tests*", "examples*"]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
##########################
|
|
2
|
+
# author: roan #
|
|
3
|
+
# date: 2026/06/25 #
|
|
4
|
+
##########################
|
|
5
|
+
# Propose: Exponer funciones principales del paquete
|
|
6
|
+
|
|
7
|
+
from secure_credentials.crypto import(
|
|
8
|
+
generate_key,
|
|
9
|
+
save_key,
|
|
10
|
+
load_key,
|
|
11
|
+
create_key_file,
|
|
12
|
+
encrypt_text,
|
|
13
|
+
decrypt_text,
|
|
14
|
+
encrypt_file,
|
|
15
|
+
decrypt_file,
|
|
16
|
+
load_credentials
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
from secure_credentials.parser import get_dict
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"generate_key",
|
|
23
|
+
"save_key",
|
|
24
|
+
"load_key",
|
|
25
|
+
"create_key_file",
|
|
26
|
+
"encrypt_text",
|
|
27
|
+
"decrypt_text",
|
|
28
|
+
"encrypt_file",
|
|
29
|
+
"decrypt_file",
|
|
30
|
+
"load_credentials",
|
|
31
|
+
"get_dict",
|
|
32
|
+
|
|
33
|
+
]
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
##########################
|
|
2
|
+
# author: roan #
|
|
3
|
+
# date: 2026/06/24 #
|
|
4
|
+
##########################
|
|
5
|
+
# Propose: Realizar cifrado y descifrado de archivos, generar una llave, guardarla y cargarla
|
|
6
|
+
# Retornar valores cifrados para ser usados
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
from cryptography.fernet import Fernet, InvalidToken
|
|
10
|
+
from secure_credentials.parser import get_dict
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
#Generar llave
|
|
15
|
+
def generate_key() -> bytes:
|
|
16
|
+
#Genera una llave y la regresa para ser guardada
|
|
17
|
+
return Fernet.generate_key()
|
|
18
|
+
|
|
19
|
+
#Guardar llave secreta en un archivo
|
|
20
|
+
def save_key(key: bytes, key_path: str | Path) -> None:
|
|
21
|
+
|
|
22
|
+
#Verificamos si existe la ruta si no se crea
|
|
23
|
+
key_path = Path(key_path)
|
|
24
|
+
key_path.parent.mkdir(parents=True, exist_ok=True)
|
|
25
|
+
|
|
26
|
+
#Guardar la llave en modo binario
|
|
27
|
+
with open(key_path, "wb") as file:
|
|
28
|
+
file.write(key)
|
|
29
|
+
|
|
30
|
+
#Lee la llave secreta desde un archivo
|
|
31
|
+
def load_key(key_path: str | Path) -> bytes:
|
|
32
|
+
|
|
33
|
+
key_path = Path(key_path)
|
|
34
|
+
|
|
35
|
+
#Verificar que existe el path
|
|
36
|
+
if not key_path.exists():
|
|
37
|
+
raise FileNotFoundError (f"No se encontró la llave en la ruta: {key_path}")
|
|
38
|
+
|
|
39
|
+
#Cargar/retornar llave que se leyo del archivo
|
|
40
|
+
with open(key_path, "rb") as f:
|
|
41
|
+
return f.read()
|
|
42
|
+
|
|
43
|
+
#Genera una llave secreta y la guarda en un archivo
|
|
44
|
+
def create_key_file(key_path: str | Path, overwrite: bool = False) -> bytes:
|
|
45
|
+
|
|
46
|
+
key_path = Path(key_path)
|
|
47
|
+
|
|
48
|
+
#Verificar si existe la llave
|
|
49
|
+
if key_path.exists() and not overwrite:
|
|
50
|
+
raise FileExistsError(f"La llave {key_path} ya existe en el sistema, utiliza overrite = True si deseas reemplazarla")
|
|
51
|
+
|
|
52
|
+
#Crear la llave
|
|
53
|
+
key = generate_key()
|
|
54
|
+
|
|
55
|
+
#Guardar la llave
|
|
56
|
+
save_key(key, key_path)
|
|
57
|
+
|
|
58
|
+
return key
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
#Cifrar texto usando la llave Fernet
|
|
62
|
+
def encrypt_text(text: str, key: bytes) -> bytes:
|
|
63
|
+
#Se inicia la instancia de fernet con la llave
|
|
64
|
+
fernet = Fernet(key)
|
|
65
|
+
|
|
66
|
+
#Convertir el texto en bytes
|
|
67
|
+
text_bytes = text.encode("utf-8")
|
|
68
|
+
|
|
69
|
+
#cifrar el contenido
|
|
70
|
+
encrypted_data = fernet.encrypt(text_bytes)
|
|
71
|
+
|
|
72
|
+
return encrypted_data
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
#descifrar datos usando la llave fernet
|
|
76
|
+
def decrypt_text(encrypted_data: bytes, key: bytes) -> str:
|
|
77
|
+
|
|
78
|
+
#Iniciar instancia con la llave
|
|
79
|
+
fernet = Fernet(key)
|
|
80
|
+
|
|
81
|
+
#Se realiza el descifrado
|
|
82
|
+
try:
|
|
83
|
+
#Descifrando datos
|
|
84
|
+
decrypted_data = fernet.decrypt(encrypted_data)
|
|
85
|
+
|
|
86
|
+
#Mensaje de error en caso de que no se pueda descifrar
|
|
87
|
+
except InvalidToken as it:
|
|
88
|
+
raise ValueError(f"No se pudo descifrar el contenido, Verifica que la llave sea la correcta") from it
|
|
89
|
+
|
|
90
|
+
#Devuelve los valores en formato str
|
|
91
|
+
return decrypted_data.decode("utf-8")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
#Lee un archivo de texto, cifra su contenido y guarda el archivo cifrado.
|
|
95
|
+
def encrypt_file(original_file: str | Path, output_file: str | Path, key_path: str | Path) -> None:
|
|
96
|
+
|
|
97
|
+
original_file = Path(original_file)
|
|
98
|
+
#Verificar que existe el archivo que vamos a cifrar
|
|
99
|
+
if not original_file.exists():
|
|
100
|
+
raise FileNotFoundError(f"No se encontró un archivo para cidfrar en {original_file}")
|
|
101
|
+
|
|
102
|
+
#Cargar la llave
|
|
103
|
+
key = load_key(key_path)
|
|
104
|
+
|
|
105
|
+
#Se lee el archivo original como texto
|
|
106
|
+
with open(original_file, "r", encoding="utf-8") as file:
|
|
107
|
+
original_text = file.read()
|
|
108
|
+
|
|
109
|
+
#Cifrar el texto
|
|
110
|
+
encrypted_data = encrypt_text(original_text, key)
|
|
111
|
+
|
|
112
|
+
#Crear la carpeta destino si no existe
|
|
113
|
+
output_file = Path(output_file)
|
|
114
|
+
output_file.parent.mkdir(parents= True, exist_ok=True)
|
|
115
|
+
|
|
116
|
+
#Guardar contenido cifrado en modo binario
|
|
117
|
+
with open(output_file, "wb") as file:
|
|
118
|
+
file.write(encrypted_data)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
#Lee un archivo cifrado y devuelve su contenido descifrado como texto.
|
|
122
|
+
def decrypt_file(encrypted_file: str | Path, key_path: str):
|
|
123
|
+
|
|
124
|
+
#Verificar que el path a descifrar existe
|
|
125
|
+
encrypted_path = Path(encrypted_file)
|
|
126
|
+
|
|
127
|
+
if not encrypted_path.exists():
|
|
128
|
+
raise FileNotFoundError(f"El archivo a decifrar no existe en la ruta {encrypted_path}")
|
|
129
|
+
|
|
130
|
+
#cargar la llave
|
|
131
|
+
key = load_key(key_path)
|
|
132
|
+
|
|
133
|
+
with open(encrypted_path, "rb") as file:
|
|
134
|
+
|
|
135
|
+
data_decrypt = file.read()
|
|
136
|
+
|
|
137
|
+
text = decrypt_text(data_decrypt, key)
|
|
138
|
+
|
|
139
|
+
return text
|
|
140
|
+
|
|
141
|
+
#Descifra un archivo de credenciales y retorna sus valores como diccionario.
|
|
142
|
+
def load_credentials(encrypted_path: str | Path, key_path: str | Path) -> dict [str:str]:
|
|
143
|
+
|
|
144
|
+
#Descifrar el archivo
|
|
145
|
+
decrypted_text = decrypt_file(encrypted_path, key_path)
|
|
146
|
+
|
|
147
|
+
#Formatear credenciales en formato
|
|
148
|
+
credentials = get_dict(decrypted_text)
|
|
149
|
+
|
|
150
|
+
return credentials
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
##########################
|
|
2
|
+
# author: roan #
|
|
3
|
+
# date: 22/06/2026 #
|
|
4
|
+
##########################
|
|
5
|
+
# Propose: Obtener un diccionario de datos para cifrar
|
|
6
|
+
|
|
7
|
+
def get_dict(data_text: str) -> dict [str:str]:
|
|
8
|
+
#Diccionario para organizar los datos clave=valor
|
|
9
|
+
dict_data = {}
|
|
10
|
+
|
|
11
|
+
#Comienza recorriendo linea por linea
|
|
12
|
+
for line_number, linea in enumerate(data_text.splitlines(), start=1):
|
|
13
|
+
#Qutar espacios al inicio y al final
|
|
14
|
+
cleanline = linea.strip()
|
|
15
|
+
|
|
16
|
+
#Ignorar las lineas vacias
|
|
17
|
+
if not cleanline:
|
|
18
|
+
continue
|
|
19
|
+
|
|
20
|
+
#Ignoramos lineas con comentarios
|
|
21
|
+
if cleanline.startswith("#"):
|
|
22
|
+
continue
|
|
23
|
+
|
|
24
|
+
#Validar el formato de linea
|
|
25
|
+
if "=" not in cleanline:
|
|
26
|
+
raise ValueError(f"La línea {line_number} no contiene el formato clave=valor: {cleanline}")
|
|
27
|
+
|
|
28
|
+
#Obtener clave valor de la cadena
|
|
29
|
+
key, value = cleanline.split("=")
|
|
30
|
+
|
|
31
|
+
#Limpiar espacios
|
|
32
|
+
keyClean = key.strip()
|
|
33
|
+
valueClean = value.strip()
|
|
34
|
+
|
|
35
|
+
#Validar que la clave no este vacia
|
|
36
|
+
if not keyClean:
|
|
37
|
+
raise ValueError(f"La linea {linea} tiene una clave vacia")
|
|
38
|
+
|
|
39
|
+
#Retornar diccionario listo para cifrar los datos
|
|
40
|
+
dict_data[keyClean] = valueClean
|
|
41
|
+
|
|
42
|
+
return dict_data
|
|
43
|
+
|
|
44
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: secure-credentials-roan
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Paquete sencillo para cifrar y descifrar archivos de credenciales
|
|
5
|
+
Author: Angel Rogelio Argonza Roblero
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/TU_USUARIO/secure_credentials_roan
|
|
8
|
+
Project-URL: Repository, https://github.com/TU_USUARIO/secure_credentials_roan
|
|
9
|
+
Project-URL: Issues, https://github.com/TU_USUARIO/secure_credentials_roan/issues
|
|
10
|
+
Keywords: python,credentials,encryption,security,fernet
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Security
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
Requires-Dist: cryptography>=42.0.0
|
|
22
|
+
|
|
23
|
+
# Secure Credentials Roan
|
|
24
|
+
|
|
25
|
+
Paquete de Python para cifrar y descifrar archivos de credenciales con formato clave=valor.
|
|
26
|
+
|
|
27
|
+
## Instalación
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install secure-credentials-roan
|
|
31
|
+
|
|
32
|
+
## Uso básico
|
|
33
|
+
from secure_credentials import create_key_file, encrypt_file, load_credentials
|
|
34
|
+
|
|
35
|
+
create_key_file("secret.key")
|
|
36
|
+
|
|
37
|
+
encrypt_file(
|
|
38
|
+
input_path="credentials.txt",
|
|
39
|
+
output_path="credentials.enc",
|
|
40
|
+
key_path="secret.key",
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
credentials = load_credentials(
|
|
44
|
+
encrypted_path="credentials.enc",
|
|
45
|
+
key_path="secret.key",
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
print(credentials)
|
|
49
|
+
|
|
50
|
+
## Formato del archivo de credenciales
|
|
51
|
+
user=root
|
|
52
|
+
password=mysql_5
|
|
53
|
+
database=automcae
|
|
54
|
+
host=localhost
|
|
55
|
+
port=3306
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
secure_credentials/__init__.py
|
|
4
|
+
secure_credentials/crypto.py
|
|
5
|
+
secure_credentials/parser.py
|
|
6
|
+
secure_credentials_roan.egg-info/PKG-INFO
|
|
7
|
+
secure_credentials_roan.egg-info/SOURCES.txt
|
|
8
|
+
secure_credentials_roan.egg-info/dependency_links.txt
|
|
9
|
+
secure_credentials_roan.egg-info/requires.txt
|
|
10
|
+
secure_credentials_roan.egg-info/top_level.txt
|
|
11
|
+
tests/test_secure_credential.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cryptography>=42.0.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
secure_credentials
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
##########################
|
|
2
|
+
# author: roan #
|
|
3
|
+
# date: 2026/06/24 #
|
|
4
|
+
##########################
|
|
5
|
+
# Propose: test
|
|
6
|
+
|
|
7
|
+
import unittest
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from secure_credentials.parser import get_dict
|
|
10
|
+
from secure_credentials.crypto import save_key
|
|
11
|
+
|
|
12
|
+
BASE_DIR = Path(__file__).resolve().parent
|
|
13
|
+
|
|
14
|
+
class TestSecureCredential(unittest.TestCase):
|
|
15
|
+
|
|
16
|
+
#Prueba de lectura de archivos
|
|
17
|
+
def test_readfile(self):
|
|
18
|
+
path_file = BASE_DIR / "secret.txt"
|
|
19
|
+
|
|
20
|
+
dict = get_dict(path_file)
|
|
21
|
+
|
|
22
|
+
def test_save_key(self):
|
|
23
|
+
save_key()
|