2017-10-20 88 views
8

我正在研究使用Android KeyStore for Marshmallow及以上版本。如何在Android Keystore中使用keyed-hash消息认证码(HMAC)

我想通过采用HMAC来同时验证数据完整性和数据验证。

我该如何去做到这一点?

我电流产生的加密/解密密钥如下: -

 mKeyStore = KeyStore.getInstance(keyStoreName); 
     mKeyStore.load(mKeyStoreLoadStoreParameter); 

     if (mKeyStore.containsAlias(keyStoreAlias)) { 
      mSecretKey = (SecretKey) mKeyStore.getKey(keyStoreAlias, KEY_STORE_PASSWORD); 
     } else { 
      final KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, keyStoreName); 
      final int keyPurpose = KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT; 

      keyGenerator.init(
        new KeyGenParameterSpec.Builder(keyStoreAlias, keyPurpose) 
          .setKeySize(KEY_STORE_KEY_SIZE) 
          .setBlockModes(KeyProperties.BLOCK_MODE_GCM) 
          .setRandomizedEncryptionRequired(true) 
          .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) 
          .build()); 

      mSecretKey = keyGenerator.generateKey(); 

我发现这个样本生成HMAC的

SecretKey key = ...; // HMAC key of algorithm "HmacSHA512". 

KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 
keyStore.load(null); 
keyStore.setEntry(
     "key1", 
     new KeyStore.SecretKeyEntry(key), 
     new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN).build()); 
// Key imported, obtain a reference to it. 
SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null); 
// The original key can now be discarded. 

Mac mac = Mac.getInstance("HmacSHA512"); 
mac.init(keyStoreKey); 

但是,我怎么使用这个加密时/解密我的数据?

说明

我有很多的选择/决定任何Android应用程序中实现安全性/密码时进行。

1)。我是否实施任何类型的密码术是或否? 2)。如果是,那么......我应该尝试实现“最”安全​​的解决方案。

如果我要采用密码术,那么我需要确保以下内容。 a)。

a)。我将密码/密钥存储在“安全位置”中,例如Android密钥存储。 b)。我使用可用的“最强”加密技术。 c)。我想同时验证数据的完整性和我的数据的身份验证,例如我想检测我的加密数据是否被篡改。

据我了解我已阅读​​有关HMAC的,他们提供此功能。我想知道如何将HMAC的使用编码到我的Android应用程序中,以确保数据完整性和我的数据的身份验证。

+1

是否要将HMAC应用于密文?这可能是多余的,因为如果密文被改变,它将不能被解密。什么是最终目的? – pedrofb

+0

@pedrofb,是的,我想将HMAC应用于我的密文。虽然如果我理解使用HMAC,我不会同时加密并将HMAC应用于我的纯文本,以获得也由我的应用HMAC“保护”的加密文本? – Hector

+1

如果您将HMAC应用于密文'HMAC(加密(纯文本));'您必须在解密之前对其进行验证。如果您将HMAC应用于纯文本“HMAC(纯文本);加密(纯文本)”,则必须在解密后验证MAC,以检查原始消息是否真的相同。 – pedrofb

回答

6

您可以在解密后加密并重新计算HMAC以检查原始消息是否相同之前,将HMAC应用于纯文本HMAC(plain text)

它可能是多余的,因为如果密文被改变,你将无法解密它。

首先在AndroidKeyStore内部生成一个HMAC密钥。我发现了一个例子here

KeyGenerator keyGenerator = KeyGenerator.getInstance(
     KeyProperties.KEY_ALGORITHM_HMAC_SHA256, "AndroidKeyStore"); 
keyGenerator.initialize(
     new KeyGenParameterSpec.Builder(hmacKeyAlias, KeyProperties.PURPOSE_SIGN).build()); 
SecretKey key = keyGenerator.generateKey(); 

然后应用HMAC原始数据,并将结果存入某处

Mac mac = Mac.getInstance("HmacSHA256"); 
mac.init(key); 
byte hmacOriginalData[] = mac.doFinal(dataToEncrypt); 
//Store hmacOriginalData 

解密后,得到AndroidKeyStore HMAC密钥,重新计算HMAC和检查两台Mac相等

Key key = keyStore.getKey(hmacKeyAlias, null); 
Mac mac = Mac.getInstance("HmacSHA256"); 
mac.init(key); 
byte hmacDecryptedData[] = mac.doFinal(decryptedData); 
//Check equals(hmacDecryptedData, hmacOriginalData); 
+0

不错的工作。感谢您的时间和努力 – Hector

相关问题