Does anyone have a secure way to store passwords so users don't have to enter their password every time?
I don't want to just store the password as plain text in a preferences file or anything like that.
Names default to here(1);
nw = new window("Login",
lineupbox(ncol(2),
textbox("Username"), teb_uid = texteditbox("Vincent", <<Set Width(200)),
textbox("Password"), teb_pwd = texteditbox("thisisapassword", <<Width(200), <<Password Style(1))
),
cb_save = checkbox({"Remember Me"}),
buttonbox("OK",
uid = teb_uid << Get Text();
pwd = teb_pwd << Get Text();
nw << close window();
)
);
On Windows I believe this code could be re-created with JSL and the command line to interact with the windows credential manager, could be wrong. Maybe someday I will take this on; sharing it here in case someone else figures it out first. :)
#include <windows.h>
#include <wincred.h>
#include <tchar.h>
#pragma hdrstop
void main ()
{
{ //--- SAVE
char* password = "brillant"; DWORD cbCreds = 1 + strlen(password);
CREDENTIALW cred = {0}; cred.Type = CRED_TYPE_GENERIC; cred.TargetName = L"FOO/account"; cred.CredentialBlobSize = cbCreds; cred.CredentialBlob = (LPBYTE) password; cred.Persist = CRED_PERSIST_LOCAL_MACHINE; cred.UserName = L"paula";
BOOL ok = ::CredWriteW (&cred, 0); wprintf (L"CredWrite() - errno %d\n", ok ? 0 : ::GetLastError());
if (!ok) exit(1);
}
{ //--- RETRIEVE PCREDENTIALW pcred; BOOL ok = ::CredReadW (L"FOO/account", CRED_TYPE_GENERIC, 0, &pcred); wprintf (L"CredRead() - errno %d\n", ok ? 0 : ::GetLastError());
if (!ok) exit(1); wprintf (L"Read username = '%s', password='%S' (%d bytes)\n",
pcred->UserName, (char*)pcred->CredentialBlob, pcred->CredentialBlobSize);
// must free memory allocated by CredRead()!
::CredFree (pcred);
}
}From kkm here:
Here is a version that uses an available module in powershell, maybe that is an option?
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'.
I take an obfuscation-style route. I convert characters to numbers, then feed these numbers into a mathematical formula to generate an 'encrypted' representation.
I tend to use the technique more for software license codes rather than user passwords. So I will take a product name or code combined with site ID information, plus an expiry date, build a numeric representation and parse that through a complex mathematical formula: the final output might be something like 1143932720966.