Search code examples
androidxamarincertificatex509certificate2securestring

xamarin.android X509Certificate2 constructor/import failed with SecureString password instead of plain string


I have a self signed certificate with private key in a PFX file. It is added as resource in a Xamarin.Android c# application in Visual Studio 2015. I'm using it as client certificate to establish secure HTTPS connection to a Web service.

To do this I import the certificate in a X509Certificate2 object. When I supply the password for the certificate's private key as a plain text (string) it works well, but I would like to use the X509Certificate2 constructors/import methods which use SecureString.

Unfortunately they throw

'Unable to decode certificate exception'

in that case, no matter if constructor or import method is used, no matter if the certificate is passed as byte[] or file name.

My question is why it fails with the password in a SecureString while works well with plain string and how to proceed in order to use SecureString for the password.

Thanks!

Georgi

Just to add that the same code with same certificate file and password works well under Windows 10, .NET 4 Otherwise Xamarin.Android is 6.1.1.1 and Xamarin extension is 4.1.1.3, minimum android to target is API level 19, tested on Android 6.0


Solution

  • The reason is that SecureString is not completely supported in Mono. See the source for a comment. It calls the certificate class' Import method and passes a (string)null:

    [MonoTODO ("SecureString is incomplete")]
    public override void Import (byte[] rawData, SecureString password, X509KeyStorageFlags keyStorageFlags)
    {
        Import (rawData, (string) null, keyStorageFlags);
    }
    

    Also note that SecureString does not make your data 100% secure:

    Overall, SecureString is more secure than String because it limits the exposure of sensitive string data. However, those strings may still be exposed to any process or operation that has access to raw memory, such as a malicious process running on the host computer, a process dump, or a user-viewable swap file. Instead of using SecureString to protect passwords, the recommended alternative is to use an opaque handle to credentials that are stored outside of the process.