/// <summary> /// Returns the <see cref="SymmetricAlgorithm"/>. /// </summary> /// <returns></returns> /// <exception cref="ArgumentException">The <see cref="SecurityKey"/> cannot be converted to byte array</exception> /// <exception cref="ArgumentOutOfRangeException">The keysize doesn't match the algorithm.</exception> /// <exception cref="InvalidOperationException">Failed to create symmetric algorithm with provided key and algorithm.</exception> protected virtual SymmetricAlgorithm GetSymmetricAlgorithm(SecurityKey key, string algorithm) { if (key == null) { throw LogHelper.LogArgumentNullException(nameof(key)); } if (!IsSupportedAlgorithm(key, algorithm)) { throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10661, algorithm, key))); } byte[] keyBytes = null; if (key is SymmetricSecurityKey symmetricSecurityKey) { keyBytes = symmetricSecurityKey.Key; } else if (key is JsonWebKey jsonWebKey) { if (JsonWebKeyConverter.TryConvertToSymmetricSecurityKey(jsonWebKey, out SecurityKey securityKey)) { keyBytes = (securityKey as SymmetricSecurityKey).Key; } } if (keyBytes == null) { throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10657, key.GetType()))); } ValidateKeySize(keyBytes, algorithm); try { // Create the AES provider SymmetricAlgorithm symmetricAlgorithm = Aes.Create(); symmetricAlgorithm.Mode = CipherMode.ECB; symmetricAlgorithm.Padding = PaddingMode.None; symmetricAlgorithm.KeySize = keyBytes.Length * 8; symmetricAlgorithm.Key = keyBytes; // Set the AES IV to Zeroes var aesIv = new byte[symmetricAlgorithm.BlockSize >> 3]; Utility.Zero(aesIv); symmetricAlgorithm.IV = aesIv; return(symmetricAlgorithm); } catch (Exception ex) { throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10663, key, algorithm), ex)); } }
/// <summary> /// Called to obtain the byte[] needed to create a <see cref="KeyedHashAlgorithm"/> /// </summary> /// <param name="key"><see cref="SecurityKey"/>that will be used to obtain the byte[].</param> /// <returns><see cref="byte"/>[] that is used to populated the KeyedHashAlgorithm.</returns> /// <exception cref="ArgumentNullException">if <paramref name="key"/> is null.</exception> /// <exception cref="ArgumentException">if a byte[] can not be obtained from SecurityKey.</exception> /// <remarks><see cref="SymmetricSecurityKey"/> and <see cref="JsonWebKey"/> are supported. /// <para>For a <see cref="SymmetricSecurityKey"/> .Key is returned</para> /// <para>For a <see cref="JsonWebKey"/>Base64UrlEncoder.DecodeBytes is called with <see cref="JsonWebKey.K"/> if <see cref="JsonWebKey.Kty"/> == JsonWebAlgorithmsKeyTypes.Octet</para> /// </remarks> protected virtual byte[] GetKeyBytes(SecurityKey key) { if (key == null) { throw LogHelper.LogArgumentNullException(nameof(key)); } if (key is SymmetricSecurityKey symmetricSecurityKey) { return(symmetricSecurityKey.Key); } if (key is JsonWebKey jsonWebKey && JsonWebKeyConverter.TryConvertToSymmetricSecurityKey(jsonWebKey, out SecurityKey securityKey)) { return(GetKeyBytes(securityKey)); } throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10667, key))); }