我正在尝试在 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 应用程序并尝试用它创建 key 。
SecretKeySpec secretKeySpec = new SecretKeySpec(symKeyData, "AES");
我知道 SymKeyData == rnd。我可以使用这个 SecretKey 来加密某些内容,但是当我解密时,我收到错误:“鉴于最终 block 未正确填充”
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");
但没有成功,异常:“错误的 key ”
找到解决方案
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);
最佳答案
我认为这是因为您在没有 pad 的情况下启动加密:
Cipher symCipher = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false);
数据被逐 block 分割和加密。这些 block 的大小与 key 相同,因为您需要加密的数据不一定是 key 的倍数,您必须指定填充方法,以便最后一个 block 将“完整”以适合 key 大小。
将填充方法更改为:
Cipher symCipher = Cipher.getInstance(Cipher.ALG_AES_CBC_ISO9797_M2 , false);
让我们知道发生了什么。
关于java - AES key 从 javacard 到 java,加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15882088/