private static readonly byte[] DefaultIV = { 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6 }; // http://www.ietf.org/rfc/rfc3394.txt (see 2.2.3) public static byte[] Wrap(byte[] cek, byte[] kek) { Ensure.MinBitSize(cek, 128, "AesKeyWrap.Wrap() expects content length not less than 128 bits, but was {0}", cek.Length * 8); Ensure.Divisible(cek.Length, 8, "AesKeyWrap.Wrap() expects content length to be divisable by 8, but was given a content of {0} bit size.", cek.Length * 8); // 1) Initialize variables byte[] a = DefaultIV; // Set A = IV, an initial value byte[][] r = Arrays.Slice(cek, 8); // For i = 1 to n // R[0][i] = P[i] long n = r.Length; // 2) Calculate intermediate values. for (long j = 0; j < 6; j++) // For j = 0 to 5 { for (long i = 0; i < n; i++) // For i=1 to n { long t = n * j + i + 1; byte[] b = AesEnc(kek, Arrays.Concat(a, r[i])); // B=AES(K, A | R[i]) a = Arrays.FirstHalf(b); // A=MSB(64,B) ^ t where t = (n*j)+i r[i] = Arrays.SecondHalf(b); // R[i] = LSB(64, B) a = Arrays.Xor(a, t); } } // 3) Output the results byte[][] c = new byte[n + 1][]; c[0] = a; // Set C[0] = A for (long i = 1; i <= n; i++) // For i = 1 to n { c[i] = r[i - 1]; // C[i] = R[i] } return(Arrays.Concat(c)); }
public static byte[] Wrap(byte[] cek, byte[] kek) { Ensure.MinBitSize(cek, 128, "AesKeyWrap.Wrap() expects content length not less than 128 bits, but was {0}", new object[] { (int)cek.Length * 8 }); Ensure.Divisible((int)cek.Length, 8, "AesKeyWrap.Wrap() expects content length to be divisable by 8, but was given a content of {0} bit size.", new object[] { (int)cek.Length * 8 }); byte[] defaultIV = AesKeyWrap.DefaultIV; byte[][] numArray = Arrays.Slice(cek, 8); long length = (long)((int)numArray.Length); for (long i = (long)0; i < (long)6; i += (long)1) { for (long j = (long)0; j < length; j += (long)1) { long num = length * i + j + (long)1; byte[] numArray1 = AesKeyWrap.AesEnc(kek, Arrays.Concat(new byte[][] { defaultIV, numArray[checked (j)] })); defaultIV = Arrays.FirstHalf(numArray1); numArray[checked (j)] = Arrays.SecondHalf(numArray1); defaultIV = Arrays.Xor(defaultIV, num); } } byte[][] numArray2 = new byte[checked (length + 1)][]; numArray2[0] = defaultIV; for (long k = (long)1; k <= length; k += (long)1) { numArray2[checked (k)] = numArray[checked (k - (long)1)]; } return(Arrays.Concat(numArray2)); }
public byte[][] WrapNewKey(int cekSizeBits, object key, IDictionary <string, object> header) { var sharedPassphrase = Ensure.Type <string>(key, "Pbse2HmacShaKeyManagementWithAesKeyWrap management algorithm expectes key to be string."); byte[] sharedKey = Encoding.UTF8.GetBytes(sharedPassphrase); byte[] algId = Encoding.UTF8.GetBytes((string)header["alg"]); int iterationCount = 8192; byte[] saltInput = Arrays.Random(96); //12 bytes header["p2c"] = iterationCount; header["p2s"] = Base64Url.Encode(saltInput); byte[] salt = Arrays.Concat(algId, Arrays.Zero, saltInput); byte[] kek; using (var prf = PRF) { kek = PBKDF2.DeriveKey(sharedKey, salt, iterationCount, keyLengthBits, prf); } return(aesKW.WrapNewKey(cekSizeBits, kek, header)); }
public byte[] Unwrap(byte[] encryptedCek, object key, int cekSizeBits, IDictionary <string, object> header) { var sharedPassphrase = Ensure.Type <string>(key, "Pbse2HmacShaKeyManagementWithAesKeyWrap management algorithm expectes key to be string."); byte[] sharedKey = Encoding.UTF8.GetBytes(sharedPassphrase); Ensure.Contains(header, new[] { "p2c" }, "Pbse2HmacShaKeyManagementWithAesKeyWrap algorithm expects 'p2c' param in JWT header, but was not found"); Ensure.Contains(header, new[] { "p2s" }, "Pbse2HmacShaKeyManagementWithAesKeyWrap algorithm expects 'p2s' param in JWT header, but was not found"); byte[] algId = Encoding.UTF8.GetBytes((string)header["alg"]); int iterationCount = Convert.ToInt32(header["p2c"]); byte[] saltInput = Base64Url.Decode((string)header["p2s"]); byte[] salt = Arrays.Concat(algId, Arrays.Zero, saltInput); byte[] kek; using (var prf = PRF) { kek = PBKDF2.DeriveKey(sharedKey, salt, iterationCount, keyLengthBits, prf); } return(aesKW.Unwrap(encryptedCek, kek, cekSizeBits, header)); }
public static byte[] Unwrap(byte[] encryptedCek, byte[] kek) { Ensure.MinBitSize(encryptedCek, 128, "AesKeyWrap.Unwrap() expects content length not less than 128 bits, but was {0}", new object[] { (int)encryptedCek.Length * 8 }); Ensure.Divisible((int)encryptedCek.Length, 8, "AesKeyWrap.Unwrap() expects content length to be divisable by 8, but was given a content of {0} bit size.", new object[] { (int)encryptedCek.Length * 8 }); byte[][] numArray = Arrays.Slice(encryptedCek, 8); byte[] numArray1 = numArray[0]; byte[][] numArray2 = new byte[(int)numArray.Length - 1][]; for (int i = 1; i < (int)numArray.Length; i++) { numArray2[i - 1] = numArray[i]; } long length = (long)((int)numArray2.Length); for (long j = (long)5; j >= (long)0; j -= (long)1) { for (long k = length - (long)1; k >= (long)0; k -= (long)1) { long num = length * j + k + (long)1; numArray1 = Arrays.Xor(numArray1, num); byte[] numArray3 = AesKeyWrap.AesDec(kek, Arrays.Concat(new byte[][] { numArray1, numArray2[checked (k)] })); numArray1 = Arrays.FirstHalf(numArray3); numArray2[checked (k)] = Arrays.SecondHalf(numArray3); } } if (!Arrays.ConstantTimeEquals(AesKeyWrap.DefaultIV, numArray1)) { throw new IntegrityException("AesKeyWrap integrity check failed."); } return(Arrays.Concat(numArray2)); }
private static byte[] securedInput(byte[] header, byte[] payload, bool b64) { return(b64 ? Encoding.UTF8.GetBytes(Compact.Serialize(header, payload)) : Arrays.Concat(Encoding.UTF8.GetBytes(Compact.Serialize(header)), Encoding.UTF8.GetBytes("."), payload)); }
private byte[] ComputeAuthTag(byte[] aad, byte[] iv, byte[] cipherText, byte[] hmacKey) { byte[] al = Arrays.LongToBytes(aad.Length * 8); byte[] hmacInput = Arrays.Concat(aad, iv, cipherText, al); byte[] hmac = hashAlgorithm.Sign(hmacInput, hmacKey); return(Arrays.FirstHalf(hmac)); }
private static byte[] F(byte[] salt, int iterationCount, int blockIndex, HMAC prf) { byte[] numArray = prf.ComputeHash(Arrays.Concat(new byte[][] { salt, Arrays.IntToBytes(blockIndex) })); byte[] numArray1 = numArray; for (int i = 2; i <= iterationCount; i++) { numArray = prf.ComputeHash(numArray); numArray1 = Arrays.Xor(numArray1, numArray); } return(numArray1); }
private byte[] DeriveKey(IDictionary <string, object> header, int cekSizeBits, CngKey externalPublicKey, CngKey privateKey) { byte[] bytes = Encoding.UTF8.GetBytes((string)header[this.algIdHeader]); byte[] numArray = (header.ContainsKey("apv") ? Base64Url.Decode((string)header["apv"]) : Arrays.Empty); byte[] numArray1 = (header.ContainsKey("apu") ? Base64Url.Decode((string)header["apu"]) : Arrays.Empty); byte[] numArray2 = Arrays.Concat(new byte[][] { Arrays.IntToBytes((int)bytes.Length), bytes }); byte[] numArray3 = Arrays.Concat(new byte[][] { Arrays.IntToBytes((int)numArray1.Length), numArray1 }); byte[] numArray4 = Arrays.Concat(new byte[][] { Arrays.IntToBytes((int)numArray.Length), numArray }); byte[] bytes1 = Arrays.IntToBytes(cekSizeBits); return(ConcatKDF.DeriveKey(externalPublicKey, privateKey, cekSizeBits, numArray2, numArray4, numArray3, bytes1)); }
private byte[] DeriveKey(IDictionary <string, object> header, int cekSizeBits, CngKey externalPublicKey, CngKey privateKey) { byte[] enc = Encoding.UTF8.GetBytes((string)header[algIdHeader]); byte[] apv = header.ContainsKey("apv") ? Base64Url.Decode((string)header["apv"]) : Arrays.Empty; byte[] apu = header.ContainsKey("apu") ? Base64Url.Decode((string)header["apu"]) : Arrays.Empty; byte[] algorithmId = Arrays.Concat(Arrays.IntToBytes(enc.Length), enc); byte[] partyUInfo = Arrays.Concat(Arrays.IntToBytes(apu.Length), apu); byte[] partyVInfo = Arrays.Concat(Arrays.IntToBytes(apv.Length), apv); byte[] suppPubInfo = Arrays.IntToBytes(cekSizeBits); return(ConcatKDF.DeriveKey(externalPublicKey, privateKey, cekSizeBits, algorithmId, partyVInfo, partyUInfo, suppPubInfo)); }
private static byte[] F(byte[] salt, int iterationCount, int blockIndex, HMAC prf) { byte[] U = prf.ComputeHash(Arrays.Concat(salt, Arrays.IntToBytes(blockIndex))); // U_1 = PRF (P, S || INT (i)) byte[] result = U; for (int i = 2; i <= iterationCount; i++) { U = prf.ComputeHash(U); // U_c = PRF (P, U_{c-1}) . result = Arrays.Xor(result, U); // U_1 \xor U_2 \xor ... \xor U_c } return(result); }
private static IntPtr ImportKey(IntPtr hAlg, byte[] key, out IntPtr hKey) { int num = BitConverter.ToInt32(AesGcm.GetProperty(hAlg, BCrypt.BCRYPT_OBJECT_LENGTH), 0); IntPtr intPtr = Marshal.AllocHGlobal(num); byte[] numArray = Arrays.Concat(new byte[][] { BCrypt.BCRYPT_KEY_DATA_BLOB_MAGIC, BitConverter.GetBytes(1), BitConverter.GetBytes((int)key.Length), key }); uint num1 = BCrypt.BCryptImportKey(hAlg, IntPtr.Zero, BCrypt.BCRYPT_KEY_DATA_BLOB, out hKey, intPtr, num, numArray, (int)numArray.Length, 0); if (num1 != 0) { throw new CryptographicException(string.Format("BCrypt.BCryptImportKey() failed with status code:{0}", num1)); } return(intPtr); }
private static IntPtr ImportKey(IntPtr hAlg, byte[] key, out IntPtr hKey) { byte[] objLength = GetProperty(hAlg, BCrypt.BCRYPT_OBJECT_LENGTH); int keyDataSize = BitConverter.ToInt32(objLength, 0); IntPtr keyDataBuffer = Marshal.AllocHGlobal(keyDataSize); byte[] keyBlob = Arrays.Concat(BCrypt.BCRYPT_KEY_DATA_BLOB_MAGIC, BitConverter.GetBytes(0x1), BitConverter.GetBytes(key.Length), key); uint status = BCrypt.BCryptImportKey(hAlg, IntPtr.Zero, BCrypt.BCRYPT_KEY_DATA_BLOB, out hKey, keyDataBuffer, keyDataSize, keyBlob, keyBlob.Length, 0x0); if (status != BCrypt.ERROR_SUCCESS) { throw new CryptographicException(string.Format("BCrypt.BCryptImportKey() failed with status code:{0}", status)); } return(keyDataBuffer); }
public byte[] Unwrap(byte[] encryptedCek, object key, int cekSizeBits, IDictionary <string, object> header) { byte[] numArray; string str = Ensure.Type <string>(key, "Pbse2HmacShaKeyManagementWithAesKeyWrap management algorithm expectes key to be string.", new object[0]); byte[] bytes = Encoding.UTF8.GetBytes(str); Ensure.Contains(header, new string[] { "p2c" }, "Pbse2HmacShaKeyManagementWithAesKeyWrap algorithm expects 'p2c' param in JWT header, but was not found", new object[0]); Ensure.Contains(header, new string[] { "p2s" }, "Pbse2HmacShaKeyManagementWithAesKeyWrap algorithm expects 'p2s' param in JWT header, but was not found", new object[0]); byte[] bytes1 = Encoding.UTF8.GetBytes((string)header["alg"]); int num = Convert.ToInt32(header["p2c"]); byte[] numArray1 = Base64Url.Decode((string)header["p2s"]); byte[] numArray2 = Arrays.Concat(new byte[][] { bytes1, Arrays.Zero, numArray1 }); using (HMAC pRF = this.PRF) { numArray = PBKDF2.DeriveKey(bytes, numArray2, num, this.keyLengthBits, pRF); } return(this.aesKW.Unwrap(encryptedCek, numArray, cekSizeBits, header)); }
public byte[][] WrapNewKey(int cekSizeBits, object key, IDictionary <string, object> header) { byte[] numArray; string str = Ensure.Type <string>(key, "Pbse2HmacShaKeyManagementWithAesKeyWrap management algorithm expectes key to be string.", new object[0]); byte[] bytes = Encoding.UTF8.GetBytes(str); byte[] bytes1 = Encoding.UTF8.GetBytes((string)header["alg"]); int num = 8192; byte[] numArray1 = Arrays.Random(96); header["p2c"] = num; header["p2s"] = Base64Url.Encode(numArray1); byte[] numArray2 = Arrays.Concat(new byte[][] { bytes1, Arrays.Zero, numArray1 }); using (HMAC pRF = this.PRF) { numArray = PBKDF2.DeriveKey(bytes, numArray2, num, this.keyLengthBits, pRF); } return(this.aesKW.WrapNewKey(cekSizeBits, numArray, header)); }
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)); }
static byte[] DeriveKey(IDictionary <string, object> header, int cekSizeBits, ECPublicKeyParameters externalPublicKey, ECPrivateKeyParameters ephemeralPrvKey) { var z = EcdhKeyAgreementZ(externalPublicKey, ephemeralPrvKey); var kdfGen = new ConcatenationKdfGenerator(new Sha256Digest()); byte[] algId = Encoding.ASCII.GetBytes(header["enc"].ToString()); byte[] apu = header.ContainsKey("apu") ? Base64Url.Decode((string)header["apu"]) : Arrays.Empty; byte[] apv = header.ContainsKey("apv") ? Base64Url.Decode((string)header["apv"]) : Arrays.Empty; byte[] kdl = CalcBeLengthArray(cekSizeBits); var otherInfo = Arrays.Concat(PrependLength(algId), PrependLength(apu), PrependLength(apv), kdl); //Console.Out.WriteLine($"otherInfo={VAU.ByteArrayToHexString(otherInfo)}"); kdfGen.Init(new KdfParameters(z, otherInfo)); byte[] secretKeyBytes = new byte[32]; kdfGen.GenerateBytes(secretKeyBytes, 0, secretKeyBytes.Length); return(secretKeyBytes); }
public static byte[] Unwrap(byte[] encryptedCek, byte[] kek) { Ensure.MinBitSize(encryptedCek, 128, "AesKeyWrap.Unwrap() expects content length not less than 128 bits, but was {0}", encryptedCek.Length * 8); Ensure.Divisible(encryptedCek.Length, 8, "AesKeyWrap.Unwrap() expects content length to be divisable by 8, but was given a content of {0} bit size.", encryptedCek.Length * 8); // 1) Initialize variables byte[][] c = Arrays.Slice(encryptedCek, 8); byte[] a = c[0]; // Set A = C[0] byte[][] r = new byte[c.Length - 1][]; for (int i = 1; i < c.Length; i++) // For i = 1 to n { r[i - 1] = c[i]; // R[i] = C[i] } long n = r.Length; // 2) Calculate intermediate values for (long j = 5; j >= 0; j--) // For j = 5 to 0 { for (long i = n - 1; i >= 0; i--) // For i = n to 1 { long t = n * j + i + 1; a = Arrays.Xor(a, t); byte[] B = AesDec(kek, Arrays.Concat(a, r[i])); // B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i a = Arrays.FirstHalf(B); // A = MSB(64, B) r[i] = Arrays.SecondHalf(B); // R[i] = LSB(64, B) } } // 3) Output the results if (!Arrays.ConstantTimeEquals(DefaultIV, a)) // If A is an appropriate initial value { throw new IntegrityException("AesKeyWrap integrity check failed."); } // For i = 1 to n return(Arrays.Concat(r)); // P[i] = R[i] }
/// <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> }
private byte[] ComputeAuthTag(byte[] aad, byte[] iv, byte[] cipherText, byte[] hmacKey) { byte[] bytes = Arrays.LongToBytes((long)((int)aad.Length * 8)); byte[] numArray = Arrays.Concat(new byte[][] { aad, iv, cipherText, bytes }); return(Arrays.FirstHalf(this.hashAlgorithm.Sign(numArray, hmacKey))); }
static byte[] PrependLength(byte[] data) { return(Arrays.Concat(CalcBeLengthArray(data.Length), data)); }