密码加密 [重复]

Posted

技术标签:

【中文标题】密码加密 [重复]【英文标题】:Password Encrypting [duplicate] 【发布时间】:2013-03-30 23:04:51 【问题描述】:

我正在尝试编写一个密码加密类,我可以使用它来加密和存储用户密码。我想确保我做的正确。这段代码工作正常,似乎生成了一个加密密码,但我想在这里发布它以获得一些反馈。对我来说,这相当复杂,而且我知道加密货币中的任何东西都很容易犯错误,而没有意识到你正在犯错误。

这是我的代码:

    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 字段中,这就是我以 char[] 开头的原因。为了测试,我使用这段代码来调用函数:

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

由于这是我第一次尝试,我想我忽略了一些东西。我对 任何 建议或 cmets 感兴趣。不过,我确实有几个具体问题:

    当我将 char[] 转换为 byte[] 时,我不相信我这样做是正确的。我怎么知道要使用哪种编码?在这里,我输入了“UTF-8”,主要是作为占位符,但我担心这在某些情况下可能会失败。

    我读到我应该在密码被消化后使用盐和迭代,但我不知道如何做到这一点。有人可以给我建议吗?

    我正在使用 SHA-256。这是建议的算法吗?我也读过MD5。有没有一种算法更适合密码加密?

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

【问题讨论】:

见How to securely hash passwords?。 SHA-256 不适合密码散列,你需要一个盐。 【参考方案1】:

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

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

然后将新生成的哈希与您存储在数据库或任何地方的哈希进行比较。

对密码加盐也是一个好主意——这是一个明文值,您在对密码进行散列之前附加到密码。这使得某人更难以执行离线暴力攻击。

【讨论】:

加盐是不够的,你还需要一个昂贵的哈希值。首选 scrypt、bcrypt 或 PBKDF2,但迭代 SHA-2 也可以。单次迭代 SHA-2 不行。 谢谢。您发布的代码与我的代码有何不同?您正在使用字符串密码(大概),我读过这是一个坏主意,因为它们是不可变的并且可以在内存中存在一段时间。我正在使用 char[],它需要几个步骤才能转换为 byte[],但是当我比较这两个代码 sn-ps 时,它们都使用 MessageDigest 变量并消化该变量。我将加密(散列)密码转换回字符串以供返回,但它们看起来基本相同。我错过了什么吗?谢谢! 我同意你关于加盐的看法。有人可以建议我怎么做吗?我被困在这一点上。 这显示了某种方式***.com/a/2861125/1083581,这有一个完整的示例***.com/a/11038230/1083581 使用 byte[] salt = new byte[16], new Random().nextBytes(salt) 生成盐 - 你可以使用 SecureRandom 代替,但这并没有增加太多,因为盐不是秘密。然后使用 System.arraycopy 将盐和密码复制到一个数组中,对其进行哈希处理,然后将其删除。【参考方案2】:

MD5 已死,而 UTF-8 应该是您最不必担心的。阅读this 当然,根据您加密密码的目的(取决于您获得的目标受众类型),如果您在安全堆栈交换中搜索足够长的时间,您将很快找到挑战的完整答案。只需我的 0.02 美元

【讨论】:

以上是关于密码加密 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

客户端密码加密[重复]

登录怎么对密码MD5加密

加密密码php的最佳方式(2017年)[重复]

密码加密和通过网络发送的最佳方法[重复]

与 PHP 一起使用的最佳密码加密和解密技术 [重复]

MySQL中的密码加密[重复]