/// <summary> /// Initializes a new instance of the <see cref="RsaKeyWrapProvider"/> class used for wrap key and unwrap key. /// <param name="key">The <see cref="SecurityKey"/> that will be used for crypto operations.</param> /// <param name="algorithm">The KeyWrap algorithm to apply.</param> /// <param name="willUnwrap">Whether this <see cref="RsaKeyWrapProvider"/> is required to create decrypts then set this to true.</param> /// <exception cref="ArgumentNullException">'key' is null.</exception> /// <exception cref="ArgumentNullException">'algorithm' is null.</exception> /// <exception cref="ArgumentException">The keysize doesn't match the algorithm.</exception> /// <exception cref="ArgumentException">If <see cref="SecurityKey"/> and algorithm pair are not supported.</exception> /// <exception cref="InvalidOperationException">Failed to create RSA algorithm with provided key and algorithm.</exception> /// </summary> public RsaKeyWrapProvider(SecurityKey key, string algorithm, bool willUnwrap) { if (key == null) { throw LogHelper.LogArgumentNullException(nameof(key)); } if (string.IsNullOrEmpty(algorithm)) { throw LogHelper.LogArgumentNullException(nameof(algorithm)); } if (!IsSupportedAlgorithm(key, algorithm)) { throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10661, algorithm, key))); } Algorithm = algorithm; Key = key; var rsaAlgorithm = Utility.ResolveRsaAlgorithm(key, algorithm, willUnwrap); #if NETSTANDARD1_4 if (rsaAlgorithm != null && rsaAlgorithm.rsa != null) { _rsa = rsaAlgorithm.rsa; _disposeRsa = rsaAlgorithm.dispose; return; } #else if (rsaAlgorithm != null) { if (rsaAlgorithm.rsaCryptoServiceProvider != null) { _rsaCryptoServiceProvider = rsaAlgorithm.rsaCryptoServiceProvider; _disposeRsa = rsaAlgorithm.dispose; return; } if (rsaAlgorithm.rsaCryptoServiceProviderProxy != null) { _rsaCryptoServiceProviderProxy = rsaAlgorithm.rsaCryptoServiceProviderProxy; _disposeRsa = rsaAlgorithm.dispose; return; } } #endif throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10661, algorithm, key))); }
private void ResolveAsymmetricAlgorithm(SecurityKey key, string algorithm, bool willCreateSignatures) { if (key == null) { throw LogHelper.LogArgumentNullException("key"); } if (string.IsNullOrWhiteSpace(algorithm)) { throw LogHelper.LogArgumentNullException("algorithm"); } _hashAlgorithm = GetHashAlgorithmString(algorithm); RsaAlgorithm rsaAlgorithm = Utility.ResolveRsaAlgorithm(key, algorithm, willCreateSignatures); if (rsaAlgorithm != null) { if (rsaAlgorithm.rsaCryptoServiceProvider != null) { _rsaCryptoServiceProvider = rsaAlgorithm.rsaCryptoServiceProvider; _disposeRsa = rsaAlgorithm.dispose; return; } else if (rsaAlgorithm.rsaCryptoServiceProviderProxy != null) { _rsaCryptoServiceProviderProxy = rsaAlgorithm.rsaCryptoServiceProviderProxy; _disposeRsa = rsaAlgorithm.dispose; return; } else { throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10641, key))); } } ECDsaAlgorithm ecdsaAlgorithm = Utility.ResolveECDsaAlgorithm(key, algorithm, willCreateSignatures); if (ecdsaAlgorithm != null && ecdsaAlgorithm.ecdsaCng != null) { _ecdsa = ecdsaAlgorithm.ecdsaCng; _ecdsa.HashAlgorithm = new CngAlgorithm(_hashAlgorithm); _disposeEcdsa = ecdsaAlgorithm.dispose; return; } throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10641, key))); }
private void InitializeUsingRsa(RSA rsa, string algorithm) { #if NET461 || NETSTANDARD2_0 if (algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha256, StringComparison.Ordinal) || algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha256Signature, StringComparison.Ordinal) || algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha384, StringComparison.Ordinal) || algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha384Signature, StringComparison.Ordinal) || algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha512, StringComparison.Ordinal) || algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha512Signature, StringComparison.Ordinal)) { RSASignaturePadding = RSASignaturePadding.Pss; } else { // default RSASignaturePadding for other supported RSA algorithms is Pkcs1 RSASignaturePadding = RSASignaturePadding.Pkcs1; } #endif // This case is the result of a calling // X509Certificate2.GetPrivateKey OR X509Certificate2.GetPublicKey.Key // These calls return an AsymmetricAlgorithm which doesn't have API's to do much and need to be cast. // RSACryptoServiceProvider is wrapped to support SHA2 // RSACryptoServiceProviderProxy is only supported on Windows platform #if DESKTOP _useRSAOeapPadding = algorithm.Equals(SecurityAlgorithms.RsaOAEP, StringComparison.Ordinal) || algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap, StringComparison.Ordinal); if (rsa is RSACryptoServiceProvider rsaCryptoServiceProvider) { RsaCryptoServiceProviderProxy = new RSACryptoServiceProviderProxy(rsaCryptoServiceProvider); SignatureFunction = SignWithRsaCryptoServiceProviderProxy; VerifyFunction = VerifyWithRsaCryptoServiceProviderProxy; // RSACryptoServiceProviderProxy will keep track of if it creates a new RSA object. // Only if a new RSA was creaated, RSACryptoServiceProviderProxy will call RSA.Dispose(). _disposeCryptoOperators = true; return; } #endif // This case required the user to get a RSA object by calling // X509Certificate2.GetRSAPrivateKey() OR X509Certificate2.GetRSAPublicKey() // This requires 4.6+ to be installed. If a dependent library is targeting 4.5, 4.5.1, 4.5.2 or 4.6 // they will use Net45, but the type is RSACng. // The 'lightup' code will bind to the correct operators. #if NET45 else if (rsa.GetType().ToString().Equals(_rsaCngTypeName, StringComparison.Ordinal) && IsRsaCngSupported()) { _lightUpHashAlgorithmName = GetLightUpHashAlgorithmName(); SignatureFunction = Pkcs1SignData; VerifyFunction = Pkcs1VerifyData; return; } else { // In NET45 we only support RSACryptoServiceProvider or "System.Security.Cryptography.RSACng" throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10687, typeof(RSACryptoServiceProvider).ToString(), _rsaCngTypeName, rsa.GetType().ToString()))); } #endif #if NET461 || NETSTANDARD2_0 // Here we can use RSA straight up. _rsaEncryptionPadding = (algorithm.Equals(SecurityAlgorithms.RsaOAEP, StringComparison.Ordinal) || algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap, StringComparison.Ordinal)) ? RSAEncryptionPadding.OaepSHA1 : RSAEncryptionPadding.Pkcs1; RSA = rsa; SignatureFunction = SignWithRsa; VerifyFunction = VerifyWithRsa; #endif }
public RsaAlgorithm(RSACryptoServiceProviderProxy rsaCryptoServiceProviderProxy) { RsaCryptoServiceProviderProxy = rsaCryptoServiceProviderProxy; }
private void InitializeUsingRsa(RSA rsa, string algorithm) { // The return value for X509Certificate2.GetPrivateKey OR X509Certificate2.GetPublicKey.Key is a RSACryptoServiceProvider // These calls return an AsymmetricAlgorithm which doesn't have API's to do much and need to be cast. // RSACryptoServiceProvider is wrapped with RSACryptoServiceProviderProxy as some CryptoServideProviders (CSP's) do // not natively support SHA2. #if DESKTOP if (rsa is RSACryptoServiceProvider rsaCryptoServiceProvider) { _useRSAOeapPadding = algorithm.Equals(SecurityAlgorithms.RsaOAEP) || algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap); RsaCryptoServiceProviderProxy = new RSACryptoServiceProviderProxy(rsaCryptoServiceProvider); DecryptFunction = DecryptWithRsaCryptoServiceProviderProxy; EncryptFunction = EncryptWithRsaCryptoServiceProviderProxy; SignatureFunction = SignWithRsaCryptoServiceProviderProxy; VerifyFunction = VerifyWithRsaCryptoServiceProviderProxy; // RSACryptoServiceProviderProxy will track if a new RSA object is created and dispose appropriately. _disposeCryptoOperators = true; return; } #endif #if NET45 // This case required the user to get a RSA object by calling // X509Certificate2.GetRSAPrivateKey() OR X509Certificate2.GetRSAPublicKey() // This requires 4.6+ to be installed. If a dependent library is targeting 4.5, 4.5.1, 4.5.2 or 4.6 // they will bind to our Net45 target, but the type is RSACng. // The 'lightup' code will bind to the correct operators. else if (rsa.GetType().ToString().Equals(_rsaCngTypeName) && IsRsaCngSupported()) { _useRSAOeapPadding = algorithm.Equals(SecurityAlgorithms.RsaOAEP) || algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap); _lightUpHashAlgorithmName = GetLightUpHashAlgorithmName(); DecryptFunction = DecryptNet45; EncryptFunction = EncryptNet45; SignatureFunction = Pkcs1SignData; VerifyFunction = Pkcs1VerifyData; RSA = rsa; return; } else { // In NET45 we only support RSACryptoServiceProvider or "System.Security.Cryptography.RSACng" throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10687, LogHelper.MarkAsNonPII(typeof(RSACryptoServiceProvider).ToString()), LogHelper.MarkAsNonPII(_rsaCngTypeName), LogHelper.MarkAsNonPII(rsa.GetType().ToString())))); } #endif #if NET461 || NET472 || NETSTANDARD2_0 if (algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha256) || algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha256Signature) || algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha384) || algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha384Signature) || algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha512) || algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha512Signature)) { RSASignaturePadding = RSASignaturePadding.Pss; } else { // default RSASignaturePadding for other supported RSA algorithms is Pkcs1 RSASignaturePadding = RSASignaturePadding.Pkcs1; } RSAEncryptionPadding = (algorithm.Equals(SecurityAlgorithms.RsaOAEP) || algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap)) ? RSAEncryptionPadding.OaepSHA1 : RSAEncryptionPadding.Pkcs1; RSA = rsa; DecryptFunction = DecryptWithRsa; EncryptFunction = EncryptWithRsa; SignatureFunction = SignWithRsa; VerifyFunction = VerifyWithRsa; #endif }
private void ResolveAsymmetricAlgorithm(SecurityKey key, string algorithm, bool willCreateSignatures) { if (key == null) { throw LogHelper.LogArgumentNullException("key"); } if (string.IsNullOrWhiteSpace(algorithm)) { throw LogHelper.LogArgumentNullException("algorithm"); } _hashAlgorithm = GetHashAlgorithmString(algorithm); RsaSecurityKey rsaKey = key as RsaSecurityKey; if (rsaKey != null) { if (rsaKey.Rsa != null) { _rsaCryptoServiceProvider = rsaKey.Rsa as RSACryptoServiceProvider; } if (_rsaCryptoServiceProvider == null) { _rsaCryptoServiceProvider = new RSACryptoServiceProvider(); (_rsaCryptoServiceProvider as RSA).ImportParameters(rsaKey.Parameters); _disposeRsa = true; } return; } X509SecurityKey x509Key = key as X509SecurityKey; if (x509Key != null) { if (willCreateSignatures) { _rsaCryptoServiceProviderProxy = new RSACryptoServiceProviderProxy(x509Key.PrivateKey as RSACryptoServiceProvider); } else { _rsaCryptoServiceProviderProxy = new RSACryptoServiceProviderProxy(x509Key.PublicKey as RSACryptoServiceProvider); } return; } ECDsaSecurityKey ecdsaKey = key as ECDsaSecurityKey; if (ecdsaKey != null) { if (ecdsaKey.ECDsa != null) { _ecdsa = ecdsaKey.ECDsa as ECDsaCng; _ecdsa.HashAlgorithm = new CngAlgorithm(_hashAlgorithm); return; } } JsonWebKey webKey = key as JsonWebKey; if (webKey.Kty == JsonWebAlgorithmsKeyTypes.RSA) { RSAParameters parameters = CreateRsaParametersFromJsonWebKey(webKey, willCreateSignatures); _rsaCryptoServiceProvider = new RSACryptoServiceProvider(); (_rsaCryptoServiceProvider as RSA).ImportParameters(parameters); return; } else if (webKey.Kty == JsonWebAlgorithmsKeyTypes.EllipticCurve) { CreateECDsaFromJsonWebKey(webKey, willCreateSignatures); return; } throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(key), String.Format(CultureInfo.InvariantCulture, LogMessages.IDX10641, key))); }
private void ResolveAsymmetricAlgorithm(SecurityKey key, string algorithm, bool willCreateSignatures) { if (key == null) { throw LogHelper.LogArgumentNullException("key"); } if (string.IsNullOrWhiteSpace(algorithm)) { throw LogHelper.LogArgumentNullException("algorithm"); } _hashAlgorithm = GetHashAlgorithmName(algorithm); RsaSecurityKey rsaKey = key as RsaSecurityKey; if (rsaKey != null) { if (rsaKey.Rsa != null) { _rsa = rsaKey.Rsa; return; } _rsa = RSA.Create(); if (_rsa != null) { _rsa.ImportParameters(rsaKey.Parameters); _disposeRsa = true; return; } } X509SecurityKey x509Key = key as X509SecurityKey; if (x509Key != null) { if (willCreateSignatures) { RSACryptoServiceProvider rsaCsp = x509Key.PrivateKey as RSACryptoServiceProvider; if (rsaCsp != null) { _rsaCryptoServiceProviderProxy = new RSACryptoServiceProviderProxy(rsaCsp); } else { _rsa = x509Key.PrivateKey as RSA; } } else { _rsa = x509Key.PublicKey as RSA; } return; } ECDsaSecurityKey ecdsaKey = key as ECDsaSecurityKey; if (ecdsaKey != null) { if (ecdsaKey.ECDsa != null) { _ecdsa = ecdsaKey.ECDsa; return; } } JsonWebKey webKey = key as JsonWebKey; if (webKey.Kty == JsonWebAlgorithmsKeyTypes.RSA) { RSAParameters parameters = CreateRsaParametersFromJsonWebKey(webKey, willCreateSignatures); _rsa = RSA.Create(); if (_rsa != null) { _rsa.ImportParameters(parameters); _disposeRsa = true; return; } } else if (webKey.Kty == JsonWebAlgorithmsKeyTypes.EllipticCurve) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { throw new PlatformNotSupportedException(); } CreateECDsaFromJsonWebKey(webKey, willCreateSignatures); return; } throw LogHelper.LogArgumentException <ArgumentOutOfRangeException>(nameof(key), LogMessages.IDX10641, key); }