パスワードを安全に保存するユーザーが毎回パスワードを入力する必要がないようにパスワードを保存する安全な方法を持っている人はいますか?
パスワードを単純に環境設定ファイルなどにプレーンテキストとして保存したくありません。
Names default to here(1);
nw = new window("Login",
lineupbox(ncol(2),
textbox("Username"), teb_uid = texteditbox("Vincent", <<SET width=""></SET>Re: パスワードを安全に保存するこれは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'.Re: パスワードを安全に保存するWindows では I信じるこのコードは 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
Re: パスワードを安全に保存する十分以上に役に立ちました。ありがとう。
Re: パスワードを安全に保存するJMP アドインを使用して暗号化を実行することを検討できます。 暗号化ライブラリの出荷には法的影響と輸出上の影響があることを理解してください。 最善の策は、ホスト OS 上にすでに存在するネイティブ暗号化ライブラリを呼び出すアドインを作成し、法務チームを通過させて実行することです。
Re: パスワードを安全に保存する私はこれが好きです。残念ながら、顧客に Python のインストールを強制することはできません (ユーザーに Python のインストールを明示的に禁止しているところもあります)。しかし、私はほとんどの人に sqlite odbc ドライバーをインストールするよう説得したので、それを MD5 で使用できるかもしれません。
暗号化を行う方法を見つける必要があります。
助けてくれてありがとう、私には確かにやるべき研究がいくつかある。
Re: パスワードを安全に保存する私は難読化スタイルのルート。文字を数値に変換し、これらの数値を数式に入力して「暗号化された」表現を生成します。
私はこのテクニックをユーザー パスワードよりもソフトウェア ライセンス コードに使用することが多いです。そこで、サイト ID 情報と有効期限を組み合わせた製品名またはコードを取得し、数値表現を構築し、複雑な数式を通じてそれを解析します。最終出力は 1143932720966 のようなものになる可能性があります。
Re: パスワードを安全に保存する自分にとってより良い解決策を探していたときにこれを見つけました。自分のマシン上のスクリプトの場合は、R を呼び出してキーリング関数を使用します。Mac ではキーチェーン、Windows では認証情報ストア、Linux ではシークレット サービス 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();Re: パスワードを安全に保存する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()
Re: パスワードを安全に保存する資格情報を安全に保管することは難しい問題です。 正しく行うのは本当に難しいです。 少なくとも、保護しようとしているシークレットの不正使用を防ぐために、ユーザーはセッションごとに 1 回何らかの形式の資格情報を入力する必要がある可能性があります。 したがって、「ユーザー」ごとに、資格情報ストアのパスワードを保存する必要がある可能性があります。 次に、資格情報ストア自体が必要になります。 どれくらい安全であれば十分ですか? rot13 (アルファベットの文字を 13 ずつシフトして m => z、a => n にする) のような単純な置換暗号のような難読化だけが必要ですか、それとも AES 暗号化や公開キー暗号化などのより強力な暗号が必要ですか? JMP テーブル、テキスト ファイル、またはデータベース テーブルを使用してデータ ストアを作成できます。JMP にはデータベース接続用の ODBC サポートがあります。 チェックサムと暗号化のサポートが強化され、JSL で記述されるか、JMP のアドイン機能または Python ブリッジを介して共有ライブラリからロードされます。
パスワードの保護、
パスワード ファイルを安全に保つ従来の方法は、ハッシュ関数を使用することでした。 1 つの方法には、MD5、SHA ファミリ、SHA1、SHA256 などの関数があり、すべてデータを取得し、元のデータを明らかにするために元に戻すことはできないハッシュを作成します。 考え方としては、保護したいデータを取得し、そのデータからハッシュを作成するということです。 通常、このようなハッシュは、パスワード データとともに保存されるランダムな値である 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 は通常、暗号化サポート、チェックサム、および暗号化アルゴリズムを使用して構築されています。 まず、パスワードのハッシュを含むパスワード テーブル テーブルを作成することから始めます。 次に、暗号化されたフィールドを持つ別のテーブルとしてデータ ストアを構築します。 どれだけ安全か、どれだけ複雑か、どれだけのコードとどれだけのテストが必要か...
Re: パスワードを安全に保存する誰かが何かアイデアを持っているかどうかを確認するために、これを試してみようと思いました。
なぜなら、今私は他の種類のシークレットにも問題を抱えているからです。ユーザーアクセスコードなど。
Re: パスワードを安全に保存するこれには、すべてのユーザーのパスワードにアクセスする必要があります。絶対に無理です。また、ユーザーにパスワードを暗号化されたスクリプトとして保存するように指示することも実行可能なオプションではありません。私は、ユーザーがプログラムで入力したユーザー名/パスワードを保存できる「記憶する」オプションが本当に欲しいのですが、そのストレージは安全です。
Re: パスワードを安全に保存する連想配列やリストなどにパスワードを含むスクリプトを作成します。次に、そのスクリプトを暗号化されたスクリプトとして保存します。