我有一个Java编写的服务器,在将密码插入数据库之前执行此代码以消化密码:
private static StandardStringDigester getDigester()
{
StandardStringDigester v_Digester = new StandardStringDigester();
v_Digester.setAlgorithm("SHA-1");
v_Digester.setIterations(50000);
return v_Digester;
}
public static String digest(String p_InputPassword)
{
return getDigester().digest(p_InputPassword);
}
我还有一个用Objective C编写的iOS应用程序,它与这个服务器进行通信,在我的代码的某些部分,我需要检查输入的密码是否与存储的密码相匹配。鉴于这不是登录功能,我不愿意将密码发送到服务器并让它进行验证,所以我需要一个等效的方法来消化Objective C中的密码。 我做了一些研究并提出了这个代码,但是我没有为我生成一个等效字符串来与服务器提供的字符串进行比较:
static const int m_Iterations = 50000;
+(NSString *) digest:(NSString *)p_InputPassword
{
unsigned char v_Digest[CC_SHA1_DIGEST_LENGTH];
NSData *v_Data = [p_InputPassword dataUsingEncoding:NSUnicodeStringEncoding];
v_Data = [NSData dataWithBytes:[v_Data bytes] + 2 length:[v_Data length] - 2];
for (int v_Iteration = 0; v_Iteration < m_Iterations; v_Iteration++)
{
if (CC_SHA1([v_Data bytes], [v_Data length], v_Digest))
{
v_Data = [NSData dataWithBytes:v_Digest length:CC_SHA1_DIGEST_LENGTH];
}
else
NSLog(@"treta %i", v_Iteration);
}
NSMutableString *v_Result = [[NSMutableString alloc] init];
for (int v_Index = 0 ; v_Index < CC_SHA1_DIGEST_LENGTH ; v_Index++)
{
[v_Result appendFormat: @"%02x", v_Digest[v_Index]];
}
return v_Result;
}
答案 0 :(得分:1)
这些天的标准密码派生方法是:PBKDF2
(基于密码的密钥派生函数2)
NSMutableData *derivedKey = [NSMutableData dataWithLength:keySize];
int result = CCKeyDerivationPBKDF(
kCCPBKDF2, // algorithm
password.UTF8String, // password
password.length, // passwordLength
salt.bytes, // salt
salt.length, // saltLen
kCCPRFHmacAlgSHA1, // PRF
rounds, // rounds
derivedKey.mutableBytes, // derivedKey
derivedKey.length); // derivedKeyLen
现在最大的问题是Java StandardStringDigester
正在做什么?
假设它迭代哈希函数(SHA1),我会觉得不舒服。似乎还有一种盐
最佳实践是使用Java似乎支持的PBKDF2。
以下是使用#if for utf8或utf16
的代码static const int iterations = 50000;
+ (NSString *) digestPassword:(NSString *)inputPassword {
NSMutableData *dataOut = [NSMutableData dataWithLength:CC_SHA1_DIGEST_LENGTH];
#if 1 // UTF16
NSData *data = [inputPassword dataUsingEncoding:NSUTF16StringEncoding];
data = [data subdataWithRange:NSMakeRange(2, data.length-2)];
#else // UTF8
NSData *data = [inputPassword dataUsingEncoding:NSUTF8StringEncoding];
#endif
for (int iteration = 0; iteration < iterations; iteration++) {
if (CC_SHA1([data bytes], [data length], dataOut.mutableBytes)) {
data = dataOut;
}
else {
NSLog(@"treta %i", iteration);
}
}
unsigned char *digest = (unsigned char *)data.bytes;
NSMutableString *result = [NSMutableString new];
for (int index = 0 ; index < CC_SHA1_DIGEST_LENGTH ; index++) {
[result appendFormat: @"%02x", digest[index]];
}
return result;
}