2016-04-15 215 views
1

在使用SQLite的移動Java應用程序中將密碼哈希到SHA1的最佳方式是什麼?用Java哈希密碼

以下是如何將數據插入到數據庫中。我想要密碼被散列,最好在SHA1中。它將被用於在另一個頁面上登錄,所以我需要在那個java類中做類似的過程嗎?

SignUp.Java

public void onSignUpClick(View v) { 
     if (v.getId() == R.id.Bsignupbutton) { 
      EditText name = (EditText) findViewById(R.id.TFname); 
      EditText email = (EditText) findViewById(R.id.TFemail); 
      EditText uname = (EditText) findViewById(R.id.TFuname); 
      EditText pass1 = (EditText) findViewById(R.id.TFpass1); 
      EditText pass2 = (EditText) findViewById(R.id.TFpass2); 
      String namestr = name.getText().toString(); 
      String emailstr = email.getText().toString(); 
      String unamestr = uname.getText().toString(); 
      String pass1str = pass1.getText().toString(); 
      String pass2str = pass2.getText().toString(); 
      if (!pass1str.equals(pass2str)) { 
       //popup msg 
       Toast pass = Toast.makeText(SignUp.this, "Passwords don't match!", Toast.LENGTH_SHORT); 
       pass.show(); 
      } else { 
       if (name.getText().toString().length() == 0) { 
        name.setError("Name Required"); 
       } else if (!email.getText().toString().matches("[a-zA-Z]{1}\\.[a-zA-Z]*[0-9]{4}@student\\.leedsbeckett\\.ac\\.uk")) { 
        email.setError("Incorrect Email Format"); 
       } else if (!uname.getText().toString().matches("[cC][0-9]{7}")) { 
        uname.setError("Incorrect ID Format"); 
       } else if (!pass1.getText().toString().matches("(?=.*[\\d])(?=.*[a-z])(?=.*[A-Z]).{8,}")) { 
        pass1.setError("Incorrect Password Format"); 
       } else { 
        //insert the details in database 
        Contact c = new Contact(); 
        c.setName(namestr); 
        c.setEmail(emailstr); 
        c.setUname(unamestr); 
        c.setPass(pass1str); 
        helper.insertContact(c); 
        Toast pass = Toast.makeText(SignUp.this, "User Registered", Toast.LENGTH_LONG); 
        pass.show(); 
        Intent i = new Intent(SignUp.this, com.example.oliver.beckettreg.MainActivity.class); 
        startActivity(i); 
       } 
      } 
     } 
    } 

回答

1

你不應該創造自己的散列和鹽析機制。

看JBCrypt - Java實現BCrypt的:

http://www.mindrot.org/projects/jBCrypt/

的API是非常簡單的:

// Hash a password for the first time 
String hashed = BCrypt.hashpw(password, BCrypt.gensalt()); 

// gensalt's log_rounds parameter determines the complexity 
// the work factor is 2**log_rounds, and the default is 10 
String hashed = BCrypt.hashpw(password, BCrypt.gensalt(12)); 

// Check that an unencrypted password matches one that has 
// previously been hashed 
if (BCrypt.checkpw(candidate, hashed)) 
    System.out.println("It matches"); 
else 
    System.out.println("It does not match"); 
+1

這應該是一條評論。 – tnw

0

採取阿帕奇百科全書編解碼庫的用途。

https://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/digest/DigestUtils.html#sha1Hex(java.lang.String)

final String SALT = "any strange string that you like"; 

String mySha1String = DigestUtils.sha1Hex(myString + SALT); 

對於數據庫的目的,你不應該改變的鹽,這樣,SHA1會不一樣,以相同的字符串作爲輸入。另一件事,不會更好地使用SHA-3?最好的標準?

0

它將被用於在另一個頁面上登錄,所以我需要在那個java類中做類似的過程嗎?

是的,當檢查密碼是否有效時,您將不得不復制散列過程。密碼的關鍵在於它們使用單​​向散列(使用salt)存儲在數據庫中,這樣如果有人惡意獲取密碼散列,他們就無法從散列中獲取原始密碼(在理論)。通過這種方式,密碼哈希算法與加密算法有所不同,因爲一旦原始密碼被哈希(即加密),您並不關心密碼的原始值,這意味着不需要哈希算法,該算法可以是反轉(解密)通常導致更強的密碼。

爲了更明確地回答你的問題,在你的登錄類(或你的密碼檢查的任何地方),一旦用戶給你他們的密碼,你將需要再次哈希(使用相同的算法和相同的鹽)並測試該哈希是否與存儲在數據庫中的密碼哈希匹配。

至於哈希本身,正如Jason指出的那樣,您不應該實現您自己的算法版本,因爲您肯定會由於這種算法的複雜性而犯錯誤。你應該找一些實現你需要的包。