我使用CCKeyDerivationPBKDF
獲取僞隨機生成的派生密鑰時遇到問題。使用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
}
我的問題是,它使生成的每個調用相同的派生的密鑰。 我試圖解密是與Rfc2898DeriveBytes
.Net的側加密的數據:
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那邊的序列生成有什麼問題?
編輯1:當我使用從.net生成的Rfc2898DeriveBytes
的密鑰和IV字節序列試圖解密在.net中加密的數據時,它工作正常。
編輯2:好的,我發現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
我是否錯誤地初始化了Swift中的IV?
您需要在生產中每次使用不同的鹽。在加密和解密中需要使用相同的IV,一種常見的方法是使用IV來加密數據的前綴,而不需要保密。在aesAlg.IV的情況下,函數初始化了一次,並且對它進行了兩次調用。多次使用同一個密鑰的同一個IV是一個安全問題。 – zaph
@ zaph非常感謝您的回覆。對不起,我還是不明白。對於AES256,IV總是長16字節?你的意思是,GetBytes方法不應該在同一個實例上調用兩次?我可能會問很愚蠢的問題,因爲我在這個主題上是新的。 – PiotrCh
AES IV總是16字節。每次使用相同的加密密鑰時,它需要不同。它最好作爲加密數據的一部分通過解密,通常用於加密數據。只要是隨機的,IV並不重要。如果使用一種方法爲同一個不安全的密鑰生成相同的IV。 – zaph