internal static SafeKeyHandle BCryptImportKey(SafeAlgorithmHandle hAlg, ReadOnlySpan <byte> key) { unsafe { const string BCRYPT_KEY_DATA_BLOB = "KeyDataBlob"; int keySize = key.Length; int blobSize = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + keySize; byte[] blob = new byte[blobSize]; fixed(byte *pbBlob = blob) { BCRYPT_KEY_DATA_BLOB_HEADER *pBlob = (BCRYPT_KEY_DATA_BLOB_HEADER *)pbBlob; pBlob->dwMagic = BCRYPT_KEY_DATA_BLOB_HEADER.BCRYPT_KEY_DATA_BLOB_MAGIC; pBlob->dwVersion = BCRYPT_KEY_DATA_BLOB_HEADER.BCRYPT_KEY_DATA_BLOB_VERSION1; pBlob->cbKeyData = (uint)keySize; } key.CopyTo(blob.AsSpan(sizeof(BCRYPT_KEY_DATA_BLOB_HEADER))); SafeKeyHandle hKey; NTSTATUS ntStatus = BCryptImportKey(hAlg, IntPtr.Zero, BCRYPT_KEY_DATA_BLOB, out hKey, IntPtr.Zero, 0, blob, blobSize, 0); if (ntStatus != NTSTATUS.STATUS_SUCCESS) { throw CreateCryptographicException(ntStatus); } return(hKey); } }
public static SafeKeyHandle BCryptImportKey(this SafeAlgorithmHandle hAlg, byte[] key) { unsafe { const String BCRYPT_KEY_DATA_BLOB = "KeyDataBlob"; int keySize = key.Length; int blobSize = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + keySize; byte[] blob = new byte[blobSize]; fixed(byte *pbBlob = blob) { BCRYPT_KEY_DATA_BLOB_HEADER *pBlob = (BCRYPT_KEY_DATA_BLOB_HEADER *)pbBlob; pBlob->dwMagic = BCRYPT_KEY_DATA_BLOB_HEADER.BCRYPT_KEY_DATA_BLOB_MAGIC; pBlob->dwVersion = BCRYPT_KEY_DATA_BLOB_HEADER.BCRYPT_KEY_DATA_BLOB_VERSION1; pBlob->cbKeyData = (uint)keySize; } Buffer.BlockCopy(key, 0, blob, sizeof(BCRYPT_KEY_DATA_BLOB_HEADER), keySize); SafeKeyHandle hKey; NTSTATUS ntStatus = Interop.BCryptImportKey(hAlg, IntPtr.Zero, BCRYPT_KEY_DATA_BLOB, out hKey, IntPtr.Zero, 0, blob, blobSize, 0); if (ntStatus != NTSTATUS.STATUS_SUCCESS) { throw CreateCryptographicException(ntStatus); } return(hKey); } }
internal static unsafe SafeKeyHandle BCryptImportKey(SafeAlgorithmHandle hAlg, ReadOnlySpan <byte> key) { const string BCRYPT_KEY_DATA_BLOB = "KeyDataBlob"; int keySize = key.Length; int blobSize = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + keySize; // 64 is large enough to hold a BCRYPT_KEY_DATA_BLOB_HEADER and an AES-256 key with room to spare. int MaxStackKeyBlob = 64; Span <byte> blob = stackalloc byte[MaxStackKeyBlob]; if (blobSize > MaxStackKeyBlob) { blob = new byte[blobSize]; } else { blob.Clear(); } fixed(byte *pbBlob = blob) { BCRYPT_KEY_DATA_BLOB_HEADER *pBlob = (BCRYPT_KEY_DATA_BLOB_HEADER *)pbBlob; pBlob->dwMagic = BCRYPT_KEY_DATA_BLOB_HEADER.BCRYPT_KEY_DATA_BLOB_MAGIC; pBlob->dwVersion = BCRYPT_KEY_DATA_BLOB_HEADER.BCRYPT_KEY_DATA_BLOB_VERSION1; pBlob->cbKeyData = (uint)keySize; key.CopyTo(blob.Slice(sizeof(BCRYPT_KEY_DATA_BLOB_HEADER))); SafeKeyHandle hKey; Interop.BCrypt.NTSTATUS ntStatus = BCryptImportKey( hAlg, IntPtr.Zero, BCRYPT_KEY_DATA_BLOB, out hKey, IntPtr.Zero, 0, pbBlob, blobSize, 0); if (ntStatus != Interop.BCrypt.NTSTATUS.STATUS_SUCCESS) { throw CreateCryptographicException(ntStatus); } return(hKey); } }
internal static SafeBCryptKeyHandle BCryptImportKey(SafeBCryptAlgorithmHandle hAlg, byte[] key) { unsafe { const String BCRYPT_KEY_DATA_BLOB = "KeyDataBlob"; int keySize = key.Length; int blobSize = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER)keySize; byte[] blob = new byte[blobSize]; fixed(byte *pbBlob = blob) { BCRYPT_KEY_DATA_BLOB_HEADER *pBlob = (BCRYPT_KEY_DATA_BLOB_HEADER *)pbBlob; pBlob->dwMagic = BCRYPT_KEY_DATA_BLOB_HEADER.BCRYPT_KEY_DATA_BLOB_MAGIC; pBlob->dwVersion = BCRYPT_KEY_DATA_BLOB_HEADER.BCRYPT_KEY_DATA_BLOB_VERSION1; pBlob->cbKeyData = (uint)keySize; } Buffer.BlockCopy(key, 0, blob, sizeof(BCRYPT_KEY_DATA_BLOB_HEADER), keySize); SafeBCryptKeyHandle hKey; ErrorCode error = UnsafeNativeMethods.BCryptImportKey( hAlg, IntPtr.Zero, BCRYPT_KEY_DATA_BLOB, out hKey, IntPtr.Zero, 0, blob, blobSize, 0); if (error != ErrorCode.Success) { throw new CryptographicException((int)error); } return(hKey); } }