加密设备上多用户共享的数据

   移动设备上的数据安全性是极为重要的。移动设备一旦丢失或被盗,而设备上的数据没有进行某种加密,将带来不可估量的损失。对于企业级应用,会使加密变得更复杂,比如由于工作模式的安排或分配任务,使得一个设备可能有多个用户使用。

 

        有几种方法试图解决这个问题,其中之一是允许授权用户访问同一设备上安全存储的数据,而不需要保存多份拷贝,这就是双层加密方法。

 

        Android实现了Java Cryptographic Extensions (JCE) ,并提供多种加密方法。加密可以在任何字节阵列上进行,所以能实现双层加密系统,其中密钥用来加密敏感数据后,用用户的密码再次加密,每个用户都保存密钥的加密拷贝。当用户希望访问数据时,他们输入自己的密码,于是可以解密数据。

 

        这种方法的好处是你只需要保存主要数据的一份拷贝,这可以节省空间。要访问数据你需要使用设备上没有保存的东西(用户密码)

 

        Android使用下面的JCE方法产生256比特的AES key:

 

KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(256);
SecretKey key = kg.generateKey();

 

       有了key之后,可以使用JCE来加密任何字节:

 

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] iv = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
byte[] encryptedData = cipher.doFinal(originalByteArray);

 

         它使用了Android 加密实现方法的另两个部分:

 

  • CBC; 这是密文段链接方法,允许加密算法能工作在特定大小的数据段(如AES),来加密比算法长的数据,它会把数据分成多个段,依次加密,然后使用某个段的加密结果去加密下一个段。
  • PKCS7Padding; 前面提到过,AES只能工作在一定大小的数据段,而CBC只能工作在段大小倍数的数据上。PKCS7Padding通过添加填充字节来保证数据有合适的大小。

 

      你需要保存iv和encryptedData 来加密数据(如果你不知道iv包括什么,请查询初始化向量及在CBC中 如何使用它们)

 

      要解密数据,你要使用同样的代码,并用Cipher.ENCRYPT_MODE替代 Cipher.DECRYPT_MODE,并提供在加密阶段获得的iv。 

 

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
byte[] originalByteArray = cipher.doFinal(encryptedData);

 

       现在已经实现第一级加密,接下来继续第二级加密,这可以允许多个用户访问同一被AES 密钥加密的数据。

 

       SecretKey JCE类包括一个获得密钥的字节阵列的函数。字节阵列可以使用下面的Password Based Encryption (PBE) 进行加密。

 

byte[] keyBytes = key.getEncoded();
PBEKeySpec passwordKeySpec = new PBEKeySpec(password.toCharArray(), salt, 100, 256);
SecretKeyFactory kf = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey passwordKey = kf.generateSecret(passwordKeySpec);
Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
cipher.init(Cipher.ENCRYPT_MODE, passwordKey);
byte[] encryptedKey = cipher.doFinal(keyBytes);

 

        salt 是用密码来创建的加密密钥的字节阵列。salt 值对每个用户都是唯一地,你应当为每个用户保存其salt 值,因为你需要它来解密密钥。另外两个数(100和256)用来构建PBEKeySpec,前一个数是加密算法迭代次数,后一个数是密码生成的密钥的比特长度。这里加密算法要用256比特的密钥加密100次。

 

        再次使用同样代码,替换DECRYPT_MODE 来解密数据(这里是AES 密钥),并从解密数据中重新生成 SecretKey 对象。

 

PBEKeySpec passwordKeySpec = new PBEKeySpec(PASSWORD.toCharArray(), salt, 100, 256);
SecretKeyFactory kf = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey passwordKey = kf.generateSecret(passwordKeySpec);
Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
cipher.init(Cipher.DECRYPT_MODE, passwordKey);
byte[] keyBytes = cipher.doFinal(encryptedKey);

SecretKey key = new SecretKeySpec(keyBytes,"AES");

 

       这就实现了第二级加密,这样每个用户都可以访问共享的加密密钥。

 

       有了双层加密系统,如果一个新用户要使用这个设备,或一个老用户不能再使用这个设备,只需要增加或删除用他们密码加密的共享密钥版本即可。如果住数据集需要更新,只需要用共享密钥加密一次即可。

 

      这样可以减少数据存储和复制,同时保证数据安全。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值