安全地保存密碼有沒有人有安全的方法來儲存密碼,以便使用者不必每次都輸入密碼?
我不想將密碼以純文字形式儲存在首選項檔案或類似檔案中。
Names default to here(1);
nw = new window("Login",
lineupbox(ncol(2),
textbox("Username"), teb_uid = texteditbox("Vincent", <<SET width=""></SET>回覆:安全保存密碼這是一個使用 powershell 中可用模組的版本,也許這是一個選項?
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'.回覆:安全保存密碼在 Windows 上相信可以使用 JSL 和命令列重新建立此程式碼以與 Windows 憑證管理器交互,但可能是錯誤的。也許有一天我會承擔這個任務;在這裡分享它,以防其他人先弄清楚。 
<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>從kkm這裡:
https://stackoverflow.com/questions/9221245/how-do-i-store-and-retrieve-credentials-from-the-windows-vault-credential-manage
回覆:安全保存密碼你已經幫了很多忙了。謝謝。
回覆:安全保存密碼您可以查看使用 JMP 插件進行加密。 了解運輸加密庫會產生法律和出口影響。 您最好的選擇是編寫一個加載項,呼叫主機作業系統上已有的本機加密庫,然後仍然透過您的法律團隊運行它。
回覆:安全保存密碼我喜歡這個。不幸的是我不能強迫客戶安裝python(有些已經明確禁止他們的用戶安裝它)。但我已經說服大多數人安裝 sqlite odbc 驅動程序,所以也許我可以將其與 MD5 一起使用。
我仍然需要找到某種方法來進行加密。
感謝您的幫助,我確實需要做一些研究。
回覆:安全保存密碼我拿一個混淆式路線。我將字元轉換為數字,然後將這些數字輸入數學公式以產生“加密”表示形式。
我更傾向於將該技術用於軟體許可證代碼而不是用戶密碼。因此,我將採用產品名稱或程式碼與網站 ID 資訊結合,加上到期日期,建立數字表示形式並透過複雜的數學公式對其進行解析:最終輸出可能類似於 1143932720966。
回覆:安全保存密碼在為自己尋找更好的解決方案時發現了這一點。對於我自己機器上的腳本,我呼叫 R 並使用 keyring 函數。它在 Mac 上使用 Keychain,在 Windows 上使用 Credential Store,在 Linux 上使用 Secret Service API。顯然這會帶來開銷,如果沒有 R 就可以做到這一點會很好。如果有興趣,我放一個用於創建這些功能的 JMP 願望清單項目在 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();回覆:安全保存密碼用於建立 sqlite 資料儲存的範例 python 腳本,
#! /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()
回覆:安全保存密碼憑證的安全儲存是一個難題。 要做到正確確實很難。 至少您可能仍然需要使用者在每個工作階段中輸入某種形式的憑證,以防止未經授權使用您試圖保護的秘密。 因此,對於每個“使用者”,您可能需要為其憑證儲存儲存一個密碼。 然後您需要憑證儲存本身。 多安全才夠? 您是否只需要混淆,例如像rot13 這樣的簡單替換密碼(將字母表中的字母移動13,所以m => z、a =>n 或者您是否需要更強大的東西,例如AES 加密或公鑰加密? 您可以使用 JMP 表、文字檔案或資料庫表格建立資料存儲,JMP 具有對資料庫連線的 ODBC 支援。 更好的校驗和和加密支持,可以用 JSL 編寫,也可以透過 JMP 的插件功能或透過 Python 橋從共享庫載入。
保護密碼,
確保密碼檔案安全的傳統方法是使用雜湊函數。 一種方法具有 MD5、SHA 系列、SHA1、SHA256 等函數,所有這些函數都會取得資料並建立一個無法反轉的雜湊值以揭示原始資料。 這個想法是,您獲取想要保護的資料並根據該資料建立哈希值。 通常,此類雜湊值與 SALT 值混合,SALT 值是與密碼資料一起儲存的隨機值。 鹽使得將已知資料的查找表保存為哈希值的成本要高得多。 然後,當使用者輸入密碼時,您對輸入的值進行雜湊處理,並將雜湊值與儲存的值進行比較。如果它們匹配==成功並且密碼通過驗證。 JMP 將 MD5 校驗和公開給 JSL。 從腳本索引中,請參閱 Blob MD5()。 請注意,MD5 用於加密目的對於現代加密技術來說並不安全,但對於低階安全性來說仍然應該沒問題。
然後,您可以使用雜湊值,甚至可以將雜湊值與其他資料結合起來,建立派生雜湊值或 HMAC https://en.wikipedia.org/wiki/HMAC充當受保護資料儲存的密碼密鑰。 有些資料庫具有資料欄位的加密功能,或者您可能需要自己加密資料並儲存在表中。
最後,如果您需要更高的安全性,請查看可以呼叫共享庫的 JMP 插件功能,您可以根據需要實現複雜的資料管理方案。 或者查看 JMP 的 Python 介面,呼叫 Python 套件可以讓您存取 sqlite,以及更好的校驗和和加密方法。
我將如何建構這樣一個資料儲存? 我會嚴重依賴 JMP 的 Python 介面。 sqlite 資料庫支援內建於 Python 中,並將使用該資料庫或 JMP 表作為我的資料儲存。 此外,Python 通常是使用 crypt 支援、校驗和和加密演算法建構的。 我首先建立一個密碼表,其中包含密碼的雜湊值。 然後建立一個資料儲存作為另一個具有加密欄位的表。 到底有多安全,有多複雜,有多少程式碼和多少測試的問題...
回覆:安全保存密碼我想我會嘗試解決這個問題,看看是否有人有任何想法。
因為現在我也遇到了其他類型的秘密的問題。用戶訪問代碼等等。
回覆:安全保存密碼這將使我有權存取所有用戶的密碼。絕對不可行。告訴使用者將密碼儲存為加密腳本也不是可行的選擇。我真的想要一個“記住我”選項,我可以存儲他們以編程方式輸入的任何用戶名/密碼,但該存儲是安全的。
回覆:安全保存密碼建立一個包含關聯數組或清單等中的密碼的腳本。然後將該腳本另存為加密腳本。