У меня проблема с получением псевдослучайного производного ключа с использованием CCKeyDerivationPBKDF
.
Вот код, который я использую @zaph:
// password password String
// salt salt Data
// keyByteCount number of key bytes to generate
// rounds Iteration rounds
//
// returns Derived key
func pbkdf2SHA1(password: String, salt: Data, keyByteCount: Int, rounds: Int) -> Data? {
return pbkdf2(hash:CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA1), password:password, salt:salt, keyByteCount:keyByteCount, rounds:rounds)
}
func pbkdf2SHA256(password: String, salt: Data, keyByteCount: Int, rounds: Int) -> Data? {
return pbkdf2(hash:CCPBKDFAlgorithm(kCCPRFHmacAlgSHA256), password:password, salt:salt, keyByteCount:keyByteCount, rounds:rounds)
}
func pbkdf2SHA512(password: String, salt: Data, keyByteCount: Int, rounds: Int) -> Data? {
return pbkdf2(hash:CCPBKDFAlgorithm(kCCPRFHmacAlgSHA512), password:password, salt:salt, keyByteCount:keyByteCount, rounds:rounds)
}
func pbkdf2(hash :CCPBKDFAlgorithm, password: String, salt: Data, keyByteCount: Int, rounds: Int) -> Data? {
let passwordData = password.data(using:String.Encoding.utf8)!
var derivedKeyData = Data(repeating:0, count:keyByteCount)
let derivationStatus = derivedKeyData.withUnsafeMutableBytes {derivedKeyBytes in
salt.withUnsafeBytes { saltBytes in
CCKeyDerivationPBKDF(
CCPBKDFAlgorithm(kCCPBKDF2),
password, passwordData.count,
saltBytes, salt.count,
hash,
UInt32(rounds),
derivedKeyBytes, derivedKeyData.count)
}
}
if (derivationStatus != 0) {
print("Error: \(derivationStatus)")
return nil;
}
return derivedKeyData
}
Моя проблема в том, что он продолжает генерировать одни и те же производные ключи для каждого вызова. Я пытаюсь расшифровать данные, которые были зашифрованы на стороне .Net с помощью Rfc2898DeriveBytes
:
var saltBytes = Encoding.ASCII.GetBytes(salt);
var key = new Rfc2898DeriveBytes(Inputkey, saltBytes);
var aesAlg = new RijndaelManaged();
aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8); // default keySize 256
aesAlg.IV = key.GetBytes(aesAlg.BlockSize / 8); // default blockSize 128
На стороне .Net Rfc2898DeriveBytes
возвращает новый случайный набор байтов, но мой код Swift только генерирует для каждого вызова одну и ту же последовательность. Что не так с генерацией последовательности на стороне Swift?
Edit1: когда я использовал последовательности байтов Key и IV, сгенерированные Rfc2898DeriveBytes
из .net в Swift, пытаясь расшифровать данные, зашифрованные в .net, тогда он работал нормально.
Edit2: Хорошо, я обнаружил, что первый раз, когда Rfc2898DeriveBytes
работает с методом GetBytes, дает тот же результат, что и результат Swift PBKDF2. Второй вызов GetBytes дает совершенно другой результат. Это почему? Если я найду решение для этого, то моя расшифровка должна работать.
aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8); // (1) - the same result as in Swift implementation
aesAlg.IV = key.GetBytes(aesAlg.BlockSize / 8); // (2) - completly different result
Я неправильно инициализирую IV в Swift?