我正在構建一個基於Qt的應用程序,它將通過https與Web服務器進行通信。該設置應允許使用本地證書和私鑰進行客戶端身份驗證。應用程序必須運行,而無需任何用戶交互。防止提示PEM密碼
現在我有一個問題,當私鑰文件被密碼保護:
OpenSSL將提示輸入密碼,阻止整個應用程序!
openSSL API允許傳遞迴調以獲取密碼,但是這不能通過Qt包裝器訪問。是否有另一種方法來防止openSSL提示輸入密碼?或者可以不知何故被打斷?
我正在構建一個基於Qt的應用程序,它將通過https與Web服務器進行通信。該設置應允許使用本地證書和私鑰進行客戶端身份驗證。應用程序必須運行,而無需任何用戶交互。防止提示PEM密碼
現在我有一個問題,當私鑰文件被密碼保護:
OpenSSL將提示輸入密碼,阻止整個應用程序!
openSSL API允許傳遞迴調以獲取密碼,但是這不能通過Qt包裝器訪問。是否有另一種方法來防止openSSL提示輸入密碼?或者可以不知何故被打斷?
我想出了一個解決方案:
OpenSSL的只會提示輸入密碼,當在解碼功能中沒有指定時。正如Richard Moore在他的回答中指出的那樣,QSslKey
有一個構造函數,您可以在其中傳遞密碼。
只要在這裏傳遞非空字符串,OpenSSL就不會提示輸入密碼。另外:如果密鑰不受保護,則的密碼將被忽略。因此,我只是確保一個非空字符串被傳遞,所以這是我的解決方案:
// Never use empty PWD, as this blocks. (Use null-string)
// PLUS: setting a password for a non-protected key still correctly loads the key!
QByteArray thePwd = pwd.isEmpty() ? QByteArray("\0", 1) : pwd.toUtf8();
// Try all encodings
QList<QSslKey> keys = QList<QSslKey>()
<< QSslKey(theKey, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, thePwd)
<< QSslKey(theKey, QSsl::Rsa, QSsl::Der, QSsl::PrivateKey, thePwd)
<< QSslKey(theKey, QSsl::Dsa, QSsl::Pem, QSsl::PrivateKey, thePwd)
<< QSslKey(theKey, QSsl::Dsa, QSsl::Der, QSsl::PrivateKey, thePwd);
// Find a valid encoding
foreach (QSslKey k, keys) {
if (!k.isNull()) {
ret = k;
break;
}
}
在查看online documentation時,解密私鑰時看不到任何回調選項。
最簡單的方法是使密碼免密碼。這裏是你如何能做到這一點(假設你有密碼保護的RSA密鑰):
openssl rsa -in privateKey.pem -out newPrivateKey.pem
這裏privateKey.pem
有密碼保護,但newPrivateKey.pem
不是。請注意,儘管這意味着私鑰是不受保護的,但這是進行不間斷SSL通信的常用技術(例如,甚至在stunnel
中使用)。假設私鑰存儲在具有受限權限的目錄中,並受操作系統訪問策略的保護。
更困難的方法是通過直接與OpenSSL鏈接而不是通過包裝來編寫應用程序。這樣,您就可以對密碼回調進行精細控制。
您可以在構建QSslKey時指定密碼。構造函數將被用於解密密鑰的密碼,請參閱該文檔在下面的鏈接:
我明白我可以在構造函數中傳遞密碼。但是當沒有爲我的應用程序配置密碼時,我遇到了問題,但該文件受到保護。在這種情況下,沒有什麼可以通過,應用程序阻止 –
是的,使用不受保護的PK將解決我的問題。雖然這對網絡服務器來說很常見,但是我的應用程序在客戶端,而且我不能強制要求PK文件不能受到保護...... –
如果私鑰真的存在,您發佈的解決方案如何工作保護?它會假定''thePwd''是密碼,並且會嘗試解密私鑰並且會失敗。 – Karthik
它不會提示輸入密碼,因此該過程不會被阻止。在這種情況下鑰匙不能使用,但是這個過程可以對這種情況作出反應並繼續進行,甚至只是優雅地關閉。否則,我會有一個在I/O上永久封鎖的BG流程 –