コード例 #1
0
 private static unsafe void ImportEncryptedPkcs8Overwrite(
     byte[] encryptedPkcs8,
     string keyName,
     SafeNCryptProviderHandle provHandle,
     bool machineScope,
     string password)
 {
     SafeNCryptKeyHandle keyHandle;
     fixed (char* passwordPtr = password)
     fixed (char* keyNamePtr = keyName)
     fixed (byte* blobPtr = encryptedPkcs8)
     {
         NativeMethods.NCrypt.NCryptBuffer* buffers = stackalloc NativeMethods.NCrypt.NCryptBuffer[2];
         buffers[0] = new NativeMethods.NCrypt.NCryptBuffer
         {
             BufferType = NativeMethods.NCrypt.BufferType.PkcsSecret,
             cbBuffer = checked(2 * (password.Length + 1)),
             pvBuffer = new IntPtr(passwordPtr),
         };
         if (buffers[0].pvBuffer == IntPtr.Zero)
         {
             buffers[0].cbBuffer = 0;
         }
         buffers[1] = new NativeMethods.NCrypt.NCryptBuffer
         {
             BufferType = NativeMethods.NCrypt.BufferType.PkcsName,
             cbBuffer = checked(2 * (keyName.Length + 1)),
             pvBuffer = new IntPtr(keyNamePtr),
         };
         NativeMethods.NCrypt.NCryptBufferDesc desc = new NativeMethods.NCrypt.NCryptBufferDesc
         {
             cBuffers = 2,
             pBuffers = (IntPtr)buffers,
             ulVersion = 0,
         };
         NativeMethods.NCrypt.NCryptImportFlags flags =
             NativeMethods.NCrypt.NCryptImportFlags.NCRYPT_OVERWRITE_KEY_FLAG |
             NativeMethods.NCrypt.NCryptImportFlags.NCRYPT_DO_NOT_FINALIZE_FLAG;
         if (machineScope)
         {
             flags |= NativeMethods.NCrypt.NCryptImportFlags.NCRYPT_MACHINE_KEY_FLAG;
         }
         int errorCode = NativeMethods.NCrypt.NCryptImportKey(
             provHandle,
             IntPtr.Zero,
             NCRYPT_PKCS8_PRIVATE_KEY_BLOB,
             ref desc,
             out keyHandle,
             new IntPtr(blobPtr),
             encryptedPkcs8.Length,
             flags);
         if (errorCode != 0)
         {
             keyHandle.Dispose();
             throw new Win32Exception(errorCode);
         }
         using (keyHandle)
         using (CngKey cngKey = CngKey.Open(keyHandle, CngKeyHandleOpenOptions.None))
         {
             const CngExportPolicies desiredPolicies =
                 CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport;
             cngKey.SetProperty(
                 new CngProperty(
                     "Export Policy",
                     BitConverter.GetBytes((int)desiredPolicies),
                     CngPropertyOptions.Persist));
             int error = NativeMethods.NCrypt.NCryptFinalizeKey(keyHandle, 0);
             if (error != 0)
             {
                 throw new Win32Exception(error);
             }
         }
     }
 }
コード例 #2
0
 private static unsafe byte[] ExportEncryptedPkcs8(
     CngKey cngKey,
     string password,
     int kdfCount)
 {
     var pbeParams = new NativeMethods.NCrypt.PbeParams();
     NativeMethods.NCrypt.PbeParams* pbeParamsPtr = &pbeParams;
     byte[] salt = new byte[NativeMethods.NCrypt.PbeParams.RgbSaltSize];
     using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
     {
         rng.GetBytes(salt);
     }
     pbeParams.Params.cbSalt = salt.Length;
     Marshal.Copy(salt, 0, (IntPtr)pbeParams.rgbSalt, salt.Length);
     pbeParams.Params.iIterations = kdfCount;
     fixed (char* stringPtr = password)
     fixed (byte* oidPtr = s_pkcs12TripleDesOidBytes)
     {
         NativeMethods.NCrypt.NCryptBuffer* buffers =
             stackalloc NativeMethods.NCrypt.NCryptBuffer[3];
         buffers[0] = new NativeMethods.NCrypt.NCryptBuffer
         {
             BufferType = NativeMethods.NCrypt.BufferType.PkcsSecret,
             cbBuffer = checked(2 * (password.Length + 1)),
             pvBuffer = (IntPtr)stringPtr,
         };
         if (buffers[0].pvBuffer == IntPtr.Zero)
         {
             buffers[0].cbBuffer = 0;
         }
         buffers[1] = new NativeMethods.NCrypt.NCryptBuffer
         {
             BufferType = NativeMethods.NCrypt.BufferType.PkcsAlgOid,
             cbBuffer = s_pkcs12TripleDesOidBytes.Length,
             pvBuffer = (IntPtr)oidPtr,
         };
         buffers[2] = new NativeMethods.NCrypt.NCryptBuffer
         {
             BufferType = NativeMethods.NCrypt.BufferType.PkcsAlgParam,
             cbBuffer = sizeof(NativeMethods.NCrypt.PbeParams),
             pvBuffer = (IntPtr)pbeParamsPtr,
         };
         var desc = new NativeMethods.NCrypt.NCryptBufferDesc
         {
             cBuffers = 3,
             pBuffers = (IntPtr)buffers,
             ulVersion = 0,
         };
         using (var keyHandle = cngKey.Handle)
         {
             int result = NativeMethods.NCrypt.NCryptExportKey(
                 keyHandle,
                 IntPtr.Zero,
                 NCRYPT_PKCS8_PRIVATE_KEY_BLOB,
                 ref desc,
                 null,
                 0,
                 out int bytesNeeded,
                 0);
             if (result != 0)
             {
                 throw new Win32Exception(result);
             }
             byte[] exported = new byte[bytesNeeded];
             result = NativeMethods.NCrypt.NCryptExportKey(
                 keyHandle,
                 IntPtr.Zero,
                 NCRYPT_PKCS8_PRIVATE_KEY_BLOB,
                 ref desc,
                 exported,
                 exported.Length,
                 out bytesNeeded,
                 0);
             if (result != 0)
             {
                 throw new Win32Exception(result);
             }
             if (bytesNeeded != exported.Length)
             {
                 Array.Resize(ref exported, bytesNeeded);
             }
             return exported;
         }
     }
 }