Userpath: 一个在我的Android应用程序中注册,然后决定通过iPhone应用程序登录。
服务器向我发送加密密码,我需要与刚刚输入密码字段的用户进行比较。
这是加密字符串的Java方法:
public static String encrypt(String password) {
int iterations = 1000;
char[] chars = password.toCharArray();
byte[] salt = getSalt().getBytes();
PBEKeySpec spec = new PBEKeySpec(chars, salt, iterations, 256);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] hash = skf.generateSecret(spec).getEncoded();
return toHex(hash);
}
到目前为止我所拥有的:
- (BOOL)isPasswordValid
{
NSString * saltString = @"5b42406231323062343030";
NSString * storedPasswordString = @"90bd42e6f15ccd2d3ec3386d031758898bb7bc08f476a3d7afe6fe1cfbc372e6";
NSData * hashData = [storedPasswordString dataFromHexString];
unsigned char out[256];
//converting saltstring into char array
//
NSMutableArray * saltArray = [NSMutableArray array];
for (NSInteger idx = 0; idx < saltString.length; idx++) {
[saltArray addObject:[NSString stringWithFormat:@"%C", [saltString characterAtIndex:idx]]];
}
unsigned char * buffer = (unsigned char *)calloc([saltArray count],
sizeof(unsigned char));
for (int i = 0; i < [saltArray count]; i++)
buffer[i] = (char)[saltArray objectAtIndex:i];
PKCS5_PBKDF2_HMAC_SHA1("password", strlen("password"), buffer, sizeof(buffer), ITERATION, 256, out);
NSMutableString * hashTestString = [NSMutableString new];
for (NSInteger idx = 0; idx < sizeof(out); idx++) {
[hashTestString appendString:[NSString stringWithFormat:@"%02x", out[idx]]];
}
NSData * hashDataTest = [hashTestString dataFromHexString];
const char *hashBytes = [hashData bytes];
const char *hashBytesTest = [hashDataTest bytes];
int diff = hashData.length ^ hashDataTest.length;
for (int i = 0; i < hashData.length && i < hashDataTest.length; i++) {
diff |= hashBytes[i] ^ hashBytesTest[i];
}
free(buffer);
return diff == 0;
}
Method PKCS5_PBKDF2_HMAC_SHA1不幸的是,对于测试用例,它总是返回-1。
想法:
以十六进制表示形式接收到的字符串中的Salt,这可能是问题所在。所以我尝试将十六进制@"5b42406231323062343030"
转换为字符串@"[B@b120b400"
,然后将其转换为char数组,但仍然没有结果。
UPD:
如果我使用unsigned char salt[] = {'[','B','@','b','1','2','0','b','4','0','0'};' instead of
buffer`变量,它可以正常工作。所以,我的十六进制字符串转换为char数组很糟糕。
答案 0 :(得分:1)
您使用buffer
calloc
的空间
unsigned char * buffer = (unsigned char *)calloc([saltArray count],
下面:
PKCS5_PBKDF2_HMAC_SHA1("password", strlen("password"), buffer, sizeof(buffer), ..
sizeof(buffer)
返回sizeof(unsigned char *)
,使用strlen((char *)buffer)
答案 1 :(得分:0)
我一遍又一遍地测试我的解决方案。正如我上面评论的,
如果我使用unsigned char salt[] = {'[','B','@','b','1','2','0','b','4','0','0'};
代替buffer
变量,它可以正常工作。所以,我注意到我的十六进制字符串转换为char数组很糟糕。
NSString
实例有- (const char *)UTF8String
方法,它返回以null结尾的UTF8表示。
此外,我将我从服务器收到的hex-salt转换为NSString,最后得到以下代码段:
- (BOOL)isPasswordValid
{
NSString * saltString = @"[B@b120b400";
NSString * storedPasswordString = @"90bd42e6f15ccd2d3ec3386d031758898bb7bc08f476a3d7afe6fe1cfbc372e6";
NSData * hashData = [storedPasswordString dataFromHexString];
unsigned char out[[hashData length]];
PKCS5_PBKDF2_HMAC_SHA1("password", strlen("password"),
(const unsigned char *)[saltString UTF8String],
strlen([saltString UTF8String]), 1000,
[hashData length], out);
NSMutableString * hashTestString = [NSMutableString new];
for (NSInteger idx = 0; idx < sizeof(out); idx++) {
[hashTestString appendString:[NSString stringWithFormat:@"%02x", out[idx]]];
}
NSData * hashDataTest = [hashTestString dataFromHexString];
const char * hashBytes = [hashData bytes];
const char * hashBytesTest = [hashDataTest bytes];
int diff = hashData.length ^ hashDataTest.length;
for (int i = 0; i < hashData.length && i < hashDataTest.length; i++) {
diff |= hashBytes[i] ^ hashBytesTest[i];
}
return diff == 0;
}