Home > Back-end >  Read X509 certificate in android .net 6.0 application
Read X509 certificate in android .net 6.0 application

Time:11-26

I am trying to migrate my .net android app from "android xamarin app" to .net 6.0. I finally made build and now it falls each time I start it on reading X509 certificate from byte array:

return new X509Certificate(bytes);

I am sure that certificate is valid since there were no problem before migration. Stacktrace of exception is:

System.PlatformNotSupportedException: Cryptography_AlgorithmNotSupported, RC2
at System.Security.Cryptography.PasswordBasedEncryption.CreateRC2()
at System.Security.Cryptography.PasswordBasedEncryption.Decrypt(AlgorithmIdentifierAsn& algorithmIdentifier, ReadOnlySpan`1 password, ReadOnlySpan`1 passwordBytes, ReadOnlySpan`1 encryptedData, Span`1 destination)
Internal.Cryptography.Pal.UnixPkcs12Reader.DecryptAndProcessSafeContents(ReadOnlySpan`1 password, CertBagAsn[]& certBags, AttributeAsn[][]& certBagAttrs, Int32& certBagIdx, SafeBagAsn[]& keyBags, Int32& keyBagIdx)
at Internal.Cryptography.Pal.UnixPkcs12Reader.Decrypt(ReadOnlySpan`1 password, ReadOnlyMemory`1 authSafeContents)
at Internal.Cryptography.Pal.UnixPkcs12Reader.VerifyAndDecrypt(ReadOnlySpan`1 password, ReadOnlyMemory`1 authSafeContents)
at Internal.Cryptography.Pal.UnixPkcs12Reader.Decrypt(SafePasswordHandle password, Boolean ephemeralSpecified)
Exception_EndOfInnerExceptionStack
at Internal.Cryptography.Pal.UnixPkcs12Reader.Decrypt(SafePasswordHandle password, Boolean ephemeralSpecified)
at Internal.Cryptography.Pal.AndroidCertificatePal.ReadPkcs12(ReadOnlySpan`1 rawData, SafePasswordHandle password, Boolean ephemeralSpecified)
at Internal.Cryptography.Pal.AndroidCertificatePal.FromBlob(ReadOnlySpan`1 rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at Internal.Cryptography.Pal.CertificatePal.FromBlob(ReadOnlySpan`1 rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] data)
...

I tried to find some information about it and just found that I can't create "RC2" in runtime/src/libraries/Common/src/Internal/Cryptography/Helpers.cs file:

#if NET5_0_OR_GREATER
        [UnsupportedOSPlatformGuard("android")]
        [UnsupportedOSPlatformGuard("browser")]
        public static bool IsRC2Supported => !OperatingSystem.IsAndroid();
#else
        public static bool IsRC2Supported => true;
#endif

So the questions are:
Does anyone know why is this code unsupported?
Could I somehow use x509 certificate in my .net 6.0 android app?

CodePudding user response:

Does anyone know why is this code unsupported?

.NET 6 for Android uses the Android built-in cryptographic providers, and those don't include RC2.

now it falls each time I start it on reading X509 certificate from byte array

Your bytes aren't, technically, a certificate. They're a PFX, and the certificate(s) in that PFX are encrypted with 40-bit RC2 (an algorithm so weak that it may as well be ROT13, but that was the balancing act of 1990s US cryptographic regulations... then tradition).

Could I somehow use x509 certificate in my .net 6.0 android app?

If you load the PFX in .NET 6 for Windows, Linux, or macOS as exportable, then re-export it as a new PFX, it should work on Android; as all of the modern stacks should be using 3DES instead of RC2-40 (they're still using 3DES instead of AES because not all in-market OS versions wired AES up to their PFX readers).

X509Certificate2Collection coll = new X509Certificate2Collection();
coll.Import(bytes, pwd, X509KeyStorageFlags.Exportable);
byte[] newPfx = coll.Export(X509ContentType.Pfx, pwd);

Or, if you use OpenSSL's command line utility to build your PFXes, add -certpbe 3DES to your command line (e.g. openssl pkcs12 -export -in cert.cer -inkey cert.key -certpbe 3DES -out cert.pfx).

  • Related