guardar contraseñas de forma segura¿Alguien tiene una forma segura de almacenar contraseñas para que los usuarios no tengan que ingresarla cada vez?
No quiero simplemente almacenar la contraseña como texto sin formato en un archivo de preferencias ni nada por el estilo.
Names default to here(1);
nw = new window("Login",
lineupbox(ncol(2),
textbox("Username"), teb_uid = texteditbox("Vincent", <<SET width=""></SET>Re: guardar contraseñas de forma seguraAquí hay una versión que usa un módulo disponible en powershell, ¿tal vez esa sea una opción?
Names default to here(1);
loadmodule = "
if (!(Get-Module -ListAvailable -Name CredentialManager)) {
Install-Module CredentialManager -force -Scope CurrentUser
}
";
//Function to run command in powershell, strips trailing line breaks
RunPowershell = Function( {command},
Regex(RunProgram(
Executable( "powershell.exe" ),
Options( {"/c", command } ),
ReadFunction( "text" )
), "^(.*?)[\r\n]+$", "\1")
);
// Set password
SetPass = Function( {target,user,pass},
RunPowershell(
"$target = '" || target || "'
$usr = '" || user || "'
$pswd = '" || pass || "'
" || loadmodule || "
New-StoredCredential -Target $target -UserName $usr -Password $pswd"
);
1; //password is returned as free text, don't return the response
);
// Get password
GetPass = Function( {target},
RunPowershell(
"$target = '" || target || "'
" || loadmodule || "
$creds = Get-StoredCredential -Target $target
$creds.GetNetworkCredential().Password"
)
);
// Get username
GetUser = Function( {target},
RunPowershell(
"$target = '" || target || "'
" || loadmodule || "
$creds = Get-StoredCredential -Target $target
$creds.GetNetworkCredential().UserName"
)
);
// Set and retrieve credentials
SetPass("testcredential", "myusername3", "mypassword3");
GetPass("testcredential");
GetUser("testcredential");
//You can delete these test credentials using the 'windows credential store'.Re: guardar contraseñas de forma seguraEn Windows I creer Este código podría recrearse con JSL y la línea de comando para interactuar con el administrador de credenciales de Windows podría estar incorrecta.Quizás algún día me haga cargo de esto; compartiéndolo aquí en caso de que alguien más lo descubra primero. 
<SPAN class="com">#include</SPAN> <SPAN class="str"><WINDOWS.H></WINDOWS.H></SPAN>
<SPAN class="com">#include</SPAN> <SPAN class="str"><WINCRED.H></WINCRED.H></SPAN>
<SPAN class="com">#include</SPAN> <SPAN class="str"><TCHAR.H></TCHAR.H></SPAN>
<SPAN class="com">#pragma</SPAN><SPAN class="pln"> hdrstop
</SPAN><SPAN class="kwd">void</SPAN><SPAN class="pln"> main </SPAN><SPAN class="pun">()</SPAN>
<SPAN class="pun">{</SPAN>
<SPAN class="pun">{</SPAN> <SPAN class="com">//--- SAVE</SPAN>
<SPAN class="kwd">char</SPAN><SPAN class="pun">*</SPAN><SPAN class="pln"> password </SPAN><SPAN class="pun">=</SPAN> <SPAN class="str">"brillant"</SPAN><SPAN class="pun">;</SPAN><SPAN class="pln"> DWORD cbCreds </SPAN><SPAN class="pun">=</SPAN> <SPAN class="lit">1</SPAN> <SPAN class="pun">+</SPAN><SPAN class="pln"> strlen</SPAN><SPAN class="pun">(</SPAN><SPAN class="pln">password</SPAN><SPAN class="pun">);</SPAN><SPAN class="pln">
CREDENTIALW cred </SPAN><SPAN class="pun">=</SPAN> <SPAN class="pun">{</SPAN><SPAN class="lit">0</SPAN><SPAN class="pun">};</SPAN><SPAN class="pln"> cred</SPAN><SPAN class="pun">.</SPAN><SPAN class="typ">Type</SPAN> <SPAN class="pun">=</SPAN><SPAN class="pln"> CRED_TYPE_GENERIC</SPAN><SPAN class="pun">;</SPAN><SPAN class="pln"> cred</SPAN><SPAN class="pun">.</SPAN><SPAN class="typ">TargetName</SPAN> <SPAN class="pun">=</SPAN><SPAN class="pln"> L</SPAN><SPAN class="str">"FOO/account"</SPAN><SPAN class="pun">;</SPAN><SPAN class="pln"> cred</SPAN><SPAN class="pun">.</SPAN><SPAN class="typ">CredentialBlobSize</SPAN> <SPAN class="pun">=</SPAN><SPAN class="pln"> cbCreds</SPAN><SPAN class="pun">;</SPAN><SPAN class="pln"> cred</SPAN><SPAN class="pun">.</SPAN><SPAN class="typ">CredentialBlob</SPAN> <SPAN class="pun">=</SPAN> <SPAN class="pun">(</SPAN><SPAN class="pln">LPBYTE</SPAN><SPAN class="pun">)</SPAN><SPAN class="pln"> password</SPAN><SPAN class="pun">;</SPAN><SPAN class="pln"> cred</SPAN><SPAN class="pun">.</SPAN><SPAN class="typ">Persist</SPAN> <SPAN class="pun">=</SPAN><SPAN class="pln"> CRED_PERSIST_LOCAL_MACHINE</SPAN><SPAN class="pun">;</SPAN><SPAN class="pln"> cred</SPAN><SPAN class="pun">.</SPAN><SPAN class="typ">UserName</SPAN> <SPAN class="pun">=</SPAN><SPAN class="pln"> L</SPAN><SPAN class="str">"paula"</SPAN><SPAN class="pun">;</SPAN><SPAN class="pln">
BOOL ok </SPAN><SPAN class="pun">=</SPAN> <SPAN class="pun">::</SPAN><SPAN class="typ">CredWriteW</SPAN> <SPAN class="pun">(&</SPAN><SPAN class="pln">cred</SPAN><SPAN class="pun">,</SPAN> <SPAN class="lit">0</SPAN><SPAN class="pun">);</SPAN><SPAN class="pln"> wprintf </SPAN><SPAN class="pun">(</SPAN><SPAN class="pln">L</SPAN><SPAN class="str">"CredWrite() - errno %d\n"</SPAN><SPAN class="pun">,</SPAN><SPAN class="pln"> ok </SPAN><SPAN class="pun">?</SPAN> <SPAN class="lit">0</SPAN> <SPAN class="pun">:</SPAN> <SPAN class="pun">::</SPAN><SPAN class="typ">GetLastError</SPAN><SPAN class="pun">());</SPAN>
<SPAN class="kwd">if</SPAN> <SPAN class="pun">(!</SPAN><SPAN class="pln">ok</SPAN><SPAN class="pun">)</SPAN> <SPAN class="kwd">exit</SPAN><SPAN class="pun">(</SPAN><SPAN class="lit">1</SPAN><SPAN class="pun">);</SPAN>
<SPAN class="pun">}</SPAN>
<SPAN class="pun">{</SPAN> <SPAN class="com">//--- RETRIEVE</SPAN><SPAN class="pln"> PCREDENTIALW pcred</SPAN><SPAN class="pun">;</SPAN><SPAN class="pln"> BOOL ok </SPAN><SPAN class="pun">=</SPAN> <SPAN class="pun">::</SPAN><SPAN class="typ">CredReadW</SPAN> <SPAN class="pun">(</SPAN><SPAN class="pln">L</SPAN><SPAN class="str">"FOO/account"</SPAN><SPAN class="pun">,</SPAN><SPAN class="pln"> CRED_TYPE_GENERIC</SPAN><SPAN class="pun">,</SPAN> <SPAN class="lit">0</SPAN><SPAN class="pun">,</SPAN> <SPAN class="pun">&</SPAN><SPAN class="pln">pcred</SPAN><SPAN class="pun">);</SPAN><SPAN class="pln"> wprintf </SPAN><SPAN class="pun">(</SPAN><SPAN class="pln">L</SPAN><SPAN class="str">"CredRead() - errno %d\n"</SPAN><SPAN class="pun">,</SPAN><SPAN class="pln"> ok </SPAN><SPAN class="pun">?</SPAN> <SPAN class="lit">0</SPAN> <SPAN class="pun">:</SPAN> <SPAN class="pun">::</SPAN><SPAN class="typ">GetLastError</SPAN><SPAN class="pun">());</SPAN>
<SPAN class="kwd">if</SPAN> <SPAN class="pun">(!</SPAN><SPAN class="pln">ok</SPAN><SPAN class="pun">)</SPAN> <SPAN class="kwd">exit</SPAN><SPAN class="pun">(</SPAN><SPAN class="lit">1</SPAN><SPAN class="pun">);</SPAN><SPAN class="pln"> wprintf </SPAN><SPAN class="pun">(</SPAN><SPAN class="pln">L</SPAN><SPAN class="str">"Read username = '%s', password='%S' (%d bytes)\n"</SPAN><SPAN class="pun">,</SPAN><SPAN class="pln">
pcred</SPAN><SPAN class="pun">-></SPAN><SPAN class="typ">UserName</SPAN><SPAN class="pun">,</SPAN> <SPAN class="pun">(</SPAN><SPAN class="kwd">char</SPAN><SPAN class="pun">*)</SPAN><SPAN class="pln">pcred</SPAN><SPAN class="pun">-></SPAN><SPAN class="typ">CredentialBlob</SPAN><SPAN class="pun">,</SPAN><SPAN class="pln"> pcred</SPAN><SPAN class="pun">-></SPAN><SPAN class="typ">CredentialBlobSize</SPAN><SPAN class="pun">);</SPAN>
<SPAN class="com">// must free memory allocated by CredRead()!</SPAN>
<SPAN class="pun">::</SPAN><SPAN class="typ">CredFree</SPAN> <SPAN class="pun">(</SPAN><SPAN class="pln">pcred</SPAN><SPAN class="pun">);</SPAN>
<SPAN class="pun">}</SPAN>
<SPAN class="pun">}</SPAN>De kkm aquí:
https://stackoverflow.com/questions/9221245/how-do-i-store-and-retrieve-credentials-from-the-windows-vault-credential-manage
Re: guardar contraseñas de forma seguraHas sido más que útil.Gracias.
Re: guardar contraseñas de forma seguraPuede considerar realizar cifrado utilizando un complemento JMP. Comprenda que enviar una biblioteca de cifrado tiene ramificaciones legales y de exportación. Su mejor opción sería escribir un complemento que llame a las bibliotecas de cifrado nativas que ya están en el sistema operativo host y luego ejecutarlo ante su equipo legal.
Re: guardar contraseñas de forma seguraMe gusta esto.Desafortunadamente, no puedo obligar a los clientes a instalar Python (algunos han prohibido explícitamente a sus usuarios instalarlo).Pero he convencido a la mayoría de instalar el controlador sqlite odbc, así que tal vez pueda usarlo con MD5.
Todavía tendría que encontrar alguna manera de cifrar.
Gracias por la ayuda, definitivamente tengo que investigar un poco.
Re: guardar contraseñas de forma seguratomo un ruta de estilo ofuscación.Convierto caracteres en números y luego introduzco estos números en una fórmula matemática para generar una representación "cifrada".
Tiendo a utilizar la técnica más para códigos de licencia de software que para contraseñas de usuario.Entonces, tomaré el nombre o código de un producto combinado con la información de identificación del sitio, más una fecha de vencimiento, construiré una representación numérica y la analizaré a través de una fórmula matemática compleja: el resultado final podría ser algo así como 1143932720966.
Re: guardar contraseñas de forma seguraEncontré esto mientras buscaba una mejor solución para mí.Para scripts en mi propia máquina, llamo a R y uso la función de conjunto de claves.Utiliza Keychain en Mac, Credential Store en Windows y la API del Servicio Secreto en Linux.Obviamente esto viene con gastos generales, sería bueno hacerlo sin R.Si te interesa pongo un Elemento de la lista de deseos de JMP para crear estas funciones en JMP.
https://github.com/r-lib/keyring
R Init();
R Submit(
"library(keyring)
pw <- keyring::key_get(\!"DomainAccount\!", \!"username\!")"
);
pw = R Get("pw");
R Term();Re: guardar contraseñas de forma seguraScript de Python de muestra para crear un almacén de datos SQLite,
#! /usr/bin/env/python3
#
# Author: Paul Nelson - JMP Statistical Discovery, From SAS
# Date: 9 Mar 2020
#
# Description: This sample shows the python code using sqlite to create a data data store
# for saving passwords, credentails... While Python has hash functions, the standard library
# does not include ciphers. For purposes of this sample I used lzma compression to 'encode' and
# decompression to 'decrypt' For use from JSL, I would turn this into a python module and then
# import 'my_dataStore_api' to cut down code in the JSL string.
#
# sample python program using sqlite to create a secure store for passwords and
# key, value data storage.
#
# While Python contains hash functions, does not include encryption primitives in the standard library.
# an example using PyCrypto can be found
# https://stackoverflow.com/questions/12524994/encrypt-decrypt-using-pycrypto-aes-265
# however pycrypto has no been updated since 2014... https://github.com/dlitz/pycrypto
#
# pyca/cryptography - https://cryptography.io/ https://github.com/pyca/cryptography
# seems to be currently maintained.
#
# Don't create your own encryption! The above packages or, openssl, or many other providers are
# better than writing your own.
#
# It is an exercise left to the reader to replace the code using lzma compression with real encrypt
# and decrypt code.
#
#
import sqlite3
import hashlib
import os
from pathlib import Path
import lzma
# Salt should be random quantity, get from OS entropy source
salt = os.urandom(16);
mypasswd = b'JMP in a dried up lake'
dk = hashlib.pbkdf2_hmac('sha256', mypasswd, salt, 1000)
# dk.hex() will be the actual hashed password saved to db
# but the binary dk, will be what we use as the encryption key
# dkhex = dk.hex()
# binDk = bytes.fromhex(dkhex)
#
# Path to my credential store , my home directory + AppData
data_path = str(Path.home()) + '/AppData/'
filename = 'dataStore'
# Create directory if it doesn't exist
os.makedirs(data_path, exist_ok=True)
# will create database if it doesn't exist
db = sqlite3.connect(data_path + filename + '.db')
# my username
me = 'jmpuser'
# create our password table storing hashed passwords
db.execute('CREATE TABLE IF NOT EXISTS passwd (uid INTEGER PRIMARY KEY, name TEXT, salt TEXT, key TEXT)')
# should check to see if user is in database and only insert if not found
# exercise left to the reader
db.execute("INSERT INTO passwd (name, salt, key) VALUES( ?,?,? ) ", (me, salt.hex(), dk.hex()) )
db.commit()
print('******* passwd database *******')
for row in db.execute('SELECT * from passwd'):
print(row)
print('*******************************')
# create our credentials table which will store the name of the credential, and its value
db.execute('CREATE TABLE IF NOT EXISTS credentials (id INTEGER PRIMARY KEY, uid INTEGER, key TEXT, value TEXT)')
# first we need to have validated that user gave propper password, and we authenticated against passwd
# table assuming user is authenticated
# should check to see if user is in database and only insert if not found, potentially update if found
# exercise left to the reader.
# my user id in this scheme
id = 0
#The value data I'm going to store into the database
myson1 = """
{
user: paul
magic_key: JMP Rocks!
}"""
myson2 = """
{
user: paul
magic_key: supercalifragilisticexpialidocious
}"""
# 'encrypt' my data
lvalue = lzma.compress( myson2.encode() )
lvalue2 = lzma.compress( myson1.encode() )
# you could encrypt the 'key' as well as the value if you really want security
db.execute("INSERT INTO credentials (uid, key, value) VALUES( ?,?,? ) ", (id, 'JMPCommunity', lvalue.hex()) )
db.execute("INSERT INTO credentials (uid, key, value) VALUES( ?,?,? ) ", (id, 'WDW', lvalue2.hex()) )
db.commit()
print('******* credentials database *******')
for row in db.execute('SELECT * from credentials WHERE uid=?', (id,) ):
print(row)
value = bytes.fromhex(row[3])
print(lzma.decompress(value).decode())
print('************************************')
db.close()
Re: guardar contraseñas de forma seguraEl almacenamiento seguro de credenciales es una cuestión difícil. Es realmente difícil hacerlo bien. Como mínimo, es probable que aún necesite que el usuario ingrese algún tipo de credencial una vez por sesión, para evitar el uso no autorizado de los secretos que intenta proteger. Entonces, para cada 'usuario' probablemente necesitará almacenar una contraseña para su almacén de credenciales. Entonces necesitas el almacén de credenciales. ¿Qué tan seguro es suficiente? ¿Solo necesita ofuscación, como un cifrado de sustitución simple como rot13 (cambie las letras del alfabeto en 13 para que m => z, a =>n o necesite algo más potente como el cifrado AES o el cifrado de clave pública? Puede crear su almacén de datos utilizando una tabla JMP, un archivo de texto o una tabla de base de datos. JMP tiene soporte ODBC para la conectividad de la base de datos. Mejores sumas de verificación y soporte de cifrado, ya sea escrito en JSL o cargado desde bibliotecas compartidas a través de la capacidad complementaria de JMP o mediante el puente Python.
Proteger contraseñas,
Una forma tradicional de mantener seguros los archivos de contraseñas es utilizar una función hash. Una forma tiene funciones como MD5, la familia SHA, SHA1, SHA256, ... todas toman datos y crean un hash que no se puede revertir para revelar los datos originales. La idea es tomar los datos que desea proteger y crear un hash a partir de los datos. Por lo general, estos hashes se mezclan con un valor SALT, un valor aleatorio que se almacena con los datos de la contraseña. La sal hace que sea mucho más costoso mantener tablas de búsqueda de datos conocidos en valores hash. Luego, cuando el usuario escribe la contraseña, aplica un hash al valor ingresado y lo compara con el valor almacenado.Si coinciden == éxito y contraseña validada. JMP expone la suma de comprobación MD5 a JSL. En el índice de secuencias de comandos, consulte Blob MD5(). Tenga en cuenta que el uso de MD5 con fines criptográficos no es seguro contra las técnicas criptográficas modernas, pero para un nivel de seguridad bajo aún debería estar bien.
Luego, puede usar el hash o incluso combinar el hash con datos adicionales para crear un hash derivado o HMAC. https://en.wikipedia.org/wiki/HMAC para actuar como clave de contraseña para su almacén de datos protegido. Algunas bases de datos tienen funcionalidad de cifrado para campos de datos, o es posible que usted tenga que cifrar los datos usted mismo y almacenarlos en la tabla.
Por último, si necesita mayor seguridad, observe la funcionalidad complementaria de JMP que puede llamar a bibliotecas compartidas, donde podría implementar un esquema de administración de datos tan complejo como desee. O mire la interfaz Python de JMP, llamar a los paquetes Python puede brindarle acceso a sqlite y mejores sumas de verificación y métodos de cifrado.
¿Cómo haría para construir un almacén de datos de este tipo? Me apoyaría mucho en la interfaz Python de JMP. El soporte de la base de datos sqlite está integrado en Python y usaría eso o tablas JMP para mi almacén de datos. Además, Python generalmente se construye con soporte de criptas, sumas de verificación y algoritmos de cifrado. Primero comenzaría creando una tabla de contraseñas que tenga un hash de las contraseñas. Luego cree un almacén de datos como otra tabla que tenga campos cifrados. Qué tan seguro, qué complicado, es una cuestión de cuánto código y cuántas pruebas...
Re: guardar contraseñas de forma seguraPensé en intentar modificar esto para ver si alguien tiene alguna idea.
Porque ahora también tengo problemas con otro tipo de secretos.Códigos de acceso de usuario y demás.
Re: guardar contraseñas de forma seguraEso implicaría que tuviera acceso a las contraseñas de todos los usuarios.Definitivamente no es factible.Y decirle a un usuario que guarde su contraseña como un script cifrado tampoco es una opción viable.Realmente quiero una opción "recordarme" donde pueda almacenar cualquier nombre de usuario/contraseña que escriban mediante programación, pero ese almacenamiento sea seguro.
Re: guardar contraseñas de forma seguraCree un script que contenga las contraseñas... en matrices asociativas, o en listas, etc. Luego guarde ese script como un script cifrado.