2013-04-08 184 views
0

我想写一个密码加密类,我可以用它来加密和存储用户密码。我想确保我正确地做到了这一点。此代码工作正常,似乎生成一个加密的密码,但我想在这里发布,以获得一些反馈。对我而言,这是相当复杂的,并且我知道加密中的任何事情,在没有意识到你正在制造它们的情况下很容易犯错。密码加密

这里是我的代码:

public CipherHandler { 

     public String encryptPassword(char[] plaintext, String encoding) throws Exception { 

      MessageDigest msgDigest = null; 
      String hashValue = null; 

      /* Convert char array plaintext to byte array */ 
      byte[] b = new byte[plaintext.length << 1]; 
      for (int i = 0; i < plaintext.length; i++) { 
       b[i] = (byte) plaintext[i]; //will this work regardless of encoding? 
      } 

      try { 
       msgDigest = MessageDigest.getInstance("SHA-256"); 
       msgDigest.update(b); 
       byte rawByte[] = msgDigest.digest(); 
       hashValue = (new BASE64Encoder()).encode(rawByte); 
      } catch (NoSuchAlgorithmException e) { 
       System.out.println("No Such Algorithm Exists"); 
      } 

      System.out.println(hashValue); 
      return hashValue; 
     }    
    } 

此功能一般会从Swing事件处理程序在用户输入密码进入JPassword场,这就是为什么我开始用炭称为[] 。为了测试,我使用此代码来调用该函数:

CipherHandler cp = new CipherHandler(); 
String initPW; 
try { 
    initPW = cp.encryptPassword("welcome".toCharArray(), "UTF-8"); 
} 

由于这是我第一次尝试,我想,我忽略了一些东西。我对感兴趣建议或意见。我有几个具体的问题,虽然:

  1. 当我的char []转换成一个byte [],我不相信,我正确地做这个。我如何知道使用哪种编码?在这里,我放置了“UTF-8”,主要是作为占位符,但我担心在某些情况下这可能会失败。

  2. 我已经读过,我应该在密码被消化后使用盐和迭代,但我无法弄清楚如何做到这一点。有人可以请教我这个吗?

  3. 我正在使用SHA-256。这是建议的算法吗?我也读过关于MD5的内容。是否有一种算法适用于密码加密?

感谢您的任何帮助。我很感激!

+3

参见[如何安全地散列密码?](http://security.stackexchange.com/questions/211/how-to-securely-hash-passwords)。 SHA-256不适合密码散列,并且需要盐。 – CodesInChaos 2013-04-08 18:35:19

回答

1

通常,密码是通过散列存储的,而不是通过加密存储的。

MessageDigest md = MessageDigest.getInstance("SHA-256"); 
byte[] hash = md.digest(password.getBytes("UTF-8")); 

再对比一下新生成散列您已经存储在数据库中或其它地方的哈希值。

将密码加密也是一个好主意 - 这是一个明文值,您可以在对密码进行哈希处理之前将其附加到密码中。这使得有人执行离线暴力攻击更加困难。

+2

腌制是不够的,你还需要一个昂贵的散列。优选的scrypt,bcrypt或者PBKDF2,但是迭代的SHA-2也可以。单迭代SHA-2不好。 – CodesInChaos 2013-04-08 18:36:58

+0

谢谢。你发布的代码与我的代码有什么不同?你正在使用一个字符串密码(据推测),我已经阅读是一个坏主意,因为它们是不可改变的,可以在内存中生活一段时间。我正在使用一个char [],它需要多个步骤才能转换为byte [],但是当我比较这两个代码片段时,它们都使用MessageDigest变量并摘要化该变量。为了返回目的,我将加密(哈希)密码变回字符串,但它们看起来基本相同。我错过了什么吗?谢谢! – Alex 2013-04-08 18:40:56

+0

我同意你关于腌制。有人可以建议我怎么做?我被困在这一点上。 – Alex 2013-04-08 18:41:47

0

MD5已经死了,而UTF-8应该可能是您最小的担忧。阅读this
当然,根据您的密码加密目的(取决于您获得的目标受众类型),如果您在安全堆栈交换中搜索了足够长的时间,则可以为您的挑战找到完整答案。

只是我的$ 0.02