Я пытаюсь воссоздать реализацию PasswordDeriveBytes из VB.NET, и до сих пор я реализовал в iOS Objective C код, дающий мне разные результаты из реализации Java.SHA1 Обновления MessageDigest и CommonCrypto, получающие разные результаты
Причина, по которой мы пытаемся воссоздать реализацию PasswordDeriveBytes, заключается в том, что клиентская сторона использует ее для шифрования/дешифрования данных и из того, что я искал, PasswordDeriveBytes использует PBKDF1, который устарел. Реализация Java возвращает ожидаемое зашифрованное значение и успешно расшифровывается сервером. Однако значение, возвращаемое из реализации iOS ObjC, неверно.
Ниже реализация Java из Конструктора, взятый из этого ответа: Encryption Diff Between Java and C#
public static class PasswordDeriveBytes{
private final MessageDigest hash;
private final byte[] firstToLastDigest;
private final byte[] outputBuffer;
private int position = 0;
public PasswordDeriveBytes(String password, byte[] salt, int iterations) {
try {
this.hash = MessageDigest.getInstance("SHA-1");
this.hash.update(password.getBytes("UTF-8"));
this.hash.update(salt);
this.firstToLastDigest = this.hash.digest();
// At this point, the Obj-C and Java values are the same
// this.firstToLastDigest = b8fa3d36....
for (int i = 1; i < iterations - 1; i++) {
System.out.println(" Iterate " + i);
hash.update(firstToLastDigest);
hash.digest(firstToLastDigest, 0, firstToLastDigest.length);
}
this.outputBuffer = hash.digest(firstToLastDigest);
// However at this point, they become different
// Java has outputBuffer = f498e100...
// Obj-C has outputBuffer = <d7d5fa71...
} catch (UnsupportedEncodingException|NoSuchAlgorithmException | DigestException e) {
throw new IllegalStateException("SHA-1 digest should always be available", e);
}
}
Хотя ниже является Objective C код конструктора, с помощью этой библиотеки: https://github.com/TakahikoKawasaki/nv-ios-digest
@implementation PasswordDeriveBytesObjC
{
SHA1 *hash;
Byte *firstToLastDigest;
Byte *outputBuffer;
int position;
}
- (instancetype)initWithPassword:(NSString *)password salt:(NSData *)salt iterations:(int)iterations
{
self = [[[self class] alloc] init];
if (self){
hash = [[SHA1 alloc] init];
const char* ASCIIpassword = [password cStringUsingEncoding:NSUTF8StringEncoding];
NSData *passwordData = [NSData dataWithBytes:ASCIIpassword length:strlen(ASCIIpassword)];
[hash updateWith:[passwordData bytes] length:(CC_LONG)[passwordData length]];
[hash updateWith:[salt bytes] length:(CC_LONG)[salt length]];
firstToLastDigest = [hash final];
// At this point, the Obj-C and Java values are the same
// firstToLastDigest = <b8fa3d36....
for (int i = 1; i < iterations - 1; i++){
[hash updateWith:firstToLastDigest length:(CC_LONG)strlen(firstToLastDigest)];
}
[hash updateWith:firstToLastDigest length:(CC_LONG)strlen(firstToLastDigest)];
outputBuffer = [hash final];
// However at this point, they become different
// Java has outputBuffer = f498e100...
// Obj-C has outputBuffer = <d7d5fa71...
}
return self;
}
As насколько я исследовал, реализация hash.digest(input)
java такая же, как [hash updateWith:firstToLastDigest length:(CC_LONG)strlen(firstToLastDigest)]; outputBuffer = [hash final];
в Obj-C, но у меня разные результаты.
На данный момент у меня нет других идей относительно того, почему они получают разные значения, поэтому любые рекомендации или предложения приветствуются.
спасибо, что указал мне в правильном направлении! – Jakob