public static CngKey Import(byte[] keyBlob, CngKeyBlobFormat format, CngProvider provider) { if (keyBlob == null) { throw new ArgumentNullException(nameof(keyBlob)); } if (format == null) { throw new ArgumentNullException(nameof(format)); } if (provider == null) { throw new ArgumentNullException(nameof(provider)); } SafeNCryptProviderHandle providerHandle = provider.OpenStorageProvider(); SafeNCryptKeyHandle keyHandle; ErrorCode errorCode = Interop.NCrypt.NCryptImportKey(providerHandle, IntPtr.Zero, format.Format, IntPtr.Zero, out keyHandle, keyBlob, keyBlob.Length, 0); if (errorCode != ErrorCode.ERROR_SUCCESS) { throw errorCode.ToCryptographicException(); } CngKey key = new CngKey(providerHandle, keyHandle); // We can't tell directly if an OpaqueTransport blob imported as an ephemeral key or not key.IsEphemeral = format != CngKeyBlobFormat.OpaqueTransportBlob; return(key); }
public static CngKey Import(byte[] keyBlob, CngKeyBlobFormat format, CngProvider provider) { if (keyBlob == null) { throw new ArgumentNullException("keyBlob"); } if (format == null) { throw new ArgumentNullException("format"); } if (provider == null) { throw new ArgumentNullException("provider"); } if (!NCryptNative.NCryptSupported) { throw new PlatformNotSupportedException(System.SR.GetString("Cryptography_PlatformNotSupported")); } if ((format != CngKeyBlobFormat.EccPublicBlob) && (format != CngKeyBlobFormat.GenericPublicBlob)) { new KeyContainerPermission(KeyContainerPermissionFlags.Import).Demand(); } SafeNCryptProviderHandle kspHandle = NCryptNative.OpenStorageProvider(provider.Provider); return(new CngKey(kspHandle, NCryptNative.ImportKey(kspHandle, keyBlob, format.Format)) { IsEphemeral = format != CngKeyBlobFormat.OpaqueTransportBlob }); }
private static CngKey ImportKeyBlob( byte[] blob, string curveName, CngKeyBlobFormat format, ECCurve.ECCurveType curveType) { try { CngKey newKey = CngKey.Import(blob, curveName, format); newKey.ExportPolicy |= CngExportPolicies.AllowPlaintextExport; return(newKey); } catch (CryptographicException e) { if (curveType != ECCurve.ECCurveType.Named && e.HResult == (int)ErrorCode.NTE_NOT_SUPPORTED) { throw new PlatformNotSupportedException( SR.GetString(SR.Cryptography_CurveNotSupported, curveType), e); } throw; } }
/// <summary> /// Wrap a CNG key /// </summary> #pragma warning disable SYSLIB0043 // byte[] constructor on ECDiffieHellmanPublicKey is obsolete internal ECDiffieHellmanCngPublicKey(byte[] keyBlob, string?curveName, CngKeyBlobFormat format) : base(keyBlob) #pragma warning restore SYSLIB0043 { _format = format; // Can be null for P256, P384, P521, or an explicit blob _curveName = curveName; }
/// <summary> /// Export the key out of the KSP /// </summary> public byte[] Export(CngKeyBlobFormat format) { if (format == null) { throw new ArgumentNullException(nameof(format)); } int numBytesNeeded; ErrorCode errorCode = Interop.NCrypt.NCryptExportKey(_keyHandle, IntPtr.Zero, format.Format, IntPtr.Zero, null, 0, out numBytesNeeded, 0); if (errorCode != ErrorCode.ERROR_SUCCESS) { throw errorCode.ToCryptographicException(); } byte[] buffer = new byte[numBytesNeeded]; errorCode = Interop.NCrypt.NCryptExportKey(_keyHandle, IntPtr.Zero, format.Format, IntPtr.Zero, buffer, buffer.Length, out numBytesNeeded, 0); if (errorCode != ErrorCode.ERROR_SUCCESS) { throw errorCode.ToCryptographicException(); } Array.Resize(ref buffer, numBytesNeeded); return(buffer); }
internal ECDiffieHellmanCngPublicKey(CngKey key) : base(key.Export(CngKeyBlobFormat.EccPublicBlob)) { this.m_format = CngKeyBlobFormat.EccPublicBlob; new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); this.m_key = CngKey.Open(key.Handle, key.IsEphemeral ? CngKeyHandleOpenOptions.EphemeralKey : CngKeyHandleOpenOptions.None); CodeAccessPermission.RevertAssert(); }
private static byte[] ExportFullKeyBlob(CngKey key, bool includePrivateParameters) { CngKeyBlobFormat blobFormat = includePrivateParameters ? CngKeyBlobFormat.EccFullPrivateBlob : CngKeyBlobFormat.EccFullPublicBlob; return(key.Export(blobFormat)); }
internal static CngKey ImportKeyBlob(byte[] ecBlob, string curveName, bool includePrivateParameters) { CngKeyBlobFormat blobFormat = includePrivateParameters ? CngKeyBlobFormat.EccPrivateBlob : CngKeyBlobFormat.EccPublicBlob; CngKey newKey = CngKey.Import(ecBlob, curveName, blobFormat); newKey.ExportPolicy |= CngExportPolicies.AllowPlaintextExport; return(newKey); }
private static CngKey ImportFullKeyBlob(byte[] ecBlob, bool includePrivateParameters) { CngKeyBlobFormat blobFormat = includePrivateParameters ? CngKeyBlobFormat.EccFullPrivateBlob : CngKeyBlobFormat.EccFullPublicBlob; CngKey newKey = CngKey.Import(ecBlob, blobFormat); newKey.ExportPolicy |= CngExportPolicies.AllowPlaintextExport; return(newKey); }
internal ECDiffieHellmanCngPublicKey(byte[] keyBlob, string curveName, CngKeyBlobFormat format) : base(keyBlob) { Contract.Requires(format != null); Contract.Ensures(m_format != null); m_format = format; // Can be null for P256, P384, P521, or an explicit blob m_curveName = curveName; }
internal static CngKey Import( byte[] keyBlob, string?curveName, CngKeyBlobFormat format, CngProvider provider) { ArgumentNullException.ThrowIfNull(keyBlob); return(Import(new ReadOnlySpan <byte>(keyBlob), curveName, format, provider)); }
internal static CngKey Import(byte[] keyBlob, string curveName, CngKeyBlobFormat format, CngProvider provider) { Contract.Ensures(Contract.Result <CngKey>() != null); if (keyBlob == null) { throw new ArgumentNullException("keyBlob"); } if (format == null) { throw new ArgumentNullException("format"); } if (provider == null) { throw new ArgumentNullException("provider"); } // Make sure that NCrypt is supported on this platform if (!NCryptNative.NCryptSupported) { throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported)); } // If we don't know for sure that the key will be ephemeral, then we need to demand Import // permission. Since we won't know the name of the key until it's too late, we demand a full Import // rather than one scoped to the key. bool safeKeyImport = format == CngKeyBlobFormat.EccPublicBlob || format == CngKeyBlobFormat.EccFullPublicBlob || format == CngKeyBlobFormat.GenericPublicBlob; if (!safeKeyImport) { new KeyContainerPermission(KeyContainerPermissionFlags.Import).Demand(); } // Import the key into the KSP SafeNCryptProviderHandle kspHandle = NCryptNative.OpenStorageProvider(provider.Provider); SafeNCryptKeyHandle keyHandle; if (curveName == null) { keyHandle = NCryptNative.ImportKey(kspHandle, keyBlob, format.Format); } else { keyHandle = ECCng.ImportKeyBlob(format.Format, keyBlob, curveName, kspHandle); } // Prepare the key for use CngKey key = new CngKey(kspHandle, keyHandle); // We can't tell directly if an OpaqueTransport blob imported as an ephemeral key or not key.IsEphemeral = format != CngKeyBlobFormat.OpaqueTransportBlob; return(key); }
internal static CngKey Import( ReadOnlySpan <byte> keyBlob, string?curveName, CngKeyBlobFormat format, CngProvider provider) { ArgumentNullException.ThrowIfNull(format); ArgumentNullException.ThrowIfNull(provider); SafeNCryptProviderHandle providerHandle = provider.OpenStorageProvider(); SafeNCryptKeyHandle? keyHandle = null; try { ErrorCode errorCode; if (curveName == null) { errorCode = Interop.NCrypt.NCryptImportKey( providerHandle, IntPtr.Zero, format.Format, IntPtr.Zero, out keyHandle, ref MemoryMarshal.GetReference(keyBlob), keyBlob.Length, 0); if (errorCode != ErrorCode.ERROR_SUCCESS) { providerHandle.Dispose(); keyHandle.Dispose(); throw errorCode.ToCryptographicException(); } } else { keyHandle = ECCng.ImportKeyBlob(format.Format, keyBlob, curveName, providerHandle); } CngKey key = new CngKey(providerHandle, keyHandle); // We can't tell directly if an OpaqueTransport blob imported as an ephemeral key or not key.IsEphemeral = format != CngKeyBlobFormat.OpaqueTransportBlob; return(key); } catch { keyHandle?.Dispose(); providerHandle.Dispose(); throw; } }
internal static byte[] EcdhParametersToBlob( ref ECParameters parameters, out CngKeyBlobFormat format, out string curveName) { return(ParametersToBlob( ref parameters, s_ecdhNamedMagicResolver, s_ecdhExplicitMagicResolver, out format, out curveName)); }
internal static CngKey Import( byte[] keyBlob, string?curveName, CngKeyBlobFormat format, CngProvider provider) { if (keyBlob == null) { throw new ArgumentNullException(nameof(keyBlob)); } return(Import(new ReadOnlySpan <byte>(keyBlob), curveName, format, provider)); }
public byte[] Export(CngKeyBlobFormat format) { if (format == null) { throw new ArgumentNullException("format"); } KeyContainerPermission permission = this.BuildKeyContainerPermission(KeyContainerPermissionFlags.Export); if (permission != null) { permission.Demand(); } return(NCryptNative.ExportKey(this.m_keyHandle, format.Format)); }
public static ECDiffieHellmanPublicKey FromByteArray(byte[] publicKeyBlob, CngKeyBlobFormat format) { ArgumentNullException.ThrowIfNull(publicKeyBlob); ArgumentNullException.ThrowIfNull(format); // Verify that the key can import successfully, because we did in the past. using (CngKey imported = CngKey.Import(publicKeyBlob, format)) { if (imported.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) { throw new ArgumentException(SR.Cryptography_ArgECDHRequiresECDHKey); } return(new ECDiffieHellmanCngPublicKey(publicKeyBlob, null, format)); } }
public static ECDiffieHellmanPublicKey FromByteArray(byte[] publicKeyBlob, CngKeyBlobFormat format) { if (publicKeyBlob == null) { throw new ArgumentNullException("publicKeyBlob"); } if (format == null) { throw new ArgumentNullException("format"); } using (CngKey key = CngKey.Import(publicKeyBlob, format)) { if (key.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman) { throw new ArgumentException(System.SR.GetString("Cryptography_ArgECDHRequiresECDHKey")); } return(new ECDiffieHellmanCngPublicKey(key)); } }
private static byte[] ParametersToBlob( ref ECParameters parameters, Func <string, bool, KeyBlobMagicNumber> namedCurveResolver, Func <bool, KeyBlobMagicNumber> explicitCurveResolver, out CngKeyBlobFormat format, out string curveName) { parameters.Validate(); ECCurve curve = parameters.Curve; bool includePrivateParameters = (parameters.D != null); if (curve.IsPrime) { curveName = null; format = includePrivateParameters ? CngKeyBlobFormat.EccFullPrivateBlob : CngKeyBlobFormat.EccFullPublicBlob; return(GetPrimeCurveBlob(ref parameters, explicitCurveResolver)); } else if (curve.IsNamed) { // FriendlyName is required; an attempt was already made to default it in ECCurve curveName = curve.Oid.FriendlyName; if (string.IsNullOrEmpty(curveName)) { throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_InvalidCurveOid, curve.Oid.Value.ToString())); } format = includePrivateParameters ? CngKeyBlobFormat.EccPrivateBlob : CngKeyBlobFormat.EccPublicBlob; return(GetNamedCurveBlob(ref parameters, namedCurveResolver)); } else { throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString())); } }
internal static byte[] ExportKeyBlob( CngKey key, bool includePrivateParameters, out CngKeyBlobFormat format, out string?curveName) { curveName = key.GetCurveName(out _); bool forceGenericBlob = false; if (string.IsNullOrEmpty(curveName)) { // Normalize curveName to null. curveName = null; forceGenericBlob = true; format = includePrivateParameters ? CngKeyBlobFormat.EccFullPrivateBlob : CngKeyBlobFormat.EccFullPublicBlob; } else { format = includePrivateParameters ? CngKeyBlobFormat.EccPrivateBlob : CngKeyBlobFormat.EccPublicBlob; } byte[] blob = key.Export(format); // Importing a known NIST curve as explicit parameters NCryptExportKey may // cause it to export with the dwMagic of the known curve and a generic blob body. // This combination can't be re-imported. So correct the dwMagic value to allow it // to import. if (forceGenericBlob) { FixupGenericBlob(blob); } return(blob); }
internal ECDiffieHellmanCngPublicKey(CngKey key) : base(key.Export(CngKeyBlobFormat.EccPublicBlob)) { Contract.Requires(key != null && key.AlgorithmGroup == CngAlgorithmGroup.ECDiffieHellman); Contract.Ensures(m_format != null); m_format = CngKeyBlobFormat.EccPublicBlob; // // We need to make a copy of the key to prevent the situation where the ECDiffieHellmanCng algorithm // object is disposed (this disposing its key) before the ECDiffieHellmanCngPublic key is disposed. // // Accessing the handle in partial trust is safe because we're not exposing it back out to user code // new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); // This looks odd, but .Handle returns a duplicate, so we need to dispose it using (SafeNCryptKeyHandle importKey = key.Handle) { m_key = CngKey.Open(importKey, key.IsEphemeral ? CngKeyHandleOpenOptions.EphemeralKey : CngKeyHandleOpenOptions.None); } CodeAccessPermission.RevertAssert(); }
/// <summary> /// Export the key out of the KSP /// </summary> public byte[] Export(CngKeyBlobFormat format) { if (format == null) { throw new ArgumentNullException("format"); } int numBytesRequired; ErrorCode errorCode = Interop.NCrypt.NCryptExportKey(_keyHandle, IntPtr.Zero, format.Format, IntPtr.Zero, null, 0, out numBytesRequired, 0); if (errorCode != ErrorCode.ERROR_SUCCESS) { throw errorCode.ToCryptographicException(); } byte[] buffer = new byte[numBytesRequired]; errorCode = Interop.NCrypt.NCryptExportKey(_keyHandle, IntPtr.Zero, format.Format, IntPtr.Zero, buffer, numBytesRequired, out numBytesRequired, 0); if (errorCode != ErrorCode.ERROR_SUCCESS) { throw errorCode.ToCryptographicException(); } return(buffer); }
// // Import factory methods // public static CngKey Import(byte[] keyBlob, CngKeyBlobFormat format) { return(Import(keyBlob, format, provider: CngProvider.MicrosoftSoftwareKeyStorageProvider)); }
public static ECDiffieHellmanPublicKey FromByteArray(byte[] publicKeyBlob, CngKeyBlobFormat format) { throw new NotImplementedException(); }
public byte[] Export(CngKeyBlobFormat format) { throw new NotImplementedException(); }
public static CngKey Import(byte[] keyBlob, CngKeyBlobFormat format, CngProvider provider) { throw new NotImplementedException(); }
internal static CngKey Import(byte[] keyBlob, string curveName, CngKeyBlobFormat format) { return(Import(keyBlob, curveName, format, provider: CngProvider.MicrosoftSoftwareKeyStorageProvider)); }
// // Import factory methods // internal static CngKey Import(ReadOnlySpan <byte> keyBlob, CngKeyBlobFormat format) { return(Import(keyBlob, null, format, CngProvider.MicrosoftSoftwareKeyStorageProvider)); }
public static CngKey Import(byte[] keyBlob, CngKeyBlobFormat format, CngProvider provider) { return(Import(keyBlob, null, format, provider)); }
/// <summary> /// <para> /// ImportParameters will replace the existing key that RSACng is working with by creating a /// new CngKey for the parameters structure. If the parameters structure contains only an /// exponent and modulus, then only a public key will be imported. If the parameters also /// contain P and Q values, then a full key pair will be imported. /// </para> /// </summary> /// <exception cref="ArgumentException"> /// if <paramref name="parameters" /> contains neither an exponent nor a modulus. /// </exception> /// <exception cref="CryptographicException"> /// if <paramref name="parameters" /> is not a valid RSA key or if <paramref name="parameters" /// /> is a full key pair and the default KSP is used. /// </exception> public override void ImportParameters(RSAParameters parameters) { unsafe { if (parameters.Exponent == null || parameters.Modulus == null) { throw new CryptographicException(SR.Cryptography_InvalidRsaParameters); } bool includePrivate; if (parameters.D == null) { includePrivate = false; if (parameters.P != null || parameters.DP != null || parameters.Q != null || parameters.DQ != null || parameters.InverseQ != null) { throw new CryptographicException(SR.Cryptography_InvalidRsaParameters); } } else { includePrivate = true; if (parameters.P == null || parameters.DP == null || parameters.Q == null || parameters.DQ == null || parameters.InverseQ == null) { throw new CryptographicException(SR.Cryptography_InvalidRsaParameters); } } // // We need to build a key blob structured as follows: // // BCRYPT_RSAKEY_BLOB header // byte[cbPublicExp] publicExponent - Exponent // byte[cbModulus] modulus - Modulus // -- Only if "includePrivate" is true -- // byte[cbPrime1] prime1 - P // byte[cbPrime2] prime2 - Q // ------------------ // int blobSize = sizeof(BCRYPT_RSAKEY_BLOB) + parameters.Exponent.Length + parameters.Modulus.Length; if (includePrivate) { blobSize += parameters.P.Length + parameters.Q.Length; } byte[] rsaBlob = new byte[blobSize]; fixed(byte *pRsaBlob = rsaBlob) { // Build the header BCRYPT_RSAKEY_BLOB *pBcryptBlob = (BCRYPT_RSAKEY_BLOB *)pRsaBlob; pBcryptBlob->Magic = includePrivate ? KeyBlobMagicNumber.BCRYPT_RSAPRIVATE_MAGIC : KeyBlobMagicNumber.BCRYPT_RSAPUBLIC_MAGIC; pBcryptBlob->BitLength = parameters.Modulus.Length * 8; pBcryptBlob->cbPublicExp = parameters.Exponent.Length; pBcryptBlob->cbModulus = parameters.Modulus.Length; if (includePrivate) { pBcryptBlob->cbPrime1 = parameters.P.Length; pBcryptBlob->cbPrime2 = parameters.Q.Length; } int offset = sizeof(BCRYPT_RSAKEY_BLOB); Emit(rsaBlob, ref offset, parameters.Exponent); Emit(rsaBlob, ref offset, parameters.Modulus); if (includePrivate) { Emit(rsaBlob, ref offset, parameters.P); Emit(rsaBlob, ref offset, parameters.Q); } // We better have computed the right allocation size above! Debug.Assert(offset == blobSize, "offset == blobSize"); } CngKeyBlobFormat blobFormat = includePrivate ? s_rsaPrivateBlob : s_rsaPublicBlob; CngKey newKey = CngKey.Import(rsaBlob, blobFormat); newKey.ExportPolicy |= CngExportPolicies.AllowPlaintextExport; Key = newKey; } }