private static CngKey Ecc256Public(CngKeyUsages usage = CngKeyUsages.Signing) { byte[] x = { 4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9 }; byte[] y = { 131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53 }; byte[] d = { 42, 148, 231, 48, 225, 196, 166, 201, 23, 190, 229, 199, 20, 39, 226, 70, 209, 148, 29, 70, 125, 14, 174, 66, 9, 198, 80, 251, 95, 107, 98, 206 }; return(EccKey.New(x, y, usage: usage)); }
/// <summary> /// Creates CngKey Elliptic Curve Key from given (x,y) curve point - public part /// and optional d - private part /// </summary> /// <param name="x">x coordinate of curve point</param> /// <param name="y">y coordinate of curve point</param> /// <param name="d">optional private part</param> /// <returns>CngKey for given (x,y) and d</returns> public static CngKey New(byte[] x, byte[] y, byte[] d=null, CngKeyUsages usage=CngKeyUsages.Signing) { if (x.Length != y.Length) throw new ArgumentException("X,Y and D must be same size"); if(d!=null && x.Length!=d.Length) throw new ArgumentException("X,Y and D must be same size"); if(usage!=CngKeyUsages.Signing && usage!=CngKeyUsages.KeyAgreement) throw new ArgumentException("Usage parameter expected to be set either 'CngKeyUsages.Signing' or 'CngKeyUsages.KeyAgreement"); bool signing = usage == CngKeyUsages.Signing; int partSize = x.Length; byte[] magic; if (partSize == 32) { magic = (d == null) ? signing ? BCRYPT_ECDSA_PUBLIC_P256_MAGIC : BCRYPT_ECDH_PUBLIC_P256_MAGIC : signing ? BCRYPT_ECDSA_PRIVATE_P256_MAGIC : BCRYPT_ECDH_PRIVATE_P256_MAGIC; } else if (partSize == 48) { magic = (d == null) ? signing ? BCRYPT_ECDSA_PUBLIC_P384_MAGIC : BCRYPT_ECDH_PUBLIC_P384_MAGIC : signing ? BCRYPT_ECDSA_PRIVATE_P384_MAGIC : BCRYPT_ECDH_PRIVATE_P384_MAGIC; } else if (partSize == 66) { magic = (d == null) ? signing ? BCRYPT_ECDSA_PUBLIC_P521_MAGIC : BCRYPT_ECDH_PUBLIC_P521_MAGIC : signing ? BCRYPT_ECDSA_PRIVATE_P521_MAGIC : BCRYPT_ECDH_PRIVATE_P521_MAGIC; } else throw new ArgumentException("Size of X,Y or D must equal to 32, 48 or 66 bytes"); byte[] partLength = BitConverter.GetBytes(partSize); CngKeyBlobFormat blobType; byte[] blob; if(d==null) { blob = Arrays.Concat(magic, partLength, x, y); blobType = CngKeyBlobFormat.EccPublicBlob; } else { blob = Arrays.Concat(magic, partLength, x, y, d); blobType = CngKeyBlobFormat.EccPrivateBlob; ; } return CngKey.Import(blob, blobType); }
/// <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(); } } } } }
/// <summary> /// Creates CngKey Elliptic Curve Key from given (x,y) curve point - public part /// and optional d - private part /// </summary> /// <param name="x">x coordinate of curve point</param> /// <param name="y">y coordinate of curve point</param> /// <param name="d">optional private part</param> /// <returns>CngKey for given (x,y) and d</returns> public static CngKey New(byte[] x, byte[] y, byte[] d = null, CngKeyUsages usage = CngKeyUsages.Signing) { if (x.Length != y.Length) { throw new ArgumentException("X,Y and D must be same size"); } if (d != null && x.Length != d.Length) { throw new ArgumentException("X,Y and D must be same size"); } if (usage != CngKeyUsages.Signing && usage != CngKeyUsages.KeyAgreement) { throw new ArgumentException("Usage parameter expected to be set either 'CngKeyUsages.Signing' or 'CngKeyUsages.KeyAgreement"); } bool signing = usage == CngKeyUsages.Signing; int partSize = x.Length; byte[] magic; if (partSize == 32) { magic = (d == null) ? signing ? BCRYPT_ECDSA_PUBLIC_P256_MAGIC : BCRYPT_ECDH_PUBLIC_P256_MAGIC : signing ? BCRYPT_ECDSA_PRIVATE_P256_MAGIC : BCRYPT_ECDH_PRIVATE_P256_MAGIC; } else if (partSize == 48) { magic = (d == null) ? signing ? BCRYPT_ECDSA_PUBLIC_P384_MAGIC : BCRYPT_ECDH_PUBLIC_P384_MAGIC : signing ? BCRYPT_ECDSA_PRIVATE_P384_MAGIC : BCRYPT_ECDH_PRIVATE_P384_MAGIC; } else if (partSize == 66) { magic = (d == null) ? signing ? BCRYPT_ECDSA_PUBLIC_P521_MAGIC : BCRYPT_ECDH_PUBLIC_P521_MAGIC : signing ? BCRYPT_ECDSA_PRIVATE_P521_MAGIC : BCRYPT_ECDH_PRIVATE_P521_MAGIC; } else { throw new ArgumentException("Size of X,Y or D must equal to 32, 48 or 66 bytes"); } byte[] partLength = BitConverter.GetBytes(partSize); CngKeyBlobFormat blobType; byte[] blob; if (d == null) { blob = Arrays.Concat(magic, partLength, x, y); blobType = CngKeyBlobFormat.EccPublicBlob; } else { blob = Arrays.Concat(magic, partLength, x, y, d); blobType = CngKeyBlobFormat.EccPrivateBlob;; } return(CngKey.Import(blob, blobType)); }
//--------------------------------------------------------------------- // IKeyStoreAdapter //--------------------------------------------------------------------- public Task <RSA> CreateRsaKeyAsync( string name, CngKeyUsages usage, bool createNewIfNotExists, IWin32Window window) { using (ApplicationTraceSources.Default.TraceMethod().WithoutParameters()) { // // Create or open CNG key in the user profile. // // NB. Keys are stored in %APPDATA%\Microsoft\Crypto\Keys when using // the default Microsoft Software Key Storage Provider. // (see https://docs.microsoft.com/en-us/windows/win32/seccng/key-storage-and-retrieval) // // For testing, you can list CNG keys using // certutil -csp "Microsoft Software Key Storage Provider" -key -user // return(Task.Run <RSA>(() => { if (CngKey.Exists(name)) { var key = CngKey.Open(name); if (key.Algorithm != CngAlgorithm.Rsa) { throw new CryptographicException( $"Key {name} is not an RSA key"); } if ((key.KeyUsage & usage) == 0) { throw new CryptographicException( $"Key {name} exists, but does not support requested usage"); } return new RSACng(key); } if (createNewIfNotExists) { var keyParams = new CngKeyCreationParameters { // Do not overwrite, store in user profile. KeyCreationOptions = CngKeyCreationOptions.None, // Do not allow exporting. ExportPolicy = CngExportPolicies.None, Provider = this.provider, KeyUsage = usage }; // // NB. If we're using the Smart Card provider, the key store // might show a UI dialog. // if (window != null && window.Handle != null) { keyParams.ParentWindowHandle = window.Handle; } keyParams.Parameters.Add( new CngProperty( "Length", BitConverter.GetBytes(this.keySize), CngPropertyOptions.None)); // // Create the key. That's a bit expensive, so do it // asynchronously. // return new RSACng(CngKey.Create( CngAlgorithm.Rsa, name, keyParams)); } return null; })); } }
public static CngKey New(byte[] x, byte[] y, byte[] d = null, CngKeyUsages usage = CngKeyUsages.Signing) { byte[] numArray; CngKeyBlobFormat eccPrivateBlob; byte[] numArray1; byte[] numArray2; byte[] numArray3; byte[] numArray4; if ((int)x.Length != (int)y.Length) { throw new ArgumentException("X,Y and D must be same size"); } if (d != null && (int)x.Length != (int)d.Length) { throw new ArgumentException("X,Y and D must be same size"); } if (usage != CngKeyUsages.Signing && usage != CngKeyUsages.KeyAgreement) { throw new ArgumentException("Usage parameter expected to be set either 'CngKeyUsages.Signing' or 'CngKeyUsages.KeyAgreement"); } bool flag = usage == CngKeyUsages.Signing; int length = (int)x.Length; if (length == 32) { if (d == null) { numArray4 = (flag ? EccKey.BCRYPT_ECDSA_PUBLIC_P256_MAGIC : EccKey.BCRYPT_ECDH_PUBLIC_P256_MAGIC); } else { numArray4 = (flag ? EccKey.BCRYPT_ECDSA_PRIVATE_P256_MAGIC : EccKey.BCRYPT_ECDH_PRIVATE_P256_MAGIC); } numArray = numArray4; } else if (length != 48) { if (length != 66) { throw new ArgumentException("Size of X,Y or D must equal to 32, 48 or 66 bytes"); } if (d == null) { numArray2 = (flag ? EccKey.BCRYPT_ECDSA_PUBLIC_P521_MAGIC : EccKey.BCRYPT_ECDH_PUBLIC_P521_MAGIC); } else { numArray2 = (flag ? EccKey.BCRYPT_ECDSA_PRIVATE_P521_MAGIC : EccKey.BCRYPT_ECDH_PRIVATE_P521_MAGIC); } numArray = numArray2; } else { if (d == null) { numArray3 = (flag ? EccKey.BCRYPT_ECDSA_PUBLIC_P384_MAGIC : EccKey.BCRYPT_ECDH_PUBLIC_P384_MAGIC); } else { numArray3 = (flag ? EccKey.BCRYPT_ECDSA_PRIVATE_P384_MAGIC : EccKey.BCRYPT_ECDH_PRIVATE_P384_MAGIC); } numArray = numArray3; } byte[] bytes = BitConverter.GetBytes(length); if (d != null) { numArray1 = Arrays.Concat(new byte[][] { numArray, bytes, x, y, d }); eccPrivateBlob = CngKeyBlobFormat.EccPrivateBlob; } else { numArray1 = Arrays.Concat(new byte[][] { numArray, bytes, x, y }); eccPrivateBlob = CngKeyBlobFormat.EccPublicBlob; } return(CngKey.Import(numArray1, eccPrivateBlob)); }
private CngKey Ecc256Private(CngKeyUsages usage=CngKeyUsages.Signing) { byte[] x = { 4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9 }; byte[] y = { 131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53 }; byte[] d = { 42, 148, 231, 48, 225, 196, 166, 201, 23, 190, 229, 199, 20, 39, 226, 70, 209, 148, 29, 70, 125, 14, 174, 66, 9, 198, 80, 251, 95, 107, 98, 206 }; return EccKey.New(x, y, d, usage); }