Android Password De/Encryption with Keystore

S_Olias_SS_Olias_S DEMember ✭✭
edited February 2016 in Xamarin.Android

I´m trying to implement a Password encryption with the Android Keystore in Xamarin. I found that tutorial for implementing it in java http://www.androidauthority.com/use-android-keystore-store-passwords-sensitive-information-623779/ I tryed my best to convert the important parts into c#. My Problem now is that everything works fine, no errors. But i get an array of 256 0 (which is the number of entrys i put encypted into the Stream for decryption)back in the "values" list after decrypting... I should get about 6 bytes back. The appname is also shown in the aliaslist, so the key should be there.

class Security:ISecurity
    {
        readonly KeyStore _keyStore;
        private readonly string _alias = "appname";
        private Locale local = Locale.Germany;
        private String encryptedText;
        private FileHelperLocal _helper = new FileHelperLocal();
        private byte[] vals;
        private List<Java.Lang.Object> aliaslist;
        public Security()
        {
            _keyStore = KeyStore.GetInstance("AndroidKeyStore");
            _keyStore.Load(null);
            aliaslist = new List<Java.Lang.Object>();
            var alias = _keyStore.Aliases();
            createNewKey();
            while (alias.HasMoreElements)
            {
                aliaslist.Add(alias.NextElement());
            }
        }
        public async void SaveCredential(string userName, String password)
        {
            KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)_keyStore.GetEntry(_alias, null);
            var publicKey = privateKeyEntry.Certificate.PublicKey;//


            Cipher input = Cipher.GetInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
            input.Init(CipherMode.EncryptMode, publicKey);//

        MemoryStream outputStream = new MemoryStream();
        CipherOutputStream cipherOutputStream = new CipherOutputStream(
                outputStream, input);
        cipherOutputStream.Write(System.Text.Encoding.UTF8.GetBytes(password));
        cipherOutputStream.Close();

        vals = outputStream.ToArray();
    }

    public byte[] GetCredential()
    {
        string[] credentials = new string[2];
        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)_keyStore.GetEntry(_alias, null);
        var privateKey = privateKeyEntry.PrivateKey;//

        Cipher output = Cipher.GetInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
        output.Init(CipherMode.EncryptMode, privateKey);

        CipherInputStream cipherInputStream = new CipherInputStream(
                new MemoryStream(vals), output);

        List<byte> values = new List<byte>();

        int nextByte;
        while ((nextByte = cipherInputStream.Read()) != -1)
        {
            values.Add((byte)nextByte);
        }    

        return  values;
    }

    public void RemoveCredential(string userName)
    {
        _keyStore.DeleteEntry(_alias);
    }

    private void createNewKey()
    {
        if (!_keyStore.ContainsAlias(_alias))
        {
            Calendar start = Calendar.GetInstance(local);
            Calendar end = Calendar.GetInstance(local);
            end.Add(CalendarField.Year, 1);
            KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(Xamarin.Forms.Forms.Context)
                    .SetAlias(_alias)
                    .SetSubject(new X500Principal("CN=Sample Name, O=Android Authority"))
                    .SetSerialNumber(BigInteger.One)
                    .SetStartDate(start.Time)
                    .SetEndDate(end.Time)
                    .Build();
            KeyPairGenerator generator = KeyPairGenerator.GetInstance("RSA", "AndroidKeyStore");
            generator.Initialize(spec);

            KeyPair keyPair = generator.GenerateKeyPair();
        }
    }
}

Answers

  • KyleRobitailleKyleRobitaille USUniversity ✭✭
    edited August 2017

    I know this is a bit old now, but were you ever able to figure out what the problem was? I'm running into the exact same issue. To me it looks like CipherInputStream isn't writing to the memory stream correctly.

Sign In or Register to comment.