2012-07-09 75 views
5

我做了一些涉及自動提交表單和/或從網站檢索數據的項目。其中一些網站需要用戶名/密碼認證。 (這些網站不具備的API,所以我依靠屏幕抓取。)我可以通過編程方式登錄到網站而不用以明文形式存儲密碼嗎?

大多數我見過存儲在源代碼中的用戶名和密碼,像任何其他POST數據的教程,例如:

string username = "someUserName"; 
string password = "somePassword"; 
// submit POST data... 

但我知道以純文本存儲密碼通常是皺眉。我應該使用另一種方法嗎?

回答

3

存儲密碼的常見方法是對其進行散列處理。由於大多數用於散列密碼的算法都具有破壞性,也就是說它們不可逆轉,所以這對您不起作用。

一個選項是使用可逆的散列,比如base64對密碼進行編碼,但它並不比以純文本存儲更安全。

就我所見,最好的解決方案是將密碼存儲在數據庫中。如果您真的擔心有人獲取用戶名和密碼,您可以使用encryption functions在數據庫中加密它們,或者您可以使用SQLite數據庫,您可以直接在磁盤上加密。

這樣你的代碼和登錄憑證是分開的,你可以安全地與別人分享你的代碼,而不必擔心安全問題。

+0

雖然這不是真正的加密。如果腳本可以獲取明文密碼,那麼任何有權限的人都可以運行它。 – pguardiario 2012-07-10 00:30:14

+0

你不能真正與加密爭論。如果它被加密,則它被加密。我的意思是,你可以將密碼與代碼分開,並將它們(加密)存儲在數據庫中,但只能通過主密碼使其可用。 OP如何決定處理主密碼完全取決於他。例如。在啓動時提示用戶輸入主密碼會阻止對密碼的未授權訪問。當然,「任何有權運行它的人」都可以,但這並不意味着訪問密碼。 – jurgemaister 2012-07-10 06:20:34

+0

嗯,提示輸入密碼是好的,但問題是如何存儲密碼。使用「主密碼」確實會增加一些不必要的複雜性,並且就加密而言......我看不出您希望從rot13或您使用的任何可逆方案獲得什麼保護。如果我可以運行腳本,我可以看到密碼。 – pguardiario 2012-07-10 06:42:33

0

加密和解密的一個非常簡單的方法是extended tiny encription algorithm (XTEA)。我在這裏粘貼維基百科的C++代碼,但請記住任何人都可以在那裏改變它。

#include <stdint.h> 

/* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */ 

void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) { 
    unsigned int i; 
    uint32_t v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9; 
    for (i=0; i < num_rounds; i++) { 
     v0 += (((v1 << 4)^(v1 >> 5)) + v1)^(sum + key[sum & 3]); 
     sum += delta; 
     v1 += (((v0 << 4)^(v0 >> 5)) + v0)^(sum + key[(sum>>11) & 3]); 
    } 
    v[0]=v0; v[1]=v1; 
} 

void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) { 
    unsigned int i; 
    uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds; 
    for (i=0; i < num_rounds; i++) { 
     v1 -= (((v0 << 4)^(v0 >> 5)) + v0)^(sum + key[(sum>>11) & 3]); 
     sum -= delta; 
     v0 -= (((v1 << 4)^(v1 >> 5)) + v1)^(sum + key[sum & 3]); 
    } 
    v[0]=v0; v[1]=v1; 
} 
+0

在什麼意義上?該算法是否易於打破? – sashoalm 2012-07-09 09:19:58

+1

感興趣:http://security.stackexchange.com/questions/3241/thoughts-on-tiny-encryption-algorithm-tea-anyone – Jacco 2012-07-09 09:38:00

+0

謝謝,我讀了鏈接。我知道TEA不是很安全,但我認爲XTEA修復了這個問題。直到我讀到其中一個答案時,我才知道XXTEA。但無論如何,OP還是需要以某種方式將密碼存儲在自己的計算機中,以便它能夠正常工作,所以無論使用哪種算法,它都會產生內在的不安全感。 – sashoalm 2012-07-09 09:58:11

0

你必須做兩兩件事:正確收到後
1.使用HTTPS登錄頁面(如有必要)
2.使用密碼加密。編碼器是這樣的:

private static String passwordEncryption(String oldPass){ 
    String newPass = ""; 
    try { 
     MessageDigest messageDigest = MessageDigest.getInstance("MD5"); 
     messageDigest.update(oldPass.getBytes(), 0, oldPass.length()); 
     newPass = new BigInteger(1,messageDigest.digest()).toString(16); 
     if (newPass.length() < 32) { 
      newPass = "0" + newPass; 
     } 
     return newPass; 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 
    return newPass; 

} 


並使用MD5()中MySql功能接收到的密碼與存儲的一個比較。

+0

在MySQL端使用'MD5()'是不好的建議:明文密碼可能會在日誌文件中結束。 – Jacco 2012-07-09 09:14:46

0

我們採用的模式是:

在你的數據庫表中你有加密列。此列包含使用系統範圍的長(128位)隨機密鑰(通常存儲在配置文件中)加密的數據。 此加密列中的數據包含用於每個第三方服務的單獨(隨機)密鑰。使用此密碼,我們會加密與此第三方服務相關的驗證詳細信息。

爲什麼這個雙重加密?

您可以將純文本密碼的數量減少爲一個密碼(系統範圍的密碼)。正因爲如此,密鑰管理更容易。 我們爲每個第三方服務創建一個長隨機密鑰,以便我們可以有選擇地解密每個第三方服務的憑證,並在必要時在系統之間傳輸它們。將我們的密鑰之一存儲在數據庫之外還可以降低與SQL注入攻擊(它們只'獲取數據庫數據)和備份(配置文件不包含在常規備份數據中)相關的風險。

弱點顯然是整個系統的密碼。它需要存儲在某個地方。

我不是密碼學家,我敢肯定上述是不是最理想的。然而,它的工作原理,可管理性和安全性遠遠超過僅以純文本格式存儲第三方服務憑證。

0

有沒有辦法做到這一點。它將需要以純文本(或「可逆加密」)的形式提供給腳本。

許多Apis(包括亞馬遜網絡服務)將推薦在環境變量中設置證書,這可能與您所希望的一樣安全。

把它放在你的.bash_profile中,仔細檢查perrmissions,至少你可以確定它不會在github上公開回購。

1

我有一個需要解決此問題的抓取項目。我的設置包括兩臺獨立的服務器第一個是用戶前端Web應用程序。第二個是處理抓取的nodejs服務器。

我使用openssl密鑰對加密來處理加密。我爲nodejs機器生成密鑰對,並將公鑰發送給前端Web應用程序。當用戶註冊他們的第三方證書時,這些證書將使用公鑰加密並存儲在數據庫中。

Web應用程序會定期選擇用戶的加密憑證,並將它們發送到節點服務器,並使用私鑰解密並與第三方一起使用進行刮取。

經過快速搜索,我找到this關於使用openssl和加密字符串的文章。

我意識到這是一個很舊的帖子,但希望它可以幫助下一個人發現這個問題。

+0

嗨!的確,這幫助了我!但是,您如何確保沒有人能夠訪問您的私鑰? – nicolasdaudin 2017-04-20 14:48:47

相關問題