繁体   English   中英

密码验证-如何安全检查输入的密码是否正确

[英]Password Verification - How to securely check if entered password is correct

我正在开发一个需要多个密码才能访问不同数据区域的应用程序。 例如,一群人可以建立一个聊天,该聊天需要密码验证才能查看。

我正在考虑这样做的方式:

我有我的关键字,假设我们说:

香蕉

当用户输入密码时,我使用RNCryptor使用输入的密钥对Banana进行加密,然后将该加密的字符串存储到服务器。

后来,当有人尝试输入密码时,我从服务器获取哈希值,并尝试使用他们输入的密码作为密钥对其进行解密。 如果解密后的值等于Banana我知道他们输入了正确的密码。

我是安全新手,因此不确定是否合适。 感谢所有帮助。

更新资料

在进行了@Greg和适当命名的@ Anti-weakpasswords建议的一些更改之后,这就是我所拥有的:

- (NSDictionary *) getPasswordDictionaryForPassword:(NSString *)password {

    NSData * salt = [self generateSalt256];
    NSData * key = [RNCryptor keyForPassword:password salt:salt settings:mySettings];

    NSMutableDictionary * passwordDictionary = [NSMutableDictionary new];

    NSString * saltString = stringFromData(salt);
    NSString * keyString = stringFromData(key);

    passwordDictionary[@"key"] = keyString;
    passwordDictionary[@"salt"] = saltString;
    passwordDictionary[@"version"] = @"1.0.0";
    passwordDictionary[@"iterationCount"] = @"10000";

    return passwordDictionary;
}

static const RNCryptorKeyDerivationSettings mySettings = {
    .keySize = kCCKeySizeAES256,
    .saltSize = 32,
    .PBKDFAlgorithm = kCCPBKDF2,
    .PRF = kCCPRFHmacAlgSHA1,
    .rounds = 10000
};

- (NSData *)generateSalt256 {
    unsigned char salt[32];
    for (int i=0; i<32; i++) {
        salt[i] = (unsigned char)arc4random();
    }
    NSData * dataSalt = [NSData dataWithBytes:salt length:sizeof(salt)];
    return dataSalt;
}
  • 不要使用任何哈希函数的单次存储密码。
  • 不要在8-16字节范围内使用随机盐。
  • 不要使用可逆加密来存储密码。
  • 请勿完全按照您输入的密码作为加密密钥。

相反,当用户选择关键字/密码时

  • 生成密码随机的8-16字节盐
  • 将PBKDF2,BCrypt或SCrypt与上述盐一起使用,并使用尽可能多的迭代计数/工作因子来创建处理器的密码哈希
    • 如果特定使用PBKDF2,请不要请求比原始哈希大小大的输出(SHA-1 = 20字节,SHA-256是32字节,SHA-384是48字节,SHA-512是64字节),或者您可以提高攻击者对您(防御者)的比较优势。

然后,在数据库中存储该用户的特定信息:

  • 清澈的盐
  • 迭代次数/工作系数
    • 这样您以后就可以轻松更改/升级它
  • 结果密码哈希
  • 身份验证协议的版本-可能是2,也可能是1。
    • 因此,以后再从此方法移至NewWellKnownMethod时,可以轻松地对其进行更改/升级。

当用户想要对您的系统进行身份验证时,您可以:

  • 从数据库中检索它们的版本,盐,迭代计数/工作因子以及所得的哈希值
  • 将他们刚输入的任何关键字/密码与盐和迭代计数/工作因子从数据库中散列。
  • 将您刚得到的结果与数据库中的结果进行比较; 如果它们相同,则让它们进入。
    • 高级:使用恒定时间比较,因此,它不只是放弃尝试第一个字节是否不同,以减少定时攻击的脆弱性。

请阅读如何安全地散列密码? ,托马斯·波林(Thomas Porrin)的答案目前是密码哈希中最常用的Stackexchange专着,当然也是迄今为止我所见过的最好的答案。

这不是这样做的好方法。 您应该使用一种哈希算法来哈希密码(您将无法对其进行解密)。 在对密码进行哈希处理之后,将其保存到数据库中,在用户提供密码之后,您必须对密码进行哈希处理并将其(哈希值)与存储在数据库中的哈希值进行比较。 如果匹配,则表示相同,如果未通过身份验证,则相同。

这样,即使有人访问了数据库,数据也将得到保护,但他不会对此进行任何操作,因为密码不会存储在那里。

大多数身份验证都是通过这种方式进行的。

//扩展

您应该使用针对此类工作的某种哈希算法。

检出SHAMD5

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM