Skip to content

Instantly share code, notes, and snippets.

@MSiccDev
Last active January 19, 2022 05:33
Show Gist options
  • Select an option

  • Save MSiccDev/6c3b8bc532192cd3abb41982198e2373 to your computer and use it in GitHub Desktop.

Select an option

Save MSiccDev/6c3b8bc532192cd3abb41982198e2373 to your computer and use it in GitHub Desktop.

Revisions

  1. @MSicc MSicc renamed this gist Apr 19, 2018. 1 changed file with 0 additions and 0 deletions.
  2. @MSicc MSicc revised this gist Apr 19, 2018. 1 changed file with 0 additions and 3 deletions.
    3 changes: 0 additions & 3 deletions PlatformEncryptionKeyHelper.cs
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,3 @@



    using Android.Content;
    using Android.OS;
    using Android.Security;
  3. @MSicc MSicc created this gist Apr 19, 2018.
    111 changes: 111 additions & 0 deletions PlatformEncryptionKeyHelper.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,111 @@



    using Android.Content;
    using Android.OS;
    using Android.Security;
    using Android.Security.Keystore;
    using Java.Math;
    using Java.Security;
    using Javax.Security.Auth.X500;
    using Calendar = Android.Icu.Util.Calendar;
    using CalendarField = Android.Icu.Util.CalendarField;

    namespace [YOURNAMESPACEHERE]
    {
    public class PlatformEncryptionKeyHelper
    {
    //do not change this name, this is where the keys have to be stored on Android
    static readonly string KEYSTORE_NAME = "AndroidKeyStore";
    private readonly KeyStore _androidKeyStore;

    private readonly Context _context;
    private readonly string _keyName;

    //Supported sizes: 512, 768, 1024, 2048, 3072, 4096
    //default is 2048
    //Higher value means longer processing time!
    public int KeySize { get; set; } = 2048;

    public PlatformEncryptionKeyHelper(Context context, string keyName)
    {
    _context = context;
    _keyName = keyName.ToLowerInvariant();

    _androidKeyStore = KeyStore.GetInstance(KEYSTORE_NAME);
    _androidKeyStore.Load(null);
    }

    public bool DeleteKey()
    {
    if (!_androidKeyStore.ContainsAlias(_keyName))
    return false;

    _androidKeyStore.DeleteEntry(_keyName);
    return true;
    }

    public bool KeysExist()
    {
    return _androidKeyStore.ContainsAlias(_keyName);
    }

    public IKey GetPrivateKey()
    {
    if (!_androidKeyStore.ContainsAlias(_keyName))
    return null;

    return _androidKeyStore.GetKey(_keyName, null);
    }

    public IKey GetPublicKey()
    {
    if (!_androidKeyStore.ContainsAlias(_keyName))
    return null;

    return _androidKeyStore.GetCertificate(_keyName)?.PublicKey;
    }



    public void CreateKeyPair()
    {
    DeleteKey();

    KeyPairGenerator keyGenerator =
    KeyPairGenerator.GetInstance(KeyProperties.KeyAlgorithmRsa, KEYSTORE_NAME);

    if (Build.VERSION.SdkInt >= BuildVersionCodes.JellyBeanMr2 &&
    Build.VERSION.SdkInt <= BuildVersionCodes.LollipopMr1)
    {
    var calendar = Calendar.GetInstance(_context.Resources.Configuration.Locale);
    var endDate = Calendar.GetInstance(_context.Resources.Configuration.Locale);
    endDate.Add(CalendarField.Year, 20);

    //this API is obsolete after Android M, but I am supporting Android L, so I need this
    #pragma warning disable 618
    var builder = new KeyPairGeneratorSpec.Builder(_context)
    #pragma warning restore 618
    .SetAlias(_keyName).SetSerialNumber(BigInteger.One)
    .SetSubject(new X500Principal($"CN={_keyName} CA Certificate"))
    .SetStartDate(calendar.Time)
    .SetEndDate(endDate.Time).SetKeySize(KeySize);

    keyGenerator.Initialize(builder.Build());
    }
    else if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
    {
    var builder =
    new KeyGenParameterSpec.Builder(_keyName, KeyStorePurpose.Encrypt | KeyStorePurpose.Decrypt)
    .SetBlockModes(KeyProperties.BlockModeEcb)
    .SetEncryptionPaddings(KeyProperties.EncryptionPaddingRsaPkcs1)
    .SetRandomizedEncryptionRequired(false).SetKeySize(KeySize);

    keyGenerator.Initialize(builder.Build());
    }

    keyGenerator.GenerateKeyPair();
    }

    }
    }