1

我正在尝试在 java 应用程序中使用 javacard 2.2.1 上制作的 AESKey 我如何制作 AESKEY:

RandomData randomData = RandomData.getInstance(RandomData.ALG_PSEUDO_RANDOM);
byte[] rnd = JCSystem.makeTransientByteArray((short)16, JCSystem.CLEAR_ON_RESET);
randomData.generateData(rnd, (short)0, (short)rnd.length);
AESKey symKey = (AESKey) KeyBuilder.buildKey (KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false);
symKey.setKey(rnd, (short)0);

我如何加密数据:

Cipher symCipher = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false);
symCipher.init(symKey, Cipher.MODE_ENCRYPT);
byte[] encryptedC= new byte[48];
symCipher.doFinal(c, (short)0, (short)c.length, encryptedC, (short)0);

之后,我将 rnd 发送到我的 java 应用程序并尝试用它制作密钥。

SecretKeySpec secretKeySpec = new SecretKeySpec(symKeyData, "AES");

我知道 SymKeyData == rnd。我可以使用此 SecretKey 加密某些内容,但是当我解密时出现错误:“鉴于最终块未正确填充”

Cipher cipherAes = Cipher.getInstance("AES");
cipherAes.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] decryptedBytes = cipherAes.doFinal(challengeEncrypted);

我检查了,challengeEncrypted 的长度很好。(48) 尝试过:

Cipher cipherAes = Cipher.getInstance("AES/CBC/NoPadding");

但没有成功,例外:“错误的钥匙”

找到解决方案

byte[] ivdata = new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 IvParameterSpec spec = new IvParameterSpec(ivdata);
 symetricKeyFromCard = new SecretKeySpec(symKeyData, "AES");

 Cipher cipherAes = Cipher.getInstance("AES/CBC/NoPadding");
 cipherAes.init(Cipher.DECRYPT_MODE, symetricKeyFromCard, spec);
 byte[] decryptedBytes = cipherAes.doFinal(challengeEncrypted);
4

2 回答 2

1

我认为这是因为您在没有 pad 的情况下启动了加密:

Cipher symCipher = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false);

数据被逐块分割和加密。这些块的大小与密钥相同,因为您需要加密的数据不一定是密钥的倍数,您必须指定填充方法,以便最后一个块“完整”以适合密钥大小。

将填充方法更改为:

Cipher symCipher = Cipher.getInstance(Cipher.ALG_AES_CBC_ISO9797_M2 , false);

让我们知道会发生什么。

于 2013-04-08T15:09:07.897 回答
0

找到解决方案

byte[] ivdata = new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 IvParameterSpec spec = new IvParameterSpec(ivdata);
 symetricKeyFromCard = new SecretKeySpec(symKeyData, "AES");

 Cipher cipherAes = Cipher.getInstance("AES/CBC/NoPadding");
 cipherAes.init(Cipher.DECRYPT_MODE, symetricKeyFromCard, spec);
 byte[] decryptedBytes = cipherAes.doFinal(challengeEncrypted);
于 2013-04-22T09:46:47.663 回答