2013-09-27 108 views
0

我正在構建一個基於Qt的應用程序,它將通過https與Web服務器進行通信。該設置應允許使用本地證書和私鑰進行客戶端身份驗證。應用程序必須運行,而無需任何用戶交互防止提示PEM密碼

現在我有一個問題,當私鑰文件被密碼保護:
OpenSSL將提示輸入密碼,阻止整個應用程序!

openSSL API允許傳遞迴調以獲取密碼,但是這不能通過Qt包裝器訪問。是否有另一種方法來防止openSSL提示輸入密碼?或者可以不知何故被打斷?

回答

0

我想出了一個解決方案:

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; 
    } 
} 
0

在查看online documentation時,解密私鑰時看不到任何回調選項。

最簡單的方法是使密碼免密碼。這裏是你如何能做到這一點(假設你有密碼保護的RSA密鑰):

openssl rsa -in privateKey.pem -out newPrivateKey.pem

這裏privateKey.pem有密碼保護,但newPrivateKey.pem不是。請注意,儘管這意味着私鑰是不受保護的,但這是進行不間斷SSL通信的常用技術(例如,甚至在stunnel中使用)。假設私鑰存儲在具有受限權限的目錄中,並受操作系統訪問策略的保護。

更困難的方法是通過直接與OpenSSL鏈接而不是通過包裝來編寫應用程序。這樣,您就可以對密碼回調進行精細控制。

+0

是的,使用不受保護的PK將解決我的問題。雖然這對網絡服務器來說很常見,但是我的應用程序在客戶端,而且我不能強制要求PK文件不能受到保護...... –

+0

如果私鑰真的存在,您發佈的解決方案如何工作保護?它會假定''thePwd''是密碼,並且會嘗試解密私鑰並且會失敗。 – Karthik

+0

它不會提示輸入密碼,因此該過程不會被阻止。在這種情況下鑰匙不能使用,但是這個過程可以對這種情況作出反應並繼續進行,甚至只是優雅地關閉。否則,我會有一個在I/O上永久封鎖的BG流程 –

0

您可以在構建QSslKey時指定密碼。構造函數將被用於解密密鑰的密碼,請參閱該文檔在下面的鏈接:

http://qt-project.org/doc/qt-4.8/qsslkey.html#QSslKey-2

+0

我明白我可以在構造函數中傳遞密碼。但是當沒有爲我的應用程序配置密碼時,我遇到了問題,但該文件受到保護。在這種情況下,沒有什麼可以通過,應用程序阻止 –