cleanup rsa encryption

This commit is contained in:
Kyle Spearrin 2017-06-05 22:25:59 -04:00
parent 93176989fd
commit cf079a159f

View file

@ -10,7 +10,6 @@ using Java.Math;
using Android.Security.Keystore; using Android.Security.Keystore;
using Android.App; using Android.App;
using Plugin.Settings.Abstractions; using Plugin.Settings.Abstractions;
using System.Collections.Generic;
using Java.Util; using Java.Util;
namespace Bit.Android.Services namespace Bit.Android.Services
@ -18,19 +17,21 @@ namespace Bit.Android.Services
public class KeyStoreBackedStorageService : ISecureStorageService public class KeyStoreBackedStorageService : ISecureStorageService
{ {
private const string AndroidKeyStore = "AndroidKeyStore"; private const string AndroidKeyStore = "AndroidKeyStore";
private const string AndroidOpenSSL = "AndroidOpenSSL";
private const string KeyAlias = "bitwardenKey"; private const string KeyAlias = "bitwardenKey";
private const string SettingsFormat = "ksSecured:{0}"; private const string SettingsFormat = "ksSecured:{0}";
private const string RsaMode = "RSA/ECB/PKCS1Padding";
private const string AesKey = "ksSecured:aesKeyForService"; private const string AesKey = "ksSecured:aesKeyForService";
private readonly string _rsaMode;
private readonly bool _oldAndroid;
private readonly ISettings _settings; private readonly ISettings _settings;
private readonly KeyStore _keyStore; private readonly KeyStore _keyStore;
private readonly bool _oldAndroid = Build.VERSION.SdkInt < BuildVersionCodes.M;
private readonly ISecureStorageService _oldKeyStorageService; private readonly ISecureStorageService _oldKeyStorageService;
public KeyStoreBackedStorageService(ISettings settings) public KeyStoreBackedStorageService(ISettings settings)
{ {
_oldAndroid = Build.VERSION.SdkInt < BuildVersionCodes.M;
_rsaMode = _oldAndroid ? "RSA/ECB/PKCS1Padding" : "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
_oldKeyStorageService = new KeyStoreStorageService(new char[] { }); _oldKeyStorageService = new KeyStoreStorageService(new char[] { });
_settings = settings; _settings = settings;
@ -118,6 +119,7 @@ namespace Bit.Android.Services
return; return;
} }
var gen = KeyPairGenerator.GetInstance(KeyProperties.KeyAlgorithmRsa, AndroidKeyStore);
var start = Calendar.Instance; var start = Calendar.Instance;
var end = Calendar.Instance; var end = Calendar.Instance;
end.Add(CalendarField.Year, 30); end.Add(CalendarField.Year, 30);
@ -125,7 +127,6 @@ namespace Bit.Android.Services
if(_oldAndroid) if(_oldAndroid)
{ {
var gen = KeyPairGenerator.GetInstance(KeyProperties.KeyAlgorithmRsa, AndroidKeyStore);
var spec = new KeyPairGeneratorSpec.Builder(Application.Context) var spec = new KeyPairGeneratorSpec.Builder(Application.Context)
.SetAlias(KeyAlias) .SetAlias(KeyAlias)
.SetSubject(subject) .SetSubject(subject)
@ -135,21 +136,22 @@ namespace Bit.Android.Services
.Build(); .Build();
gen.Initialize(spec); gen.Initialize(spec);
gen.GenerateKeyPair();
} }
else else
{ {
var gen = KeyGenerator.GetInstance(KeyProperties.KeyAlgorithmRsa, AndroidKeyStore);
var spec = new KeyGenParameterSpec.Builder(KeyAlias, KeyStorePurpose.Decrypt | KeyStorePurpose.Encrypt) var spec = new KeyGenParameterSpec.Builder(KeyAlias, KeyStorePurpose.Decrypt | KeyStorePurpose.Encrypt)
.SetCertificateSubject(subject) .SetCertificateSubject(subject)
.SetCertificateSerialNumber(BigInteger.Ten) .SetCertificateSerialNumber(BigInteger.Ten)
.SetKeyValidityStart(start.Time) .SetKeyValidityStart(start.Time)
.SetKeyValidityEnd(end.Time) .SetKeyValidityEnd(end.Time)
.SetDigests(KeyProperties.DigestSha256)
.SetEncryptionPaddings(KeyProperties.EncryptionPaddingRsaOaep)
.Build(); .Build();
gen.Init(spec); gen.Initialize(spec);
gen.GenerateKey();
} }
gen.GenerateKeyPair();
} }
private KeyStore.PrivateKeyEntry GetRsaKeyEntry() private KeyStore.PrivateKeyEntry GetRsaKeyEntry()
@ -192,48 +194,26 @@ namespace Bit.Android.Services
} }
} }
private byte[] RsaEncrypt(byte[] input) private byte[] RsaEncrypt(byte[] data)
{ {
var entry = GetRsaKeyEntry(); using(var entry = GetRsaKeyEntry())
var inputCipher = Cipher.GetInstance(RsaMode, AndroidOpenSSL); using(var cipher = Cipher.GetInstance(_rsaMode))
inputCipher.Init(CipherMode.EncryptMode, entry.Certificate.PublicKey); {
cipher.Init(CipherMode.EncryptMode, entry.Certificate.PublicKey);
var outputStream = new MemoryStream(); var cipherText = cipher.DoFinal(data);
var cipherStream = new CipherOutputStream(outputStream, inputCipher); return cipherText;
cipherStream.Write(input); }
cipherStream.Close();
var vals = outputStream.ToArray();
outputStream.Close();
return vals;
} }
private byte[] RsaDecrypt(byte[] encInput) private byte[] RsaDecrypt(byte[] encData)
{ {
var entry = GetRsaKeyEntry(); using(var entry = GetRsaKeyEntry())
var outputCipher = Cipher.GetInstance(RsaMode, AndroidOpenSSL); using(var cipher = Cipher.GetInstance(_rsaMode))
outputCipher.Init(CipherMode.DecryptMode, entry.PrivateKey);
var inputStream = new MemoryStream(encInput);
var cipherStream = new CipherInputStream(inputStream, outputCipher);
var values = new List<byte>();
int nextByte;
while((nextByte = cipherStream.Read()) != -1)
{ {
values.Add((byte)nextByte); cipher.Init(CipherMode.DecryptMode, entry.PrivateKey);
var plainText = cipher.DoFinal(encData);
return plainText;
} }
inputStream.Close();
cipherStream.Close();
var bytes = new byte[values.Count];
for(var i = 0; i < bytes.Length; i++)
{
bytes[i] = values[i];
}
return bytes;
} }
private byte[] TryGetAndMigrateFromOldKeyStore(string key) private byte[] TryGetAndMigrateFromOldKeyStore(string key)