mirror of
https://github.com/bitwarden/android.git
synced 2024-10-31 23:25:45 +03:00
cleanup rsa encryption
This commit is contained in:
parent
93176989fd
commit
cf079a159f
1 changed files with 25 additions and 45 deletions
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue