Android 采用keyStore的方式非对称加密,配合Rxjava2更好用
2017-11-29 11:32
671 查看
加密的代码如下
使用
1,初始化
2,加密
3,解密
4,保存一些隐私数据
获取隐私数据
public class RxSecureStorage { private static final String AndroidKeyStore = "AndroidKeyStore"; private Context context; private String alias; private KeyStore keyStore; private RxSharedPreferences sharedPreferences; public RxSecureStorage(Context context, String alias) { this.context = context.getApplicationContext(); this.alias = alias; SharedPreferences prefs = context.getSharedPreferences( String.format("%s-%s", context.getPackageName(), alias), Context.MODE_PRIVATE); this.sharedPreferences = RxSharedPreferences.create(prefs); } public static RxSecureStorage create(Context context, String alias) { return new RxSecureStorage(context, alias); } private void initIfNecessary() throws Exception { if (keyStore != null) { return; } try { keyStore = KeyStore.getInstance(AndroidKeyStore); keyStore.load(null); if (!keyStore.containsAlias(alias)) { // Generate a key pair for encryption Calendar start = Calendar.getInstance(); Calendar end = Calendar.getInstance(); end.add(Calendar.YEAR, 30); KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context.getApplicationContext()) .setAlias(alias) .setSubject(new X500Principal("CN=" + alias)) .setSerialNumber(BigInteger.TEN) .setStartDate(start.getTime()) .setEndDate(end.getTime()) .build(); KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", AndroidKeyStore); kpg.initialize(spec); kpg.generateKeyPair(); } } catch (Exception e) { throw new Exception("Failed to initialize this RxSecureStorage instance.", e); } } public Single<byte[]> encrypt(final byte[] data) { return Single.fromCallable( new Callable<byte[]>() { @Override public byte[] call() throws Exception { initIfNecessary(); ByteArrayOutputStream outputStream = null; CipherOutputStream cipherOutputStream = null; try { KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias, null); PublicKey publicKey = privateKeyEntry.getCertificate().getPublicKey(); Cipher input = getCipher(); input.init(Cipher.ENCRYPT_MODE, publicKey); outputStream = new ByteArrayOutputStream(); cipherOutputStream = new CipherOutputStream(outputStream, input); cipherOutputStream.write(data); closeQu e8a8 ietely(cipherOutputStream); return outputStream.toByteArray(); } catch (Exception e) { throw new Exception("Failed to encrypt data with alias" + alias, e); } finally { closeQuietely(cipherOutputStream); closeQuietely(outputStream); } } }) .observeOn(Schedulers.computation()); } public Single<String> encryptString(String text) { byte[] textBytes; try { textBytes = text.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { return Single.error(new Exception("Failed convert text to bytes.", e)); } return encrypt(textBytes) .map( new Function<byte[], String>() { @Override public String apply(byte[] encryptedData) throws Exception { return Base64.encodeToString(encryptedData, Base64.DEFAULT); } }) .observeOn(Schedulers.computation()); } public Single<byte[]> decrypt(final byte[] encryptedData) { return Single.fromCallable( new Callable<byte[]>() { @Override public byte[] call() throws Exception { initIfNecessary(); CipherInputStream cipherInputStream = null; ByteArrayOutputStream bos = null; try { KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias, null); PrivateKey privateKey = privateKeyEntry.getPrivateKey(); Cipher output = getCipher(); output.init(Cipher.DECRYPT_MODE, privateKey); cipherInputStream = new CipherInputStream(new ByteArrayInputStream(encryptedData), output); bos = new ByteArrayOutputStream(); byte[] buffer = new byte[512]; int read; while ((read = cipherInputStream.read(buffer)) != -1) { bos.write(buffer, 0, read); } return bos.toByteArray(); } catch (Exception e) { throw new Exception("Failed to decrypt data with " + alias, e); } finally { closeQuietely(cipherInputStream); closeQuietely(bos); } } }) .observeOn(Schedulers.computation()); } public Single<String> decryptString(String encryptedText) { byte[] textBytes = new byte[0]; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.FROYO) { textBytes = Base64.decode(encryptedText, Base64.DEFAULT); } return decrypt(textBytes) .map( new Function<byte[], String>() { @Override public String apply(byte[] encryptedData) throws Exception { return new String(encryptedData, 0, encryptedData.length); } }) .observeOn(Schedulers.computation()); } public Observable<byte[]> getBytes(String name) { return sharedPreferences .getString(name) .asObservable() .map( new Function<String, byte[]>() { @Override public byte[] apply(String base64Value) throws Exception { byte[] encryptedValue = Base64.decode(base64Value, Base64.DEFAULT); return decrypt(encryptedValue).blockingGet(); } }); } public Single<Boolean> putBytes(final String name, @Nullable byte[] value) { if (value == null) { sharedPreferences.getString(name).delete(); return Single.just(false); } return encrypt(value) .map( new Function<byte[], Boolean>() { @Override public Boolean apply(byte[] encryptedData) throws Exception { String encryptedString = Base64.encodeToString(encryptedData, Base64.DEFAULT); sharedPreferences.getString(name).set(encryptedString); return true; } }); } public Observable<String> getString(String name) { return sharedPreferences .getString(name) .asObservable() .map( new Function<String, String>() { @Override public String apply(String encryptedValue) throws Exception { if (encryptedValue == null || encryptedValue.trim().isEmpty()) { return null; } return decryptString(encryptedValue).blockingGet(); } }); } public Single<Boolean> putString(final String name, @Nullable String value) { if (value == null) { sharedPreferences.getString(name).delete(); return Single.just(false); } return encryptString(value) .map( new Function<String, Boolean>() { @Override public Boolean apply(String encryptedValue) throws Exception { sharedPreferences.getString(name).set(encryptedValue); return true; } }); } public void dispose() { this.context = null; this.alias = null; this.keyStore = null; this.sharedPreferences = null; } private static Cipher getCipher() { try { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { // below android m // error in android 6: InvalidKeyException: Need RSA private or public key return Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL"); } else { // error in android 5: NoSuchProviderException: Provider not available: AndroidKeyStoreBCWorkaround return Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround"); } } catch (Exception exception) { throw new RuntimeException("getCipher: Failed to get an instance of Cipher", exception); } } private static void closeQuietely(Closeable c) { try { c.close(); } catch (Throwable ignored) { } } }
使用
1,初始化
RxSecureStorage secureStorage = RxSecureStorage.create(this, "alias_name")
2,加密
secureStorage .encryptString("string to encrypt") .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { // Use the resulting string }, error -> { // Handle error });
3,解密
secureStorage .decryptString("9yIfhiwf3eDENxI1XG/XWYZOPc5RH6B9ez9y7I7BtEsig==") .observeOn(AndroidSchedulers.mainThread()) .subscribe(result -> { // Use the resulting string }, error -> { // Handle error });
4,保存一些隐私数据
secureStorage.putString("key", "hello, world!").subscribe();
获取隐私数据
secureStorage .getString("key") .subscribe( latest -> { // preference was changed, here's the latest decryped value });
相关文章推荐
- Android Keystore 对称-非对称加密
- Android: AndroidKeyStore 非对称RSA加密解密
- Android与服务器交互方式中的对称加密和非对称加密
- android Java语言非对称加密的实现
- 【黑马Android】(05)短信/查询和添加/内容观察者使用/子线程网络图片查看器和Handler消息处理器/html查看器/使用HttpURLConnection采用Post方式请求数据/开源项目
- Android 生成keystore,两种方式
- [android] 采用GET方式提交数据到服务器
- [android] 采用post的方式提交数据
- Android 获取wifi的加密方式
- Android 生成keystore,两种方式 【包括Mac下制作】
- Android 生成keystore,两种方式(转载)
- 关于RSA非对称加密在Android应用中的使用
- spring-cloud-config 非对称加密 keystore 文件加载异常
- [android]DES/3DES/AES加密方式
- android入门_采用android-async-http开源项目的GET方式或POST方式实现登陆案例
- 采用maven方式开发android
- Android的基础学习:采用Pull方式解析XML文件(代码)
- Android DES/3DES/AES加密方式
- Android Retrofit 2.0框架 GET和POST的实现方式(配合RxJava)
- Java Web 登录采用非对称加密(RSA算法)