今天我們將脫離密碼學,轉來認識一個新的主題使用權控制(access control)
當中有兩大章節,其內容可以用以下問題來囊括:
我們先花一些時間來講個認證的東西
這邊談的認證主要是講人與機器的互動
比方說一個叫Alice的人要如何說服一台機器,或是伺服器,正在操作的使用者就是Alice本人,而且是越安全越好
機器要有一套機制讓Trudy不能偽裝成Alice
一般的認證手法可大致分成三種:
以下我們來談談密碼的儲存
有關密碼的複雜程度與安全性我們留到明天再講
這邊講一下一般的登入程序系統如何做驗證
當用戶註冊帳戶資訊時,其密碼資訊也被儲存於資料庫中
你可能會想登入程序之需將此次登入的密碼明文與資料庫做比對即可
但直接將密碼明文存在資料庫是相當不安全的事情
因此實務上我們存在資料庫中的不是密碼本人,而是雜湊過後的密碼
以下是一段用Flask來建立的用戶註冊介面的函數
@bp.route('/register', methods=('GET', 'POST'))
def register():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
db = get_db()
error = None
if not username:
error = 'Username is required.'
elif not password:
error = 'Password is required.'
if error is None:
try:
db.execute(
"INSERT INTO user (username, password) VALUES (?, ?)",
(username, generate_password_hash(password)),
)
db.commit()
except db.IntegrityError:
error = f"User {username} is already registered."
else:
return redirect(url_for("auth.login"))
flash(error)
return render_template('auth/register.html')
可以看到generate_password_hash(password)))
在將用戶資料寫入資料庫時,會將密碼經過雜湊後再存入
如此一來,第三方即使成功攻擊資料庫,他也無法利用雜湊過的密碼進行登入
用戶登入時,我們也只會檢查輸入密碼的雜湊值是否與資料庫一致,並非比較密碼明文
check_password_hash(user['password'], password)
因此理論上,你可以用不同於原本密碼明文的其他字串登入,只要該字串與註冊時用的密碼雜湊值相等即可
不過由於加密雜湊函數的性質,雖然那種字串存在非常多,要找到是不可能的
今天短短講了點認證的東西
再次強調這邊講的認證是「人」與機器的互動
等到安全協議再講認證時,就變成「機器」與「機器」的互動,或是「客戶端」與「伺服器」的互動
其問題就會變得相當複雜了
明天又是數學時間,來算算密碼空間的安全性