public static byte[] DeriveKey(byte[] password, byte[] salt, int iterationCount, int keyBitLength, HMAC prf) { prf.Key = password; ulong num = unchecked ((ulong)-1); object[] objArray = new object[] { keyBitLength }; Ensure.MaxValue(keyBitLength, (long)num, "PBKDF2 expect derived key size to be not more that (2^32-1) bits, but was requested {0} bits.", objArray); int hashSize = prf.HashSize / 8; int num1 = keyBitLength / 8; int num2 = (int)Math.Ceiling((double)num1 / (double)hashSize); int num3 = num1 - (num2 - 1) * hashSize; byte[][] numArray = new byte[num2][]; for (int i = 0; i < num2; i++) { numArray[i] = PBKDF2.F(salt, iterationCount, i + 1, prf); } numArray[num2 - 1] = Arrays.LeftmostBits(numArray[num2 - 1], num3 * 8); return(Arrays.Concat(numArray)); }
public static byte[] DeriveKey(CngKey externalPubKey, CngKey privateKey, int keyBitLength, byte[] algorithmId, byte[] partyVInfo, byte[] partyUInfo, byte[] suppPubInfo) { #if NET40 || NET461 using (var cng = new ECDiffieHellmanCng(privateKey)) { using (SafeNCryptSecretHandle hSecretAgreement = cng.DeriveSecretAgreementHandle(externalPubKey)) { using (var algIdBuffer = new NCrypt.NCryptBuffer(NCrypt.KDF_ALGORITHMID, algorithmId)) using (var pviBuffer = new NCrypt.NCryptBuffer(NCrypt.KDF_PARTYVINFO, partyVInfo)) using (var pvuBuffer = new NCrypt.NCryptBuffer(NCrypt.KDF_PARTYUINFO, partyUInfo)) using (var spiBuffer = new NCrypt.NCryptBuffer(NCrypt.KDF_SUPPPUBINFO, suppPubInfo)) { using (var parameters = new NCrypt.NCryptBufferDesc(algIdBuffer, pviBuffer, pvuBuffer, spiBuffer)) { uint derivedSecretByteSize; uint status = NCrypt.NCryptDeriveKey(hSecretAgreement, "SP800_56A_CONCAT", parameters, null, 0, out derivedSecretByteSize, 0); if (status != BCrypt.ERROR_SUCCESS) { throw new CryptographicException(string.Format("NCrypt.NCryptDeriveKey() failed with status code:{0}", status)); } var secretKey = new byte[derivedSecretByteSize]; status = NCrypt.NCryptDeriveKey(hSecretAgreement, "SP800_56A_CONCAT", parameters, secretKey, derivedSecretByteSize, out derivedSecretByteSize, 0); if (status != BCrypt.ERROR_SUCCESS) { throw new CryptographicException(string.Format("NCrypt.NCryptDeriveKey() failed with status code:{0}", status)); } return(Arrays.LeftmostBits(secretKey, keyBitLength)); } } } } #elif NETSTANDARD1_4 throw new NotImplementedException("not yet"); #endif }
public static byte[] DeriveKey(CngKey externalPubKey, CngKey privateKey, int keyBitLength, byte[] algorithmId, byte[] partyVInfo, byte[] partyUInfo, byte[] suppPubInfo) { uint num; byte[] numArray; using (ECDiffieHellmanCng eCDiffieHellmanCng = new ECDiffieHellmanCng(privateKey)) { using (SafeNCryptSecretHandle safeNCryptSecretHandle = eCDiffieHellmanCng.DeriveSecretAgreementHandle(externalPubKey)) { using (NCrypt.NCryptBuffer nCryptBuffer = new NCrypt.NCryptBuffer(8, algorithmId)) { using (NCrypt.NCryptBuffer nCryptBuffer1 = new NCrypt.NCryptBuffer(10, partyVInfo)) { using (NCrypt.NCryptBuffer nCryptBuffer2 = new NCrypt.NCryptBuffer(9, partyUInfo)) { using (NCrypt.NCryptBuffer nCryptBuffer3 = new NCrypt.NCryptBuffer(11, suppPubInfo)) { using (NCrypt.NCryptBufferDesc nCryptBufferDesc = new NCrypt.NCryptBufferDesc(new NCrypt.NCryptBuffer[] { nCryptBuffer, nCryptBuffer1, nCryptBuffer2, nCryptBuffer3 })) { uint num1 = NCrypt.NCryptDeriveKey(safeNCryptSecretHandle, "SP800_56A_CONCAT", nCryptBufferDesc, null, 0, out num, 0); if (num1 != 0) { throw new CryptographicException(string.Format("NCrypt.NCryptDeriveKey() failed with status code:{0}", num1)); } byte[] numArray1 = new byte[num]; num1 = NCrypt.NCryptDeriveKey(safeNCryptSecretHandle, "SP800_56A_CONCAT", nCryptBufferDesc, numArray1, num, out num, 0); if (num1 != 0) { throw new CryptographicException(string.Format("NCrypt.NCryptDeriveKey() failed with status code:{0}", num1)); } numArray = Arrays.LeftmostBits(numArray1, keyBitLength); } } } } } } } return(numArray); }
/// <summary> /// Implements RFC2898 Password Based Key Derivation Function #2 /// </summary> /// <param name="password">password to be used as hash key</param> /// <param name="salt">salt</param> /// <param name="iterationCount">number of iterations to perform</param> /// <param name="keyBitLength">desired key length in bits to detive</param> /// <param name="prf">Pseudo Random Function, HMAC will be inited with key equal to given password</param> /// <returns></returns> public static byte[] DeriveKey(byte[] password, byte[] salt, int iterationCount, int keyBitLength, HMAC prf) { prf.Key = password; // 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and stop. Ensure.MaxValue(keyBitLength, 4294967295, "PBKDF2 expect derived key size to be not more that (2^32-1) bits, but was requested {0} bits.", keyBitLength); int hLen = prf.HashSize / 8; //size of mac in bytes int dkLen = keyBitLength / 8; //size of derived key in bytes int l = (int)Math.Ceiling(dkLen / (double)hLen); // l = CEIL (dkLen / hLen) , int r = dkLen - (l - 1) * hLen; // r = dkLen - (l - 1) * hLen . byte[][] T = new byte[l][]; for (int i = 0; i < l; i++) { T[i] = F(salt, iterationCount, i + 1, prf); // T_l = F (P, S, c, l) } T[l - 1] = Arrays.LeftmostBits(T[l - 1], r * 8); //truncate last block to r bits return(Arrays.Concat(T)); // DK = T_1 || T_2 || ... || T_l<0..r-1> }