使用单个Cipher对象或两个不同的对象进行解密和加密操作?

Ebr*_*Him 6 java cryptography javacard

如您所知,当我们想要使用Java卡进行加密操作时,我们必须使用Cipher对象.我的问题实际上与效率有关.假设我想使用AES密钥执行一些加密解密操作.

以下哪种策略更好?

  1. 定义两个不同的Cipher对象并使用单个键初始化它们,但不同的模式(MODE_ENCRYPTMODE_DECRYPT).然后对于每个操作,我只需要doFinal()在适当的对象上调用方法.
  2. 定义单个Cipher对象,每次调用doFinal()方法之前init(),使用正确的模式对对象执行方法调用.

voj*_*jta 4

首先,根据文档Cipher.doFinal(...)

CBC 模式下的 AES、DES、三重 DES 和韩国 SEED 算法将初始向量(IV)重置为 0。可以使用该方法重新初始化初始向量(IV)init(Key, byte, byte[], short, short)

这意味着,如果您使用具有非零 IV 的 AES-CBC,则必须init在每个之后调用doFinal,所以实际上别无选择。


现在让我们看一下我在 NXP 的 J2E145 卡上所做的一些实际测量。

每个对象实例ALG_AES_BLOCK_128_CBC_NOPADALG_AES_BLOCK_128_ECB_NOPAD需要34 字节 RAM32 字节持久内存。

关于时间消耗,有4种可能的情况:

情况1:相同的瞬态密钥:

key1 = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES_TRANSIENT_DESELECT,
 KeyBuilder.LENGTH_AES_128, false);
...
cipher.init(key1, Cipher.MODE_DECRYPT);
cipher.init(key1, Cipher.MODE_ENCRYPT);
Run Code Online (Sandbox Code Playgroud)

结果:每个11 毫秒init(...)

情况2:不同的瞬态键:

key1 = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES_TRANSIENT_DESELECT,
     KeyBuilder.LENGTH_AES_128, false);
key2 = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES_TRANSIENT_DESELECT,
     KeyBuilder.LENGTH_AES_128, false);
...
cipher.init(key1, Cipher.MODE_DECRYPT);
cipher.init(key2, Cipher.MODE_ENCRYPT);
Run Code Online (Sandbox Code Playgroud)

结果:每个18 毫秒init(...)

情况3:相同的持久密钥:

key1 = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES,
 KeyBuilder.LENGTH_AES_128, false);
...
cipher.init(key1, Cipher.MODE_DECRYPT);
cipher.init(key1, Cipher.MODE_ENCRYPT);
Run Code Online (Sandbox Code Playgroud)

结果:每个12 毫秒init(...)

情况4:不同的持久键:

key1 = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES,
     KeyBuilder.LENGTH_AES_128, false);
key2 = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES,
     KeyBuilder.LENGTH_AES_128, false);
...
cipher.init(key1, Cipher.MODE_DECRYPT);
cipher.init(key2, Cipher.MODE_ENCRYPT);
Run Code Online (Sandbox Code Playgroud)

结果:每个19 毫秒init(...)

结论: init与内存类型无关,速度确实很快,因为 EEPROM 仅被读取并复制到实例的内部(瞬时)内存中Cipher。虽然我可以想象一些对时间消耗要求很高的情况,但 34 个 RAM 字节对于 20ms 来说似乎太多了。当然,您的平台上的确切结果可能会有所不同,但权衡效率将或多或少保持不变。