1. 程式人生 > 其它 >android 藍芽 名稱為null_Android的KeyStore保護資料

android 藍芽 名稱為null_Android的KeyStore保護資料

技術標籤:android 藍芽 名稱為null

bf38b186b25ae8a162d01539f5b02064.png

有知友問我keystore的知識,我們先看谷歌文件對安卓中keystore的解釋:

Android Keystore系統可讓您將加密金鑰儲存在容器中,以使其更難從裝置中提取。一旦金鑰進入金鑰庫,就可以將其用於加密操作,而金鑰材料仍不可匯出。而且,它提供了限制何時和如何使用金鑰的功能,例如要求使用者進行身份驗證才能使用金鑰,或者限制僅在某些加密模式下使用金鑰。

讓我們先清除一些有關Android Keystore系統的知識。金鑰庫不一定只用於密碼,它可以用於任何敏感資料,這樣做的方式使攻擊者或惡意/未經授權的軟體很難從我們這裡獲取此資訊。

簡單來說:應用程式只能編輯,儲存和檢索自己的金鑰。

這個概念很簡單,但功能強大。該應用將生成或接收私鑰-公鑰對,然後將其儲存在Android Keystore系統中。

然後,在將公用金鑰儲存在特定於應用程式的資料夾中之前,可以使用公用金鑰對應用程式祕密進行加密,並在需要時使用專用金鑰對相同資訊進行解密。

同樣是這樣幾個步驟:

  • 建立祕鑰
  • 加密資料
  • 解密資料

1、建立祕鑰:

在開始加密過程之前,我們需要為要用來加密/解密資料的別名提供一個名稱。可以是任何字串。只要不是一個空的。別名是生成的金鑰將出現在Android KeyStore中的條目的名稱。

final KeyGenerator keyGenerator = KeyGenerator
        .getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");

此金鑰生成器的演算法將是AES,並且我們要將金鑰/資料儲存在AndroidKeyStore中。

那麼這個KeyGenParameterSpec到底是什麼?

您可以將KeyGenParameterSpec視為我們將要生成的鍵的屬性。例如,假設我們希望金鑰在一定時間後過期,這就是我們要指定的地方。

他是我們的KeyGenParameterSpec。

final KeyGenerator keyGenerator = KeyGenerator
        .getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
       .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
        .build();

第一件事是我們傳入我們要使用的別名。接下來,我們指定目的,即加密解密資料。

由於我們使用的是“ AES / GCM / NoPadding”轉換演算法,因此我們還告訴KeyGenParameterSpec應該使用的填充型別。

2、加密資料

final KeyGenerator keyGenerator = KeyGenerator
        .getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);

final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
       .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
        .build();

keyGenerator.init(keyGenParameterSpec);
final SecretKey secretKey = keyGenerator.generateKey();

final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);

現在我們有了金鑰,我們將使用它來初始化我們的cipher物件,這將負責實際的加密。我們告訴Cipher我們將要使用的加密轉換的型別,我們指定我們現在要進行加密,然後傳入secretKey進行加密。

final KeyGenerator keyGenerator = KeyGenerator
        .getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);

final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
        .build();

keyGenerator.init(keyGenParameterSpec);
final SecretKey secretKey = keyGenerator.generateKey();

final Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);

iv = cipher.getIV();

encryption = cipher.doFinal(textToEncrypt.getBytes("UTF-8"));

接下來,我們獲取解密所需的密碼初始化向量(IV)的引用,並使用doFinal(textToEncrypt)完成加密。doFinal方法返回一個位元組陣列,它是實際的加密文字。

3、解密資料

先獲取keystore例項:

keyStore =getInstance(“ AndroidKeyStore ”); 
keyStore.load(null);

獲取secretKey。

keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
final KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore
        .getEntry(alias, null);

final SecretKey secretKey = secretKeyEntry.getSecretKey();

我們需要一個GCMParameterSpec指定身份驗證標籤的長度,並傳入我們在加密過程中較早時獲取的IV來解密。

keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
final KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore
        .getEntry(alias, null);

final SecretKey secretKey = secretKeyEntry.getSecretKey();
final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
final GCMParameterSpec spec = new GCMParameterSpec(128, encryptionIv);
cipher.init(Cipher.DECRYPT_MODE, secretKey, spec);

然後就結束了,總的來說,運用起來是十分方便的。