/// <summary> /// Convert RSA security key into json web key. /// </summary> /// <param name="key">RSA security key</param> /// <returns>json web key</returns> public static JsonWebKey ConvertFromRSASecurityKey(RsaSecurityKey key) { var jsonWebKey = new JsonWebKey(); var parameters = new RSAParameters(); jsonWebKey.Kty = JsonWebAlgorithmsKeyTypes.RSA; jsonWebKey.Kid = key.KeyId; // get Parameters if (key.Rsa != null) { parameters = key.Rsa.ExportParameters(true); } else { parameters = key.Parameters; } jsonWebKey.N = parameters.Modulus != null?Base64UrlEncoder.Encode(parameters.Modulus) : null; jsonWebKey.E = parameters.Exponent != null?Base64UrlEncoder.Encode(parameters.Exponent) : null; jsonWebKey.D = parameters.D != null?Base64UrlEncoder.Encode(parameters.D) : null; jsonWebKey.P = parameters.P != null?Base64UrlEncoder.Encode(parameters.P) : null; jsonWebKey.Q = parameters.Q != null?Base64UrlEncoder.Encode(parameters.Q) : null; jsonWebKey.DP = parameters.DP != null?Base64UrlEncoder.Encode(parameters.DP) : null; jsonWebKey.DQ = parameters.DQ != null?Base64UrlEncoder.Encode(parameters.DQ) : null; jsonWebKey.QI = parameters.InverseQ != null?Base64UrlEncoder.Encode(parameters.InverseQ) : null; return(jsonWebKey); }
internal RSAParameters CreateRsaParameters() { if (string.IsNullOrEmpty(N)) { throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10700, this, "Modulus"))); } if (string.IsNullOrEmpty(E)) { throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10700, this, "Exponent"))); } return(new RSAParameters { Modulus = Base64UrlEncoder.DecodeBytes(N), Exponent = Base64UrlEncoder.DecodeBytes(E), D = string.IsNullOrEmpty(D) ? null : Base64UrlEncoder.DecodeBytes(D), P = string.IsNullOrEmpty(P) ? null : Base64UrlEncoder.DecodeBytes(P), Q = string.IsNullOrEmpty(Q) ? null : Base64UrlEncoder.DecodeBytes(Q), DP = string.IsNullOrEmpty(DP) ? null : Base64UrlEncoder.DecodeBytes(DP), DQ = string.IsNullOrEmpty(DQ) ? null : Base64UrlEncoder.DecodeBytes(DQ), InverseQ = string.IsNullOrEmpty(QI) ? null : Base64UrlEncoder.DecodeBytes(QI) }); }
/// <summary> /// Computes a sha256 hash over the <see cref="RsaSecurityKey"/>. /// </summary> /// <returns>A JWK thumbprint.</returns> /// <remarks>https://tools.ietf.org/html/rfc7638</remarks> public override byte[] ComputeJwkThumbprint() { var rsaParameters = Parameters; if (rsaParameters.Exponent == null || rsaParameters.Modulus == null) { rsaParameters = Rsa.ExportParameters(false); } var canonicalJwk = $@"{{""{JsonWebKeyParameterNames.E}"":""{Base64UrlEncoder.Encode(rsaParameters.Exponent)}"",""{JsonWebKeyParameterNames.Kty}"":""{JsonWebAlgorithmsKeyTypes.RSA}"",""{JsonWebKeyParameterNames.N}"":""{Base64UrlEncoder.Encode(rsaParameters.Modulus)}""}}"; return(Utility.GenerateSha256Hash(canonicalJwk)); }
/// <summary> /// Instantiates a <see cref="X509SecurityKey"/> using a <see cref="X509Certificate2"/>. /// </summary> /// <param name="certificate">The <see cref="X509Certificate2"/> to use.</param> /// <param name="keyId">The value to set for the KeyId</param> /// <exception cref="ArgumentNullException">if <paramref name="certificate"/> is null.</exception> /// <exception cref="ArgumentNullException">if <paramref name="keyId"/> is null or empty.</exception> public X509SecurityKey(X509Certificate2 certificate, string keyId) { Certificate = certificate ?? throw LogHelper.LogArgumentNullException(nameof(certificate)); KeyId = string.IsNullOrEmpty(keyId) ? throw LogHelper.LogArgumentNullException(nameof(keyId)) : keyId; X5t = Base64UrlEncoder.Encode(certificate.GetCertHash()); }
/// <summary> /// Instantiates a <see cref="X509SecurityKey"/> using a <see cref="X509Certificate2"/> /// </summary> /// <param name="certificate">The <see cref="X509Certificate2"/> to use.</param> /// <exception cref="ArgumentNullException">if <paramref name="certificate"/> is null.</exception> public X509SecurityKey(X509Certificate2 certificate) { Certificate = certificate ?? throw LogHelper.LogArgumentNullException(nameof(certificate)); KeyId = certificate.Thumbprint; X5t = Base64UrlEncoder.Encode(certificate.GetCertHash()); }
internal ECDsaCng CreateECDsa(string algorithm, bool usePrivateKey) { if (Crv == null) { throw LogHelper.LogArgumentNullException(nameof(Crv)); } if (X == null) { throw LogHelper.LogArgumentNullException(nameof(X)); } if (Y == null) { throw LogHelper.LogArgumentNullException(nameof(Y)); } GCHandle keyBlobHandle = new GCHandle(); try { uint dwMagic = GetMagicValue(Crv, usePrivateKey); uint cbKey = GetKeyByteCount(Crv); byte[] keyBlob; if (usePrivateKey) { keyBlob = new byte[3 * cbKey + 2 * Marshal.SizeOf(typeof(uint))]; } else { keyBlob = new byte[2 * cbKey + 2 * Marshal.SizeOf(typeof(uint))]; } keyBlobHandle = GCHandle.Alloc(keyBlob, GCHandleType.Pinned); IntPtr keyBlobPtr = keyBlobHandle.AddrOfPinnedObject(); byte[] x = Base64UrlEncoder.DecodeBytes(X); byte[] y = Base64UrlEncoder.DecodeBytes(Y); Marshal.WriteInt64(keyBlobPtr, 0, dwMagic); Marshal.WriteInt64(keyBlobPtr, 4, cbKey); int index = 8; foreach (byte b in x) { Marshal.WriteByte(keyBlobPtr, index++, b); } foreach (byte b in y) { Marshal.WriteByte(keyBlobPtr, index++, b); } if (usePrivateKey) { if (D == null) { throw LogHelper.LogArgumentNullException(nameof(D)); } byte[] d = Base64UrlEncoder.DecodeBytes(D); foreach (byte b in d) { Marshal.WriteByte(keyBlobPtr, index++, b); } Marshal.Copy(keyBlobPtr, keyBlob, 0, keyBlob.Length); using (CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPrivateBlob)) { if (Utility.ValidateECDSAKeySize(cngKey.KeySize, algorithm)) { return(new ECDsaCng(cngKey)); } else { throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException("key.KeySize", String.Format(CultureInfo.InvariantCulture, LogMessages.IDX10671, cngKey, ECDsaAlgorithm.DefaultECDsaKeySizeInBitsMap[algorithm], cngKey.KeySize))); } } } else { Marshal.Copy(keyBlobPtr, keyBlob, 0, keyBlob.Length); using (CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPublicBlob)) { if (Utility.ValidateECDSAKeySize(cngKey.KeySize, algorithm)) { return(new ECDsaCng(cngKey)); } else { throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException("key.KeySize", String.Format(CultureInfo.InvariantCulture, LogMessages.IDX10671, cngKey, ECDsaAlgorithm.DefaultECDsaKeySizeInBitsMap[algorithm], cngKey.KeySize))); } } } } finally { if (keyBlobHandle != null) { keyBlobHandle.Free(); } } }
/// <summary> /// Computes a sha256 hash over the <see cref="ECDsaSecurityKey"/>. /// </summary> /// <returns>A JWK thumbprint.</returns> /// <remarks>https://tools.ietf.org/html/rfc7638</remarks> public override byte[] ComputeJwkThumbprint() { #if NET472 || NETSTANDARD2_0 if (ECDsaAdapter.SupportsECParameters()) { ECParameters parameters = ECDsa.ExportParameters(false); var canonicalJwk = $@"{{""{JsonWebKeyParameterNames.Crv}"":""{ECDsaAdapter.GetCrvParameterValue(parameters.Curve)}"",""{JsonWebKeyParameterNames.Kty}"":""{JsonWebAlgorithmsKeyTypes.EllipticCurve}"",""{JsonWebKeyParameterNames.X}"":""{Base64UrlEncoder.Encode(parameters.Q.X)}"",""{JsonWebKeyParameterNames.Y}"":""{Base64UrlEncoder.Encode(parameters.Q.Y)}""}}"; return(Utility.GenerateSha256Hash(canonicalJwk)); } #endif throw LogHelper.LogExceptionMessage(new PlatformNotSupportedException(LogMessages.IDX10695)); }
/// <summary> /// Computes a sha256 hash over the <see cref="SymmetricSecurityKey"/>. /// </summary> /// <returns>A JWK thumbprint.</returns> /// <remarks>https://datatracker.ietf.org/doc/html/rfc7638</remarks> public override byte[] ComputeJwkThumbprint() { var canonicalJwk = $@"{{""{JsonWebKeyParameterNames.K}"":""{Base64UrlEncoder.Encode(Key)}"",""{JsonWebKeyParameterNames.Kty}"":""{JsonWebAlgorithmsKeyTypes.Octet}""}}"; return(Utility.GenerateSha256Hash(canonicalJwk)); }
/// <summary> /// Creates an ECDsa object using the <paramref name="jsonWebKey"/> and <paramref name="usePrivateKey"/>. /// 'ECParameters' structure is available in .NET Framework 4.7+, .NET Standard 1.6+, and .NET Core 1.0+. /// This method is supported only on Windows as other platforms don't support operations with <see cref="CngKey"/>. /// </summary> private ECDsa CreateECDsaUsingCNGKey(JsonWebKey jsonWebKey, bool usePrivateKey) { if (jsonWebKey == null) { throw LogHelper.LogArgumentNullException(nameof(jsonWebKey)); } if (jsonWebKey.Crv == null) { throw LogHelper.LogArgumentNullException(nameof(jsonWebKey.Crv)); } if (jsonWebKey.X == null) { throw LogHelper.LogArgumentNullException(nameof(jsonWebKey.X)); } if (jsonWebKey.Y == null) { throw LogHelper.LogArgumentNullException(nameof(jsonWebKey.Y)); } GCHandle keyBlobHandle = new GCHandle(); try { uint dwMagic = GetMagicValue(jsonWebKey.Crv, usePrivateKey); uint cbKey = GetKeyByteCount(jsonWebKey.Crv); byte[] keyBlob; #if NET45 if (usePrivateKey) { keyBlob = new byte[3 * cbKey + 2 * Marshal.SizeOf(typeof(uint))]; } else { keyBlob = new byte[2 * cbKey + 2 * Marshal.SizeOf(typeof(uint))]; } #else if (usePrivateKey) { keyBlob = new byte[3 * cbKey + 2 * Marshal.SizeOf <uint>()]; } else { keyBlob = new byte[2 * cbKey + 2 * Marshal.SizeOf <uint>()]; } #endif keyBlobHandle = GCHandle.Alloc(keyBlob, GCHandleType.Pinned); IntPtr keyBlobPtr = keyBlobHandle.AddrOfPinnedObject(); byte[] x = Base64UrlEncoder.DecodeBytes(jsonWebKey.X); if (x.Length > cbKey) { throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(jsonWebKey), LogHelper.FormatInvariant(LogMessages.IDX10675, nameof(jsonWebKey), nameof(jsonWebKey.X), cbKey, x.Length))); } byte[] y = Base64UrlEncoder.DecodeBytes(jsonWebKey.Y); if (y.Length > cbKey) { throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(jsonWebKey), LogHelper.FormatInvariant(LogMessages.IDX10675, nameof(jsonWebKey), nameof(jsonWebKey.Y), cbKey, y.Length))); } Marshal.WriteInt64(keyBlobPtr, 0, dwMagic); Marshal.WriteInt64(keyBlobPtr, 4, cbKey); int index = 8; foreach (byte b in x) { Marshal.WriteByte(keyBlobPtr, index++, b); } foreach (byte b in y) { Marshal.WriteByte(keyBlobPtr, index++, b); } if (usePrivateKey) { if (jsonWebKey.D == null) { throw LogHelper.LogArgumentNullException(nameof(jsonWebKey.D)); } byte[] d = Base64UrlEncoder.DecodeBytes(jsonWebKey.D); if (d.Length > cbKey) { throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(jsonWebKey), LogHelper.FormatInvariant(LogMessages.IDX10675, nameof(jsonWebKey), nameof(jsonWebKey.D), cbKey, d.Length))); } foreach (byte b in d) { Marshal.WriteByte(keyBlobPtr, index++, b); } Marshal.Copy(keyBlobPtr, keyBlob, 0, keyBlob.Length); using (CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPrivateBlob)) { return(new ECDsaCng(cngKey)); } } else { Marshal.Copy(keyBlobPtr, keyBlob, 0, keyBlob.Length); using (CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPublicBlob)) { return(new ECDsaCng(cngKey)); } } } catch (Exception ex) { throw LogHelper.LogExceptionMessage(new CryptographicException(LogMessages.IDX10689, ex)); } finally { if (keyBlobHandle != null && keyBlobHandle.IsAllocated) { keyBlobHandle.Free(); } } }
/// <summary> /// Decrypts ciphertext into plaintext /// </summary> /// <param name="ciphertext">the encrypted text to decrypt.</param> /// <param name="authenticatedData">the authenticateData that is used in verification.</param> /// <param name="iv">the initialization vector used when creating the ciphertext.</param> /// <param name="authenticationTag">the authenticationTag that was created during the encyption.</param> /// <returns>decrypted ciphertext</returns> /// <exception cref="ArgumentNullException">'ciphertext' is null or empty.</exception> /// <exception cref="ArgumentNullException">'authenticatedData' is null or empty.</exception> /// <exception cref="ArgumentNullException">'iv' is null or empty.</exception> /// <exception cref="ArgumentNullException">'authenticationTag' is null or empty.</exception> /// <exception cref="SecurityTokenDecryptionFailedException">signature over authenticationTag fails to verify.</exception> /// <exception cref="SecurityTokenDecryptionFailedException">AES crypto operation threw. See inner exception.</exception> public virtual byte[] Decrypt(byte[] ciphertext, byte[] authenticatedData, byte[] iv, byte[] authenticationTag) { if (ciphertext == null || ciphertext.Length == 0) { throw LogHelper.LogArgumentNullException(nameof(ciphertext)); } if (authenticatedData == null || authenticatedData.Length == 0) { throw LogHelper.LogArgumentNullException(nameof(authenticatedData)); } if (iv == null || iv.Length == 0) { throw LogHelper.LogArgumentNullException(nameof(iv)); } if (authenticationTag == null || authenticationTag.Length == 0) { throw LogHelper.LogArgumentNullException(nameof(authenticationTag)); } // Verify authentication Tag byte[] al = Utility.ConvertToBigEndian(authenticatedData.Length * 8); byte[] macBytes = new byte[authenticatedData.Length + iv.Length + ciphertext.Length + al.Length]; Array.Copy(authenticatedData, 0, macBytes, 0, authenticatedData.Length); Array.Copy(iv, 0, macBytes, authenticatedData.Length, iv.Length); Array.Copy(ciphertext, 0, macBytes, authenticatedData.Length + iv.Length, ciphertext.Length); Array.Copy(al, 0, macBytes, authenticatedData.Length + iv.Length + ciphertext.Length, al.Length); if (!_symmetricSignatureProvider.Verify(macBytes, authenticationTag, _authenticatedkeys.HmacKey.Key.Length)) { throw LogHelper.LogExceptionMessage(new SecurityTokenDecryptionFailedException(string.Format(CultureInfo.InvariantCulture, LogMessages.IDX10650, Base64UrlEncoder.Encode(authenticatedData), Base64UrlEncoder.Encode(iv), Base64UrlEncoder.Encode(authenticationTag)))); } Aes aes = Aes.Create(); aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; aes.Key = _authenticatedkeys.AesKey.Key; aes.IV = iv; try { return(Utility.Transform(aes.CreateDecryptor(), ciphertext, 0, ciphertext.Length)); } catch (Exception ex) { throw LogHelper.LogExceptionMessage(new SecurityTokenDecryptionFailedException(string.Format(CultureInfo.InvariantCulture, LogMessages.IDX10654, ex))); } }
/// <summary> /// Instantiates a <see cref="SecurityKey"/> using a <see cref="X509Certificate2"/> /// </summary> /// <param name="certificate">The cert to use.</param> public X509SecurityKey(X509Certificate2 certificate) { _certificate = certificate ?? throw LogHelper.LogExceptionMessage(new ArgumentNullException(nameof(certificate))); KeyId = Base64UrlEncoder.Encode(certificate.GetCertHash()); X5t = Base64UrlEncoder.Encode(certificate.GetCertHash()); }
/// <summary> /// Returns the JsonWebKeys as a <see cref="IList{SecurityKey}"/>. /// </summary> public IList <SecurityKey> GetSigningKeys() { List <SecurityKey> keys = new List <SecurityKey>(); for (int i = 0; i < Keys.Count; i++) { JsonWebKey webKey = Keys[i]; if (!StringComparer.Ordinal.Equals(webKey.Kty, JsonWebAlgorithmsKeyTypes.RSA)) { continue; } if ((string.IsNullOrWhiteSpace(webKey.Use) || (StringComparer.Ordinal.Equals(webKey.Use, JsonWebKeyUseNames.Sig)))) { if (webKey.X5c != null) { foreach (var certString in webKey.X5c) { try { // Add chaining SecurityKey key = new X509SecurityKey(new X509Certificate2(Convert.FromBase64String(certString))); key.KeyId = webKey.Kid; keys.Add(key); } catch (CryptographicException ex) { throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10802, webKey.X5c[0]), ex)); } catch (FormatException fex) { throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10802, webKey.X5c[0]), fex)); } } } if (!string.IsNullOrWhiteSpace(webKey.E) && !string.IsNullOrWhiteSpace(webKey.N)) { try { SecurityKey key = new RsaSecurityKey ( new RSAParameters { Exponent = Base64UrlEncoder.DecodeBytes(webKey.E), Modulus = Base64UrlEncoder.DecodeBytes(webKey.N), } ); key.KeyId = webKey.Kid; keys.Add(key); } catch (CryptographicException ex) { throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10801, webKey.E, webKey.N), ex)); } catch (FormatException ex) { throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10801, webKey.E, webKey.N), ex)); } } } } return(keys); }
/// <summary> /// Converts a <see cref="RsaSecurityKey"/> into a <see cref="JsonWebKey"/> /// </summary> /// <param name="key">a <see cref="RsaSecurityKey"/> to convert.</param> /// <returns>a <see cref="JsonWebKey"/></returns> /// <exception cref="ArgumentNullException">if <paramref name="key"/>is null.</exception> public static JsonWebKey ConvertFromRSASecurityKey(RsaSecurityKey key) { if (key == null) { throw LogHelper.LogArgumentNullException(nameof(key)); } RSAParameters parameters; if (key.Rsa != null) { try { parameters = key.Rsa.ExportParameters(true); } catch { parameters = key.Rsa.ExportParameters(false); } } else { parameters = key.Parameters; } return(new JsonWebKey { N = parameters.Modulus != null?Base64UrlEncoder.Encode(parameters.Modulus) : null, E = parameters.Exponent != null?Base64UrlEncoder.Encode(parameters.Exponent) : null, D = parameters.D != null?Base64UrlEncoder.Encode(parameters.D) : null, P = parameters.P != null?Base64UrlEncoder.Encode(parameters.P) : null, Q = parameters.Q != null?Base64UrlEncoder.Encode(parameters.Q) : null, DP = parameters.DP != null?Base64UrlEncoder.Encode(parameters.DP) : null, DQ = parameters.DQ != null?Base64UrlEncoder.Encode(parameters.DQ) : null, QI = parameters.InverseQ != null?Base64UrlEncoder.Encode(parameters.InverseQ) : null, Kty = JsonWebAlgorithmsKeyTypes.RSA, Kid = key.KeyId, ConvertedSecurityKey = key }); }
internal ECDsa CreateECDsa(string algorithm, bool usePrivateKey) { #if !WINDOWS throw new NotImplementedException(LogMessages.IDX10676); #endif if (Crv == null) { throw LogHelper.LogArgumentNullException(nameof(Crv)); } if (X == null) { throw LogHelper.LogArgumentNullException(nameof(X)); } if (Y == null) { throw LogHelper.LogArgumentNullException(nameof(Y)); } GCHandle keyBlobHandle = new GCHandle(); try { uint dwMagic = GetMagicValue(Crv, usePrivateKey); uint cbKey = GetKeyByteCount(Crv); byte[] keyBlob; #if NET45 if (usePrivateKey) { keyBlob = new byte[3 * cbKey + 2 * Marshal.SizeOf(typeof(uint))]; } else { keyBlob = new byte[2 * cbKey + 2 * Marshal.SizeOf(typeof(uint))]; } #else if (usePrivateKey) { keyBlob = new byte[3 * cbKey + 2 * Marshal.SizeOf <uint>()]; } else { keyBlob = new byte[2 * cbKey + 2 * Marshal.SizeOf <uint>()]; } #endif keyBlobHandle = GCHandle.Alloc(keyBlob, GCHandleType.Pinned); IntPtr keyBlobPtr = keyBlobHandle.AddrOfPinnedObject(); byte[] x = Base64UrlEncoder.DecodeBytes(X); if (x.Length > cbKey) { throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException("x.Length", LogHelper.FormatInvariant(LogMessages.IDX10675, nameof(x), cbKey, x.Length))); } byte[] y = Base64UrlEncoder.DecodeBytes(Y); if (y.Length > cbKey) { throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException("y.Length", LogHelper.FormatInvariant(LogMessages.IDX10675, nameof(y), cbKey, y.Length))); } Marshal.WriteInt64(keyBlobPtr, 0, dwMagic); Marshal.WriteInt64(keyBlobPtr, 4, cbKey); int index = 8; foreach (byte b in x) { Marshal.WriteByte(keyBlobPtr, index++, b); } foreach (byte b in y) { Marshal.WriteByte(keyBlobPtr, index++, b); } if (usePrivateKey) { if (D == null) { throw LogHelper.LogArgumentNullException(nameof(D)); } byte[] d = Base64UrlEncoder.DecodeBytes(D); if (d.Length > cbKey) { throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException("d.Length", LogHelper.FormatInvariant(LogMessages.IDX10675, nameof(d), cbKey, d.Length))); } foreach (byte b in d) { Marshal.WriteByte(keyBlobPtr, index++, b); } Marshal.Copy(keyBlobPtr, keyBlob, 0, keyBlob.Length); using (CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPrivateBlob)) { return(new ECDsaCng(cngKey)); } } else { Marshal.Copy(keyBlobPtr, keyBlob, 0, keyBlob.Length); using (CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPublicBlob)) { return(new ECDsaCng(cngKey)); } } } finally { if (keyBlobHandle != null) { keyBlobHandle.Free(); } } }
private byte[] DecryptWithAesCbc(byte[] ciphertext, byte[] authenticatedData, byte[] iv, byte[] authenticationTag) { // Verify authentication Tag byte[] al = Utility.ConvertToBigEndian(authenticatedData.Length * 8); byte[] macBytes = new byte[authenticatedData.Length + iv.Length + ciphertext.Length + al.Length]; Array.Copy(authenticatedData, 0, macBytes, 0, authenticatedData.Length); Array.Copy(iv, 0, macBytes, authenticatedData.Length, iv.Length); Array.Copy(ciphertext, 0, macBytes, authenticatedData.Length + iv.Length, ciphertext.Length); Array.Copy(al, 0, macBytes, authenticatedData.Length + iv.Length + ciphertext.Length, al.Length); if (!_symmetricSignatureProvider.Value.Verify(macBytes, authenticationTag, _authenticatedkeys.Value.HmacKey.Key.Length)) { throw LogHelper.LogExceptionMessage(new SecurityTokenDecryptionFailedException(LogHelper.FormatInvariant(LogMessages.IDX10650, Base64UrlEncoder.Encode(authenticatedData), Base64UrlEncoder.Encode(iv), Base64UrlEncoder.Encode(authenticationTag)))); } using Aes aes = Aes.Create(); aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; aes.Key = _authenticatedkeys.Value.AesKey.Key; aes.IV = iv; try { return(Transform(aes.CreateDecryptor(), ciphertext, 0, ciphertext.Length)); } catch (Exception ex) { throw LogHelper.LogExceptionMessage(new SecurityTokenDecryptionFailedException(LogHelper.FormatInvariant(LogMessages.IDX10654, ex))); } }
private void CreateECDsaFromJsonWebKey(JsonWebKey webKey, bool willCreateSignatures) { if (webKey == null) { throw LogHelper.LogArgumentNullException(nameof(webKey)); } if (webKey.Crv == null) { throw LogHelper.LogArgumentNullException(nameof(webKey.Crv)); } if (webKey.X == null) { throw LogHelper.LogArgumentNullException(nameof(webKey.X)); } if (webKey.Y == null) { throw LogHelper.LogArgumentNullException(nameof(webKey.Y)); } GCHandle keyBlobHandle = new GCHandle(); try { uint dwMagic = GetMagicValue(webKey.Crv, willCreateSignatures); uint cbKey = GetKeyByteCount(webKey.Crv); byte[] keyBlob; if (willCreateSignatures) { keyBlob = new byte[3 * cbKey + 2 * Marshal.SizeOf <uint>()]; } else { keyBlob = new byte[2 * cbKey + 2 * Marshal.SizeOf <uint>()]; } keyBlobHandle = GCHandle.Alloc(keyBlob, GCHandleType.Pinned); IntPtr keyBlobPtr = keyBlobHandle.AddrOfPinnedObject(); byte[] x = Base64UrlEncoder.DecodeBytes(webKey.X); byte[] y = Base64UrlEncoder.DecodeBytes(webKey.Y); Marshal.WriteInt64(keyBlobPtr, 0, dwMagic); Marshal.WriteInt64(keyBlobPtr, 4, cbKey); int index = 8; foreach (byte b in x) { Marshal.WriteByte(keyBlobPtr, index++, b); } foreach (byte b in y) { Marshal.WriteByte(keyBlobPtr, index++, b); } if (willCreateSignatures) { if (webKey.D == null) { throw LogHelper.LogArgumentNullException(nameof(webKey.D)); } byte[] d = Base64UrlEncoder.DecodeBytes(webKey.D); foreach (byte b in d) { Marshal.WriteByte(keyBlobPtr, index++, b); } Marshal.Copy(keyBlobPtr, keyBlob, 0, keyBlob.Length); using (CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPrivateBlob)) { _ecdsa = new ECDsaCng(cngKey); _disposeEcdsa = true; } } else { Marshal.Copy(keyBlobPtr, keyBlob, 0, keyBlob.Length); using (CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPublicBlob)) { _ecdsa = new ECDsaCng(cngKey); _disposeEcdsa = true; } } } finally { if (keyBlobHandle != null) { keyBlobHandle.Free(); } } }