public CngKey GetOrGenerateKey(int keySize, CngAlgorithm algorithm) { ThrowIfDisposed(); // If our key size was changed, we need to generate a new key. if (_lazyKey != null) { if (_lazyKey.KeySize != keySize) { DisposeKey(); } } // If we don't have a key yet, we need to generate one now. if (_lazyKey == null) { CngKeyCreationParameters creationParameters = new CngKeyCreationParameters() { ExportPolicy = CngExportPolicies.AllowPlaintextExport, }; Span <byte> keySizeBuffer = stackalloc byte[sizeof(int)]; bool success = BitConverter.TryWriteBytes(keySizeBuffer, keySize); Debug.Assert(success); CngProperty keySizeProperty = new CngProperty(KeyPropertyName.Length, keySizeBuffer, CngPropertyOptions.None); creationParameters.Parameters.Add(keySizeProperty); _lazyKey = CngKey.Create(algorithm, null, creationParameters); } return(_lazyKey); }
public CngKey GetOrGenerateKey(int keySize, CngAlgorithm algorithm) { ThrowIfDisposed(); // If our key size was changed, we need to generate a new key. if (_lazyKey != null) { if (_lazyKey.KeySize != keySize) { DisposeKey(); } } // If we don't have a key yet, we need to generate one now. if (_lazyKey == null) { CngKeyCreationParameters creationParameters = new CngKeyCreationParameters() { ExportPolicy = CngExportPolicies.AllowPlaintextExport, }; CngProperty keySizeProperty = new CngProperty(KeyPropertyName.Length, BitConverter.GetBytes(keySize), CngPropertyOptions.None); creationParameters.Parameters.Add(keySizeProperty); _lazyKey = CngKey.Create(algorithm, null, creationParameters); } return(_lazyKey); }
public static CngKey Create(CngAlgorithm algorithm, string keyName, CngKeyCreationParameters creationParameters) { if (algorithm == null) { throw new ArgumentNullException("algorithm"); } if (creationParameters == null) { creationParameters = new CngKeyCreationParameters(); } if (!NCryptNative.NCryptSupported) { throw new PlatformNotSupportedException(System.SR.GetString("Cryptography_PlatformNotSupported")); } if (keyName != null) { KeyContainerPermissionAccessEntry accessEntry = new KeyContainerPermissionAccessEntry(keyName, KeyContainerPermissionFlags.Create) { ProviderName = creationParameters.Provider.Provider }; KeyContainerPermission permission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags); permission.AccessEntries.Add(accessEntry); permission.Demand(); } SafeNCryptProviderHandle provider = NCryptNative.OpenStorageProvider(creationParameters.Provider.Provider); SafeNCryptKeyHandle keyHandle = NCryptNative.CreatePersistedKey(provider, algorithm.Algorithm, keyName, creationParameters.KeyCreationOptions); SetKeyProperties(keyHandle, creationParameters); NCryptNative.FinalizeKey(keyHandle); CngKey key = new CngKey(provider, keyHandle); if (keyName == null) { key.IsEphemeral = true; } return key; }
static void Main(string[] args) { string keyName = "PA ECDSA Key"; byte[] publicKeyBytes, privateKeyBytes; CngKey cngKey; if (CngKey.Exists(keyName)) { cngKey = CngKey.Open(keyName); cngKey.Delete(); Console.WriteLine("Existing key deleted."); } CngKeyCreationParameters creationParameters = new CngKeyCreationParameters(); // Allow exporting private key as plaintext creationParameters.ExportPolicy = CngExportPolicies.AllowPlaintextExport; cngKey = CngKey.Create(CngAlgorithm.ECDsaP256, keyName, creationParameters); publicKeyBytes = cngKey.Export(CngKeyBlobFormat.EccPublicBlob); privateKeyBytes = cngKey.Export(CngKeyBlobFormat.EccPrivateBlob); Console.WriteLine("\n\nPrivate: " + Debugger.BytesToString(privateKeyBytes)); Console.WriteLine("\n\nPublic: " + Debugger.BytesToString(publicKeyBytes)); Console.WriteLine("\n\nPublic Base64: " + Convert.ToBase64String(publicKeyBytes)); Console.ReadKey(); }
private static void SetKeyProperties(SafeNCryptKeyHandle keyHandle, CngKeyCreationParameters creationParameters) { if (creationParameters.ExportPolicy.HasValue) { NCryptNative.SetProperty(keyHandle, "Export Policy", creationParameters.ExportPolicy.Value, CngPropertyOptions.None | CngPropertyOptions.Persist); } if (creationParameters.KeyUsage.HasValue) { NCryptNative.SetProperty(keyHandle, "Key Usage", creationParameters.KeyUsage.Value, CngPropertyOptions.None | CngPropertyOptions.Persist); } if (creationParameters.ParentWindowHandle != IntPtr.Zero) { NCryptNative.SetProperty <IntPtr>(keyHandle, "HWND Handle", creationParameters.ParentWindowHandle, CngPropertyOptions.None); } if (creationParameters.UIPolicy != null) { NCryptNative.NCRYPT_UI_POLICY ncrypt_ui_policy = new NCryptNative.NCRYPT_UI_POLICY { dwVersion = 1, dwFlags = creationParameters.UIPolicy.ProtectionLevel, pszCreationTitle = creationParameters.UIPolicy.CreationTitle, pszFriendlyName = creationParameters.UIPolicy.FriendlyName, pszDescription = creationParameters.UIPolicy.Description }; NCryptNative.SetProperty <NCryptNative.NCRYPT_UI_POLICY>(keyHandle, "UI Policy", ncrypt_ui_policy, CngPropertyOptions.None | CngPropertyOptions.Persist); if (creationParameters.UIPolicy.UseContext != null) { NCryptNative.SetProperty(keyHandle, "Use Context", creationParameters.UIPolicy.UseContext, CngPropertyOptions.None | CngPropertyOptions.Persist); } } foreach (CngProperty property in creationParameters.ParametersNoDemand) { NCryptNative.SetProperty(keyHandle, property.Name, property.Value, property.Options); } }
public CngKey GetOrGenerateKey(int keySize, CngAlgorithm algorithm) { // If our key size was changed, we need to generate a new key. if (_lazyKey != null) { if (_lazyKey.KeySize != keySize) DisposeKey(); } // If we don't have a key yet, we need to generate one now. if (_lazyKey == null) { CngKeyCreationParameters creationParameters = new CngKeyCreationParameters() { ExportPolicy = CngExportPolicies.AllowPlaintextExport, }; CngProperty keySizeProperty = new CngProperty(KeyPropertyName.Length, BitConverter.GetBytes(keySize), CngPropertyOptions.None); creationParameters.Parameters.Add(keySizeProperty); _lazyKey = CngKey.Create(algorithm, null, creationParameters); } return _lazyKey; }
public static CngKey Create(CngAlgorithm algorithm, string keyName, CngKeyCreationParameters creationParameters) { if (algorithm == null) throw new ArgumentNullException("algorithm"); if (creationParameters == null) creationParameters = new CngKeyCreationParameters(); SafeNCryptProviderHandle providerHandle = creationParameters.Provider.OpenStorageProvider(); SafeNCryptKeyHandle keyHandle; ErrorCode errorCode = Interop.NCrypt.NCryptCreatePersistedKey(providerHandle, out keyHandle, algorithm.Algorithm, keyName, 0, creationParameters.KeyCreationOptions); if (errorCode != ErrorCode.ERROR_SUCCESS) throw errorCode.ToCryptographicException(); InitializeKeyProperties(keyHandle, creationParameters); errorCode = Interop.NCrypt.NCryptFinalizeKey(keyHandle, 0); if (errorCode != ErrorCode.ERROR_SUCCESS) throw errorCode.ToCryptographicException(); CngKey key = new CngKey(providerHandle, keyHandle); // No name translates to an ephemeral key if (keyName == null) { key.IsEphemeral = true; } return key; }
public void TestEcdhKeys() { // To make sure keys are exportable: // http://stackoverflow.com/questions/20505325/how-to-export-private-key-for-ecdiffiehellmancng/20505976#20505976 var ecdhKeyParams = new CngKeyCreationParameters { KeyUsage = CngKeyUsages.AllUsages, ExportPolicy = CngExportPolicies.AllowPlaintextExport }; var ecdhKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256, null, ecdhKeyParams); var ecdh = new ECDiffieHellmanCng(ecdhKey); ecdh.KeySize = 256; //Export the keys var privateKey = ecdh.Key.Export(CngKeyBlobFormat.EccPrivateBlob); // This returns: // [ { MinSize = 256; MaxSize = 384; SkipSize = 128 } // { MinSize = 521; MaxSize = 521; SkipSize = 0 } ] var keySizes = ecdh.LegalKeySizes; // Example of this: // <ECDHKeyValue xmlns="http://www.w3.org/2001/04/xmldsig-more#"> // <DomainParameters> // <NamedCurve URN="urn:oid:1.3.132.0.35" /> // </DomainParameters> // <PublicKey> // <X Value="6338036285454860977775086861655185721418051140960904673987863656163882965225521398319125216217757952736756437624751684728661860413862054254572205453827782795" xsi:type="PrimeFieldElemType" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" /> // <Y Value="2429739115523607678822648112222739155064474393176967830414279652115290771735466025346855521196073509912224542851147234378090051353981358078708633637907317343" xsi:type="PrimeFieldElemType" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" /> // </PublicKey> // </ECDHKeyValue> var pubKeyXml = ecdh.PublicKey.ToXmlString(); }
public CngKey GetOrGenerateKey(ECCurve?curve) { ThrowIfDisposed(); if (_lazyKey != null) { return(_lazyKey); } // We don't have a key yet so generate Debug.Assert(curve.HasValue); CngKeyCreationParameters creationParameters = new CngKeyCreationParameters() { ExportPolicy = CngExportPolicies.AllowPlaintextExport, }; if (curve.Value.IsNamed) { creationParameters.Parameters.Add(CngKey.GetPropertyFromNamedCurve(curve.Value)); } else if (curve.Value.IsPrime) { ECCurve eccurve = curve.Value; byte[] parametersBlob = ECCng.GetPrimeCurveParameterBlob(ref eccurve); CngProperty prop = new CngProperty( Interop.BCrypt.BCryptPropertyStrings.BCRYPT_ECC_PARAMETERS, parametersBlob, CngPropertyOptions.None); creationParameters.Parameters.Add(prop); } else { throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CurveNotSupported, curve.Value.CurveType.ToString())); } try { _lazyKey = CngKey.Create(DefaultKeyType ?? CngAlgorithm.ECDsa, null, creationParameters); } catch (CryptographicException e) { // Map to PlatformNotSupportedException if appropriate ErrorCode errorCode = (ErrorCode)e.HResult; if (curve.Value.IsNamed && errorCode == ErrorCode.NTE_INVALID_PARAMETER || errorCode == ErrorCode.NTE_NOT_SUPPORTED) { throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CurveNotSupported, curve.Value.Oid.FriendlyName), e); } throw; } return(_lazyKey); }
public static CngKey Create(CngAlgorithm algorithm, string keyName, CngKeyCreationParameters creationParameters) { Contract.Ensures(Contract.Result <CngKey>() != null); if (algorithm == null) { throw new ArgumentNullException("algorithm"); } if (creationParameters == null) { creationParameters = new CngKeyCreationParameters(); } // Make sure that NCrypt is supported on this platform if (!NCryptNative.NCryptSupported) { throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported)); } // If we're not creating an ephemeral key, then we need to ensure the user has access to the key name if (keyName != null) { KeyContainerPermissionAccessEntry access = new KeyContainerPermissionAccessEntry(keyName, KeyContainerPermissionFlags.Create); access.ProviderName = creationParameters.Provider.Provider; KeyContainerPermission permission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags); permission.AccessEntries.Add(access); permission.Demand(); } // // Create the native handles representing the new key, setup the creation parameters on it, and // finalize it for use. // SafeNCryptProviderHandle kspHandle = NCryptNative.OpenStorageProvider(creationParameters.Provider.Provider); SafeNCryptKeyHandle keyHandle = NCryptNative.CreatePersistedKey(kspHandle, algorithm.Algorithm, keyName, creationParameters.KeyCreationOptions); SetKeyProperties(keyHandle, creationParameters); NCryptNative.FinalizeKey(keyHandle); CngKey key = new CngKey(kspHandle, keyHandle); // No name translates to an ephemeral key if (keyName == null) { key.IsEphemeral = true; } return(key); }
public ECDSASigner() //konstruktor do generowania klucza { keyCreationParameters = new CngKeyCreationParameters(); keyCreationParameters.ExportPolicy = CngExportPolicies.AllowExport; keyCreationParameters.KeyUsage = CngKeyUsages.Signing; keyCreationParameters.ExportPolicy = CngExportPolicies.AllowPlaintextExport; CngPrivateKey = CngKey.Create(CngAlgorithm.ECDsaP256, null, keyCreationParameters); ECDSA = new ECDsaCng(CngPrivateKey); this.privateKey = ECDSA.Key.Export(CngKeyBlobFormat.EccPrivateBlob); ECDSA.HashAlgorithm = CngAlgorithm.Sha256; }
/// <summary> /// Create a RSA based certificate (to be used with encryption) with the given options /// </summary> /// <param name="buildOptions">Allows for more advanced configuration</param> /// <returns>An exportable X509Certificate2 object (with private key)</returns> public static X509Certificate2 CreateNewCertificate(RSACertificateBuilderOptions buildOptions) { if (buildOptions == null) { throw new ArgumentNullException("buildOptions"); } string keyName = buildOptions.RSAKeyName ?? "RSAKey"; CngKey objCngKey = null; if (CngKey.Exists(keyName)) { objCngKey = CngKey.Open(keyName); objCngKey.Delete(); } var creationParameters = new CngKeyCreationParameters(); creationParameters.ExportPolicy = CngExportPolicies.AllowExport; creationParameters.KeyUsage = CngKeyUsages.AllUsages; creationParameters.Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider; var keySizeProperty = new CngProperty("Length", BitConverter.GetBytes(buildOptions.KeySize ?? 4096), CngPropertyOptions.None); creationParameters.Parameters.Add(keySizeProperty); objCngKey = CngKey.Create(CngAlgorithm2.Rsa, keyName, creationParameters); var name = new X500DistinguishedName(buildOptions.FullSubjectName); X509CertificateSignatureAlgorithm certAlg; switch (buildOptions.HashingMethod ?? HashingMethods.Sha256) { case HashingMethods.Sha1: certAlg = X509CertificateSignatureAlgorithm.RsaSha1; break; case HashingMethods.Sha256: certAlg = X509CertificateSignatureAlgorithm.RsaSha256; break; case HashingMethods.Sha384: certAlg = X509CertificateSignatureAlgorithm.RsaSha384; break; case HashingMethods.Sha512: certAlg = X509CertificateSignatureAlgorithm.RsaSha512; break; default: throw new InvalidOperationException("Selected hashing method is not supported"); } var options = new X509CertificateCreationParameters(name) { SignatureAlgorithm = certAlg, TakeOwnershipOfKey = true }; return objCngKey.CreateSelfSignedCertificate(options); }
/// <summary> /// Setup the key properties specified in the key creation parameters /// </summary> private static void InitializeKeyProperties(SafeNCryptKeyHandle keyHandle, CngKeyCreationParameters creationParameters) { unsafe { if (creationParameters.ExportPolicy.HasValue) { CngExportPolicies exportPolicy = creationParameters.ExportPolicy.Value; keyHandle.SetExportPolicy(exportPolicy); } if (creationParameters.KeyUsage.HasValue) { CngKeyUsages keyUsage = creationParameters.KeyUsage.Value; ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(keyHandle, KeyPropertyName.KeyUsage, &keyUsage, sizeof(CngKeyUsages), CngPropertyOptions.Persist); if (errorCode != ErrorCode.ERROR_SUCCESS) { throw errorCode.ToCryptographicException(); } } if (creationParameters.ParentWindowHandle != IntPtr.Zero) { IntPtr parentWindowHandle = creationParameters.ParentWindowHandle; ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(keyHandle, KeyPropertyName.ParentWindowHandle, &parentWindowHandle, sizeof(IntPtr), CngPropertyOptions.None); if (errorCode != ErrorCode.ERROR_SUCCESS) { throw errorCode.ToCryptographicException(); } } CngUIPolicy uiPolicy = creationParameters.UIPolicy; if (uiPolicy != null) { InitializeKeyUiPolicyProperties(keyHandle, uiPolicy); } // Iterate over the custom properties, setting those as well. foreach (CngProperty property in creationParameters.Parameters) { byte[] value = property.GetValueWithoutCopying(); int valueLength = (value == null) ? 0 : value.Length; fixed(byte *pValue = value.MapZeroLengthArrayToNonNullPointer()) { ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(keyHandle, property.Name, pValue, valueLength, property.Options); if (errorCode != ErrorCode.ERROR_SUCCESS) { throw errorCode.ToCryptographicException(); } } } } }
/// <inheritdoc/> public ICryptographicKey CreateKeyPair(int keySize) { Requires.Range(keySize > 0, "keySize"); var keyParameters = new CngKeyCreationParameters { ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport, KeyUsage = CngKeyUsages.AllUsages, }; string keyName = "PclCrypto_" + Guid.NewGuid().ToString(); CngKey key = CngKey.Create(GetCngAlgorithm(this.algorithm), keyName, keyParameters); return new CngCryptographicKey(key, null); }
/// <summary> /// [aaron.clark.aic][2015-06-10][需要验证为什么CngKey会把当前实例保存下来?存放方法和位置] /// </summary> private SingleCngKey() { CngKeyCreationParameters creationParameters = new CngKeyCreationParameters(); // 允许以明文的形式导出私钥 creationParameters.ExportPolicy = CngExportPolicies.AllowPlaintextExport; if (!CngKey.Exists("ecc")) { ck = CngKey.Create(CngAlgorithm.ECDsaP521, "ecc", creationParameters); } else { ck = CngKey.Open("ecc"); } }
/// <summary> /// Windows Azure Service Management API requires 2048bit RSA keys. /// The private key needs to be exportable so we can save it to .pfx for sharing with team members. /// </summary> /// <returns>A 2048 bit RSA key</returns> private static CngKey Create2048RsaKey() { var keyCreationParameters = new CngKeyCreationParameters { ExportPolicy = CngExportPolicies.AllowExport, KeyCreationOptions = CngKeyCreationOptions.None, KeyUsage = CngKeyUsages.AllUsages, Provider = new CngProvider(MsEnhancedProv) }; keyCreationParameters.Parameters.Add(new CngProperty("Length", BitConverter.GetBytes(KeySize2048), CngPropertyOptions.None)); return CngKey.Create(CngAlgorithm2.Rsa, null, keyCreationParameters); }
private static CngKey Create2048RsaKey() { var keyCreationParameters = new CngKeyCreationParameters { ExportPolicy = CngExportPolicies.AllowExport, KeyCreationOptions = CngKeyCreationOptions.None, KeyUsage = CngKeyUsages.AllUsages, Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider }; const int KeySize = 2048; keyCreationParameters.Parameters.Add(new CngProperty("Length", BitConverter.GetBytes(KeySize), CngPropertyOptions.None)); return CngKey.Create(new CngAlgorithm("RSA"), null, keyCreationParameters); }
/// <summary> /// 公開鍵と秘密鍵を作成して返す /// </summary> /// <param name="publicKey">作成された公開鍵</param> /// <param name="privateKey">作成された秘密鍵</param> public static void CreateKeys(out byte[] publicKey, out byte[] privateKey) { #if Windows var ckcp = new CngKeyCreationParameters(); ckcp.ExportPolicy = CngExportPolicies.AllowPlaintextExport; ckcp.KeyUsage = CngKeyUsages.Signing; using (CngKey ck = CngKey.Create(CngAlgorithm.ECDsaP521, null, ckcp)) using (ECDsaCng ecdsa = new ECDsaCng(ck)) { publicKey = Encoding.ASCII.GetBytes(ecdsa.ToXmlString(ECKeyXmlFormat.Rfc4050)); privateKey = ecdsa.Key.Export(CngKeyBlobFormat.Pkcs8PrivateBlob); } #else throw new NotSupportedException(); #endif }
/// <summary> /// 公開鍵と秘密鍵を作成して返す /// </summary> /// <param name="publicKey">作成された公開鍵</param> /// <param name="privateKey">作成された秘密鍵</param> public static void CreateKeys(out byte[] publicKey, out byte[] privateKey) { #if Mono throw new NotSupportedException(); #else CngKeyCreationParameters ckcp = new CngKeyCreationParameters(); ckcp.ExportPolicy = CngExportPolicies.AllowPlaintextExport; ckcp.KeyUsage = CngKeyUsages.KeyAgreement; using (CngKey ck = CngKey.Create(CngAlgorithm.ECDiffieHellmanP521, null, ckcp)) using (ECDiffieHellmanCng ecdh = new ECDiffieHellmanCng(ck)) { publicKey = Encoding.ASCII.GetBytes(ecdh.ToXmlString(ECKeyXmlFormat.Rfc4050)); privateKey = ecdh.Key.Export(CngKeyBlobFormat.Pkcs8PrivateBlob); } #endif }
/// <summary> /// Setup the key properties specified in the key creation parameters /// </summary> private static void InitializeKeyProperties(SafeNCryptKeyHandle keyHandle, CngKeyCreationParameters creationParameters) { unsafe { if (creationParameters.ExportPolicy.HasValue) { CngExportPolicies exportPolicy = creationParameters.ExportPolicy.Value; keyHandle.SetExportPolicy(exportPolicy); } if (creationParameters.KeyUsage.HasValue) { CngKeyUsages keyUsage = creationParameters.KeyUsage.Value; ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(keyHandle, KeyPropertyName.KeyUsage, &keyUsage, sizeof(CngKeyUsages), CngPropertyOptions.Persist); if (errorCode != ErrorCode.ERROR_SUCCESS) throw errorCode.ToCryptographicException(); } if (creationParameters.ParentWindowHandle != IntPtr.Zero) { IntPtr parentWindowHandle = creationParameters.ParentWindowHandle; ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(keyHandle, KeyPropertyName.ParentWindowHandle, &parentWindowHandle, sizeof(IntPtr), CngPropertyOptions.None); if (errorCode != ErrorCode.ERROR_SUCCESS) throw errorCode.ToCryptographicException(); } CngUIPolicy uiPolicy = creationParameters.UIPolicy; if (uiPolicy != null) { InitializeKeyUiPolicyProperties(keyHandle, uiPolicy); } // Iterate over the custom properties, setting those as well. foreach (CngProperty property in creationParameters.Parameters) { byte[] value = property.GetValueWithoutCopying(); int valueLength = (value == null) ? 0 : value.Length; fixed (byte* pValue = value.MapZeroLengthArrayToNonNullPointer()) { ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(keyHandle, property.Name, pValue, valueLength, property.Options); if (errorCode != ErrorCode.ERROR_SUCCESS) throw errorCode.ToCryptographicException(); } } } }
public static CngKey Create(CngAlgorithm algorithm, string?keyName, CngKeyCreationParameters?creationParameters) { if (algorithm == null) { throw new ArgumentNullException(nameof(algorithm)); } if (creationParameters == null) { creationParameters = new CngKeyCreationParameters(); } SafeNCryptProviderHandle providerHandle = creationParameters.Provider !.OpenStorageProvider(); SafeNCryptKeyHandle keyHandle; ErrorCode errorCode = Interop.NCrypt.NCryptCreatePersistedKey(providerHandle, out keyHandle, algorithm.Algorithm, keyName, 0, creationParameters.KeyCreationOptions); if (errorCode != ErrorCode.ERROR_SUCCESS) { // For ecc, the exception may be caught and re-thrown as PlatformNotSupportedException throw errorCode.ToCryptographicException(); } InitializeKeyProperties(keyHandle, creationParameters); errorCode = Interop.NCrypt.NCryptFinalizeKey(keyHandle, 0); if (errorCode != ErrorCode.ERROR_SUCCESS) { // For ecc, the exception may be caught and re-thrown as PlatformNotSupportedException throw errorCode.ToCryptographicException(); } CngKey key = new CngKey(providerHandle, keyHandle); // No name translates to an ephemeral key if (keyName == null) { key.IsEphemeral = true; } return(key); }
public static CngKey Create(CngAlgorithm algorithm, string keyName, CngKeyCreationParameters creationParameters) { if (algorithm == null) { throw new ArgumentNullException("algorithm"); } if (creationParameters == null) { creationParameters = new CngKeyCreationParameters(); } if (!NCryptNative.NCryptSupported) { throw new PlatformNotSupportedException(System.SR.GetString("Cryptography_PlatformNotSupported")); } if (keyName != null) { KeyContainerPermissionAccessEntry accessEntry = new KeyContainerPermissionAccessEntry(keyName, KeyContainerPermissionFlags.Create) { ProviderName = creationParameters.Provider.Provider }; KeyContainerPermission permission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags); permission.AccessEntries.Add(accessEntry); permission.Demand(); } SafeNCryptProviderHandle provider = NCryptNative.OpenStorageProvider(creationParameters.Provider.Provider); SafeNCryptKeyHandle keyHandle = NCryptNative.CreatePersistedKey(provider, algorithm.Algorithm, keyName, creationParameters.KeyCreationOptions); SetKeyProperties(keyHandle, creationParameters); NCryptNative.FinalizeKey(keyHandle); CngKey key = new CngKey(provider, keyHandle); if (keyName == null) { key.IsEphemeral = true; } return(key); }
Task<D2LSecurityToken> IPrivateKeyProvider.GetSigningCredentialsAsync() { var creationParams = new CngKeyCreationParameters() { ExportPolicy = CngExportPolicies.AllowPlaintextExport, KeyUsage = CngKeyUsages.Signing }; byte[] privateBlob; using( var cngKey = CngKey.Create( m_algorithm, null, creationParams ) ) { using( ECDsaCng ecDsa = new ECDsaCng( cngKey ) ) { privateBlob = ecDsa.Key.Export( CngKeyBlobFormat.EccPrivateBlob ); } } D2LSecurityToken result = m_d2lSecurityTokenFactory.Create( () => { using( var cng = CngKey.Import( privateBlob, CngKeyBlobFormat.EccPrivateBlob ) ) { // ECDsaCng copies the CngKey, hence the using var ecDsa = new ECDsaCng( cng ); var key = new EcDsaSecurityKey( ecDsa ); return new Tuple<AsymmetricSecurityKey, IDisposable>( key, ecDsa ); } } ); return Task.FromResult( result ); }
public static CngKey Create(CngAlgorithm algorithm, string keyName, CngKeyCreationParameters creationParameters) { throw new NotImplementedException(); }
public static CngKey Create(CngAlgorithm algorithm, string keyName, CngKeyCreationParameters creationParameters) { Contract.Ensures(Contract.Result<System.Security.Cryptography.CngKey>() != null); return default(CngKey); }
public CngKey GetOrGenerateKey(ECCurve? curve) { if (_lazyKey != null) { return _lazyKey; } // We don't have a key yet so generate Debug.Assert(curve.HasValue); CngKeyCreationParameters creationParameters = new CngKeyCreationParameters() { ExportPolicy = CngExportPolicies.AllowPlaintextExport, }; if (curve.Value.IsNamed) { creationParameters.Parameters.Add(CngKey.GetPropertyFromNamedCurve(curve.Value)); } else if (curve.Value.IsPrime) { ECCurve eccurve = curve.Value; byte[] parametersBlob = ECCng.GetPrimeCurveParameterBlob(ref eccurve); CngProperty prop = new CngProperty( Interop.BCrypt.BCryptPropertyStrings.BCRYPT_ECC_PARAMETERS, parametersBlob, CngPropertyOptions.None); creationParameters.Parameters.Add(prop); } else { throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, curve.Value.CurveType.ToString())); } try { _lazyKey = CngKey.Create(CngAlgorithm.ECDsa, null, creationParameters); } catch (CryptographicException e) { // Map to PlatformNotSupportedException if appropriate ErrorCode errorCode = (ErrorCode)e.HResult; if (curve.Value.IsNamed && errorCode == ErrorCode.NTE_INVALID_PARAMETER || errorCode == ErrorCode.NTE_NOT_SUPPORTED) { throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, curve.Value.Oid.FriendlyName), e); } throw; } return _lazyKey; }
public async Task TestSslTermination() { ILoadBalancerService provider = CreateProvider(); using (CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TestTimeout(TimeSpan.FromSeconds(240)))) { IEnumerable<LoadBalancingProtocol> protocols = await provider.ListProtocolsAsync(cancellationTokenSource.Token); LoadBalancingProtocol httpProtocol = protocols.First(i => i.Name.Equals("HTTP", StringComparison.OrdinalIgnoreCase)); string loadBalancerName = CreateRandomLoadBalancerName(); LoadBalancerConfiguration configuration = new LoadBalancerConfiguration( name: loadBalancerName, nodes: null, protocol: httpProtocol, virtualAddresses: new[] { new LoadBalancerVirtualAddress(LoadBalancerVirtualAddressType.ServiceNet) }, algorithm: LoadBalancingAlgorithm.RoundRobin); LoadBalancer tempLoadBalancer = await provider.CreateLoadBalancerAsync(configuration, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null); string privateKey; string certificate; CngKeyCreationParameters keyParams = new CngKeyCreationParameters(); keyParams.ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport; keyParams.KeyUsage = CngKeyUsages.AllUsages; keyParams.Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider; using (CngKey key = CngKey.Create(CngAlgorithm2.Rsa, Guid.NewGuid().ToString(), keyParams)) { byte[] exported = key.Export(CngKeyBlobFormat.Pkcs8PrivateBlob); StringBuilder formatted = new StringBuilder(); formatted.AppendLine("-----BEGIN RSA PRIVATE KEY-----"); formatted.AppendLine(Convert.ToBase64String(exported, Base64FormattingOptions.InsertLineBreaks)); formatted.Append("-----END RSA PRIVATE KEY-----"); Console.WriteLine(formatted.ToString()); privateKey = formatted.ToString(); X509CertificateCreationParameters certParams = new X509CertificateCreationParameters(new X500DistinguishedName(string.Format("CN={0}, OU=Integration Testing, O=openstacknetsdk, L=San Antonio, S=Texas, C=US", loadBalancerName))); certParams.SignatureAlgorithm = X509CertificateSignatureAlgorithm.RsaSha1; certParams.StartTime = DateTime.Now; certParams.EndTime = DateTime.Now.AddYears(10); certParams.TakeOwnershipOfKey = true; X509Certificate signed = key.CreateSelfSignedCertificate(certParams); exported = signed.Export(X509ContentType.Cert); formatted = new StringBuilder(); formatted.AppendLine("-----BEGIN CERTIFICATE-----"); formatted.AppendLine(Convert.ToBase64String(exported, Base64FormattingOptions.InsertLineBreaks)); formatted.Append("-----END CERTIFICATE-----"); Console.WriteLine(formatted.ToString()); certificate = formatted.ToString(); } string intermediateCertificate = null; LoadBalancerSslConfiguration sslConfiguration = new LoadBalancerSslConfiguration(true, false, 443, privateKey, certificate, intermediateCertificate); await provider.UpdateSslConfigurationAsync(tempLoadBalancer.Id, sslConfiguration, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null); LoadBalancerSslConfiguration updatedConfiguration = new LoadBalancerSslConfiguration(true, true, 443); await provider.UpdateSslConfigurationAsync(tempLoadBalancer.Id, updatedConfiguration, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null); await provider.RemoveSslConfigurationAsync(tempLoadBalancer.Id, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null); /* Cleanup */ await provider.RemoveLoadBalancerAsync(tempLoadBalancer.Id, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null); } }
internal static CngKey Create(ECCurve curve, Func <string, CngAlgorithm> algorithmResolver) { System.Diagnostics.Debug.Assert(algorithmResolver != null); curve.Validate(); CngKeyCreationParameters creationParameters = new CngKeyCreationParameters { ExportPolicy = CngExportPolicies.AllowPlaintextExport, }; CngAlgorithm alg; if (curve.IsNamed) { if (string.IsNullOrEmpty(curve.Oid.FriendlyName)) { throw new PlatformNotSupportedException(string.Format(SR.Cryptography_InvalidCurveOid, curve.Oid.Value)); } // Map curve name to algorithm to support pre-Win10 curves alg = algorithmResolver(curve.Oid.FriendlyName); if (CngKey.IsECNamedCurve(alg.Algorithm)) { creationParameters.Parameters.Add(GetPropertyFromNamedCurve(curve)); } else { if (alg == CngAlgorithm.ECDsaP256 || alg == CngAlgorithm.ECDiffieHellmanP256 || alg == CngAlgorithm.ECDsaP384 || alg == CngAlgorithm.ECDiffieHellmanP384 || alg == CngAlgorithm.ECDsaP521 || alg == CngAlgorithm.ECDiffieHellmanP521) { // No parameters required, the algorithm ID has everything built-in. } else { Debug.Fail(string.Format("Unknown algorithm {0}", alg.ToString())); throw new ArgumentException(SR.Cryptography_InvalidKeySize); } } } else if (curve.IsPrime) { byte[] parametersBlob = ECCng.GetPrimeCurveParameterBlob(ref curve); CngProperty prop = new CngProperty( KeyPropertyName.ECCParameters, parametersBlob, CngPropertyOptions.None); creationParameters.Parameters.Add(prop); alg = algorithmResolver(null); } else { throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString())); } try { return(Create(alg, null, creationParameters)); } catch (CryptographicException e) { Interop.NCrypt.ErrorCode errorCode = (Interop.NCrypt.ErrorCode)e.HResult; if (errorCode == Interop.NCrypt.ErrorCode.NTE_INVALID_PARAMETER || errorCode == Interop.NCrypt.ErrorCode.NTE_NOT_SUPPORTED) { string target = curve.IsNamed ? curve.Oid.FriendlyName : curve.CurveType.ToString(); throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, target), e); } throw; } }
public static CngKey Create(CngAlgorithm algorithm, string keyName, CngKeyCreationParameters creationParameters) { Contract.Ensures(Contract.Result <System.Security.Cryptography.CngKey>() != null); return(default(CngKey)); }
public X509Certificate2 CreateNamedKeyCertificate(CertData data) { try { CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters { ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport | CngExportPolicies.AllowPlaintextArchiving | CngExportPolicies.AllowArchiving, KeyUsage = CngKeyUsages.AllUsages }; X509Certificate2 cert; X509CertificateCreationParameters configCreate = new X509CertificateCreationParameters(new X500DistinguishedName(data.DistinguishedName)) { EndTime = DateTime.Parse("01/01/2020", System.Globalization. DateTimeFormatInfo. InvariantInfo), StartTime = DateTime.Parse("01/01/2010", System.Globalization. DateTimeFormatInfo. InvariantInfo) }; using (CngKey namedKey = CngKey.Create(CngAlgorithm2.Rsa, data.Key, keyCreationParameters)) { cert = namedKey.CreateSelfSignedCertificate(configCreate); cert.FriendlyName = data.Friendlyname; Assert.True(cert.HasPrivateKey); Assert.True(cert.HasCngKey()); using (CngKey certKey = cert.GetCngPrivateKey()) { Assert.Equal(CngAlgorithm2.Rsa, certKey.Algorithm); } } return cert; } finally { if (CngKey.Exists(data.Key)) { using (CngKey key = CngKey.Open(data.Key)) { key.Delete(); } } } }
private static void SetKeyProperties(SafeNCryptKeyHandle keyHandle, CngKeyCreationParameters creationParameters) { if (creationParameters.ExportPolicy.HasValue) { NCryptNative.SetProperty(keyHandle, "Export Policy", creationParameters.ExportPolicy.Value, CngPropertyOptions.None | CngPropertyOptions.Persist); } if (creationParameters.KeyUsage.HasValue) { NCryptNative.SetProperty(keyHandle, "Key Usage", creationParameters.KeyUsage.Value, CngPropertyOptions.None | CngPropertyOptions.Persist); } if (creationParameters.ParentWindowHandle != IntPtr.Zero) { NCryptNative.SetProperty<IntPtr>(keyHandle, "HWND Handle", creationParameters.ParentWindowHandle, CngPropertyOptions.None); } if (creationParameters.UIPolicy != null) { NCryptNative.NCRYPT_UI_POLICY ncrypt_ui_policy = new NCryptNative.NCRYPT_UI_POLICY { dwVersion = 1, dwFlags = creationParameters.UIPolicy.ProtectionLevel, pszCreationTitle = creationParameters.UIPolicy.CreationTitle, pszFriendlyName = creationParameters.UIPolicy.FriendlyName, pszDescription = creationParameters.UIPolicy.Description }; NCryptNative.SetProperty<NCryptNative.NCRYPT_UI_POLICY>(keyHandle, "UI Policy", ncrypt_ui_policy, CngPropertyOptions.None | CngPropertyOptions.Persist); if (creationParameters.UIPolicy.UseContext != null) { NCryptNative.SetProperty(keyHandle, "Use Context", creationParameters.UIPolicy.UseContext, CngPropertyOptions.None | CngPropertyOptions.Persist); } } foreach (CngProperty property in creationParameters.ParametersNoDemand) { NCryptNative.SetProperty(keyHandle, property.Name, property.Value, property.Options); } }
private static void SetKeyProperties(SafeNCryptKeyHandle keyHandle, CngKeyCreationParameters creationParameters) { Contract.Requires(keyHandle != null && !keyHandle.IsInvalid && !keyHandle.IsClosed); Contract.Requires(creationParameters != null); // // Setup the well-known properties. // if (creationParameters.ExportPolicy.HasValue) { NCryptNative.SetProperty(keyHandle, NCryptNative.KeyPropertyName.ExportPolicy, (int)creationParameters.ExportPolicy.Value, CngPropertyOptions.Persist); } if (creationParameters.KeyUsage.HasValue) { NCryptNative.SetProperty(keyHandle, NCryptNative.KeyPropertyName.KeyUsage, (int)creationParameters.KeyUsage.Value, CngPropertyOptions.Persist); } if (creationParameters.ParentWindowHandle != IntPtr.Zero) { NCryptNative.SetProperty(keyHandle, NCryptNative.KeyPropertyName.ParentWindowHandle, creationParameters.ParentWindowHandle, CngPropertyOptions.None); } if (creationParameters.UIPolicy != null) { NCryptNative.NCRYPT_UI_POLICY uiPolicy = new NCryptNative.NCRYPT_UI_POLICY(); uiPolicy.dwVersion = 1; uiPolicy.dwFlags = creationParameters.UIPolicy.ProtectionLevel; uiPolicy.pszCreationTitle = creationParameters.UIPolicy.CreationTitle; uiPolicy.pszFriendlyName = creationParameters.UIPolicy.FriendlyName; uiPolicy.pszDescription = creationParameters.UIPolicy.Description; NCryptNative.SetProperty(keyHandle, NCryptNative.KeyPropertyName.UIPolicy, uiPolicy, CngPropertyOptions.Persist); // The use context is a seperate property from the standard UI context if (creationParameters.UIPolicy.UseContext != null) { NCryptNative.SetProperty(keyHandle, NCryptNative.KeyPropertyName.UseContext, creationParameters.UIPolicy.UseContext, CngPropertyOptions.Persist); } } // Iterate over the custom properties, setting those as well. foreach (CngProperty property in creationParameters.ParametersNoDemand) { NCryptNative.SetProperty(keyHandle, property.Name, property.Value, property.Options); } }
public static CngKey Create(CngAlgorithm algorithm, string keyName, CngKeyCreationParameters creationParameters) { Contract.Ensures(Contract.Result<CngKey>() != null); if (algorithm == null) { throw new ArgumentNullException("algorithm"); } if (creationParameters == null) { creationParameters = new CngKeyCreationParameters(); } // Make sure that NCrypt is supported on this platform if (!NCryptNative.NCryptSupported) { throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported)); } // If we're not creating an ephemeral key, then we need to ensure the user has access to the key name if (keyName != null) { KeyContainerPermissionAccessEntry access = new KeyContainerPermissionAccessEntry(keyName, KeyContainerPermissionFlags.Create); access.ProviderName = creationParameters.Provider.Provider; KeyContainerPermission permission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags); permission.AccessEntries.Add(access); permission.Demand(); } // // Create the native handles representing the new key, setup the creation parameters on it, and // finalize it for use. // SafeNCryptProviderHandle kspHandle = NCryptNative.OpenStorageProvider(creationParameters.Provider.Provider); SafeNCryptKeyHandle keyHandle = NCryptNative.CreatePersistedKey(kspHandle, algorithm.Algorithm, keyName, creationParameters.KeyCreationOptions); SetKeyProperties(keyHandle, creationParameters); NCryptNative.FinalizeKey(keyHandle); CngKey key = new CngKey(kspHandle, keyHandle); // No name translates to an ephemeral key if (keyName == null) { key.IsEphemeral = true; } return key; }
public static CngKey Create(CngAlgorithm algorithm, string keyName, CngKeyCreationParameters creationParameters) { throw new NotImplementedException (); }
/// <summary> /// Инициализация экземпляра класса /// </summary> /// <param name="seed">Инициализирующее случайное значение.</param> /// <param name="privateKey">Закрытый ключ.</param> /// <param name="hmacKey">Код аутентичности сообщения на базе хеш-функции.</param> public void Initialize(Object seed, string privateKey, Object hmacKey = null) { // Защита от потери конфиденциальных данных при многократном вызове Initialize Clear(); // Ключ для алгоритма ECDH CngKey cngKeyECDH; // Ключ для алгоритма ECDSA CngKey cngKeyECDSA; // Задаем параметры создания ключа _cngKeyCreationParameters = new CngKeyCreationParameters(); _cngKeyCreationParameters.ExportPolicy = CngExportPolicies.AllowPlaintextExport; _cngKeyCreationParameters.KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey; _cngKeyCreationParameters.KeyUsage = CngKeyUsages.AllUsages; _cngKeyCreationParameters.Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider; // Если закрытый ключ не задан... if(privateKey == null) { // - создаем его... cngKeyECDH = CngKey.Create(CngAlgorithm.ECDiffieHellmanP521, "CngKey", _cngKeyCreationParameters); //...и экспортируя в двоичные данные подготовленный ключ DH, задаем на его основе ключ для ЭЦП cngKeyECDSA = ImportKeyBinData(ExportKeyBinData(cngKeyECDH, false), false, true); } else //...а иначе используем предоставленный... { //...импортируя его из строки в формате Base64 cngKeyECDH = ImportKeyBinData(Convert.FromBase64String(privateKey.Base64String().Substring(0, PRIVATE_KEY_SIZE)), false, false); // Не ЭЦП // Строка с ключом для ЭЦП string stringECDSA; try { // Пытаемся грузить расширенную часть ключа... stringECDSA = privateKey.Base64String().Substring(PRIVATE_KEY_SIZE, PRIVATE_KEY_SIZE); } catch { //...если не получилось - формируем ключ для ECDSA на основе ключа для ECDH stringECDSA = privateKey.Base64String().Substring(0, PRIVATE_KEY_SIZE); } // Формируем ключ для ЭЦП на основе тех данных, что удалось добыть cngKeyECDSA = ImportKeyBinData(Convert.FromBase64String(stringECDSA), false, true); // ЭЦП } // Инициализируем криптографические сущности ключом _ECDiffieHellmanCng = new ECDiffieHellmanCng(cngKeyECDH); _ECDsaCng = new ECDsaCng(cngKeyECDSA); if(seed != null) { _ECDiffieHellmanCng.Seed = CryforceUtilities.ExtractByteArrayFromObject(seed); } // Если требуется использование кода аутентичности сообщения на основе хеша if(hmacKey != null) { _ECDiffieHellmanCng.HmacKey = CryforceUtilities.ExtractByteArrayFromObject(hmacKey); _ECDiffieHellmanCng.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hmac; } else { _ECDiffieHellmanCng.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash; } // Задаем функцию хеширования _ECDiffieHellmanCng.HashAlgorithm = _ECDsaCng.HashAlgorithm = CngAlgorithm.Sha512; // Указываем, что инициализация прошла успешно IsInitialized = true; }
public void OpenSubscriber() { try { if (IsListening()) return; log.InfoFormat("Opening subscriber endpoint at {0}", netTcpAddress); log.InfoFormat("Opening http subscriber endpoint at {0}", httpAddress); NotificationSubscriber notificationSubscriber = new NotificationSubscriber(); notificationSubscriber.IndicationReceived += OnIndication; CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters(); keyCreationParameters.ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport | CngExportPolicies.AllowPlaintextArchiving | CngExportPolicies.AllowArchiving; keyCreationParameters.KeyUsage = CngKeyUsages.AllUsages; X509CertificateCreationParameters configCreate = new X509CertificateCreationParameters(new X500DistinguishedName("CN=SolarWinds-SwqlStudio")); configCreate.EndTime = DateTime.Now.AddYears(1); configCreate.StartTime = DateTime.Now; using (CngKey cngKey = CngKey.Create(CngAlgorithm2.Rsa)) { X509Certificate2 certificate = cngKey.CreateSelfSignedCertificate(configCreate); ServiceHost host = new ServiceHost(notificationSubscriber, new Uri(netTcpAddress), new Uri(httpAddress)); host.Credentials.ServiceCertificate.Certificate = certificate; // SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectDistinguishedName, "CN=SolarWinds-Orion"); host.Open(); subscriberHosts.Add(host); } log.Info("Http Subscriber endpoint opened"); } catch (Exception ex) { log.ErrorFormat("Exception opening subscriber host with address {0}.\n{1}", httpAddress, ex); } foreach (ServiceHost serviceHost in subscriberHosts) { foreach (ChannelDispatcherBase channelDispatcher in serviceHost.ChannelDispatchers) { log.InfoFormat("Listening on {0}", channelDispatcher.Listener.Uri.AbsoluteUri); } } ListenerOpened?.Invoke(); }
static CngKey RecreateKey(string name, int length) { var createParams = new CngKeyCreationParameters() { KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey, ExportPolicy = CngExportPolicies.AllowPlaintextExport }; createParams.Parameters.Add(new CngProperty("Length", BitConverter.GetBytes(length), CngPropertyOptions.None)); var exists = CngKey.Exists(name, CngProvider.MicrosoftSoftwareKeyStorageProvider, CngKeyOpenOptions.None); var key = CngKey.Create(CngAlgorithm.Rsa, name, createParams); File.WriteAllBytes(@"C:\Connect\key\" + name + "-private", key.Export(CngKeyBlobFormat.GenericPrivateBlob)); File.WriteAllBytes(@"C:\Connect\key\" + name + "-public", key.Export(CngKeyBlobFormat.GenericPublicBlob)); return key; }
/// <summary> /// Create a ECDSA based certificate with the given options /// </summary> /// <param name="buildOptions">Allows for more advanced configuration</param> /// <returns>An exportable X509Certificate2 object (with private key)</returns> public static X509Certificate2 CreateNewSigningCertificate(ECCertificateBuilderOptions buildOptions) { if(buildOptions == null) { throw new ArgumentNullException("buildOptions"); } string keyName = buildOptions.ECKeyName ?? "ECDSAKey"; CngKey objCngKey = null; if (CngKey.Exists(keyName)) { objCngKey = CngKey.Open(keyName); objCngKey.Delete(); } var creationParameters = new CngKeyCreationParameters(); creationParameters.ExportPolicy = CngExportPolicies.AllowExport; creationParameters.KeyUsage = CngKeyUsages.Signing; CngAlgorithm keyAlg; switch(buildOptions.ECCurve ?? ECNamedCurves.P521) { case ECNamedCurves.P521: keyAlg = CngAlgorithm.ECDsaP521; break; case ECNamedCurves.P384: keyAlg = CngAlgorithm.ECDsaP384; break; case ECNamedCurves.P256: keyAlg = CngAlgorithm.ECDsaP256; break; default: throw new InvalidOperationException("Selected curve is not supported"); } objCngKey = CngKey.Create(keyAlg, keyName, creationParameters); var name = new X500DistinguishedName(buildOptions.FullSubjectName); X509CertificateSignatureAlgorithm certAlg; switch(buildOptions.HashingMethod ?? HashingMethods.Sha256) { case HashingMethods.Sha1: certAlg = X509CertificateSignatureAlgorithm.ECDsaSha1; break; case HashingMethods.Sha256: certAlg = X509CertificateSignatureAlgorithm.ECDsaSha256; break; case HashingMethods.Sha384: certAlg = X509CertificateSignatureAlgorithm.ECDsaSha384; break; case HashingMethods.Sha512: certAlg = X509CertificateSignatureAlgorithm.ECDsaSha512; break; default: throw new InvalidOperationException("Selected hashing method is not supported"); } var options = new X509CertificateCreationParameters(name) { SignatureAlgorithm = certAlg, TakeOwnershipOfKey = true }; return objCngKey.CreateSelfSignedCertificate(options); }