I'm using a self signed certificate to secure a websocket connection using Fleck. On the Fleck website it says:
Enabling secure connections requires two things: using the scheme wss instead of ws, and pointing Fleck to an x509 certificate containing a public and private key
I'm using Powershell to generate a CA then using the CA to sign a certificate and store it in the local machine store, no problem. However, when I retrieve the certificate in my application, the certificate doesn't include the private key and the websocket connection fails.
When I look at the certificate properties of a working certificate in Visual Studio and compare it with a failing certificate I see an exception being thrown on the PrivateKey portion of the failing certificate
I have been looking at this for hours and I can't figure out how to generate the correct certificate in Powershell. This is what I'm using to generate the certificate:
$rootcert = New-SelfSignedCertificate -CertStoreLocation cert:\CurrentUser\My -DnsName "Test CA" -KeyAlgorithm RSA -KeyUsage CertSign -HashAlgorithm SHA512 -KeyLength 4096 -NotAfter (Get-Date).AddYears(2) -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -KeyExportPolicy Exportable -KeyProtection None
Export-Certificate -Cert $rootcert -FilePath C:\Users\default\Desktop\TestRootCA.cer
Import-Certificate -FilePath C:\Users\default\Desktop\TestRootCA.cer -CertStoreLocation Cert:\LocalMachine\Root
$rootca = Get-ChildItem cert:\CurrentUser\my | Where-Object {$_.Issuer.Contains("Test")}
New-SelfSignedCertificate -CertStoreLocation cert:\LocalMachine\My -Signer $rootca -FriendlyName "TEST" -Subject "TestTransactions" -KeyAlgorithm RSA -KeyLength 2048 -KeyUsage KeyEncipherment, DigitalSignature -HashAlgorithm SHA512 -TextExtension @("2.5.29.17={text}DNS=localhost&IPAddress=127.0.0.1","2.5.29.37={text}1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.1") -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider"
I thought I had found the answer when I stumbled across this StackExchange post. One of the answers mentioned changing the provider for the certificate but that solve the problem for me. How can I generate an appropriate certificate using Powershell?
-- Edit --
When I attempt to access the private key the error message is: Keyset does not exist
and the stacktrace:
at System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)
at System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle)
at System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 dwKeySize, CspParameters parameters, Boolean useDefaultKeySize)
at System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()
at TWCP.Services.CertificateService.GetCertificateFromStore() in H:\Visual Studio Projects\TWCP\Services\CertificateService.cs:line 74
at TWCP.ViewModels.MainWindowViewModel.Startup() in H:\Visual Studio Projects\TWCP\ViewModels\MainWindowViewModel.cs:line 139
at TWCP.ViewModels.MainWindowViewModel.<get_StartupCommand>b__54_0() in H:\Visual Studio Projects\TWCP\ViewModels\MainWindowViewModel.cs:line 122
at TWCP.Helpers.DelegateCommand.Execute(Object parameter) in H:\Visual Studio Projects\TWCP\Helpers\DelegateCommand.cs:line 20
at System.Windows.Interactivity.InvokeCommandAction.Invoke(Object parameter)
at System.Windows.Interactivity.TriggerBase.InvokeActions(Object parameter)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.BroadcastEventHelper.BroadcastEvent(DependencyObject root, RoutedEvent routedEvent)
at System.Windows.BroadcastEventHelper.BroadcastLoadedEvent(Object root)
at MS.Internal.LoadedOrUnloadedOperation.DoWork()
at System.Windows.Media.MediaContext.FireLoadedPendingCallbacks()
at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
at System.Windows.Interop.HwndTarget.OnResize()
at System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
CryptographicException
shown in the second screenshot (message + error code + stack trace) - Mathias R. JessenPFX
" is indeed a shorthand for PKCS#12 which is one of those container formats. See en.wikipedia.org/wiki/PKCS_12 - Patrick Mevzek