2013-04-08 254 views
1

我试图用一个AESKey,在Java应用程序 上的Java卡2.2.1如何做我做AESKEY:AES密钥,加密

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); 
+0

注:加密密钥应该总是使用'RandomData.ALG_SECURE_RANDOM',从不使用ALG_PSEUDO_RANDOM为创造! – Robert 2013-04-09 08:33:25

+0

thx的评论,出于某种原因.ALG_SECURE_RANDOM总是崩溃。不知道为什么,我有一些想法。稍后再看。这适用于测试目的。 找到解决方案,请参阅文章。 – denBelg 2013-04-10 19:27:11

+0

请注意,您可以在此论坛中回答自己的问题。这比编辑问题的答案要好... – 2013-04-21 10:42:34

回答

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); 
1

我认为这是因为你启动加密没有垫:

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

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

更改填充方法:

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

,让我们知道会发生什么。

+0

AES的块长度总是128位,与密钥长度无关。对于128位AES密钥,您是对的,但仅限于此特定情况! – Robert 2013-04-09 08:31:18

+0

Thx查看我的问题。找到解决方案,请参阅后。 – denBelg 2013-04-10 19:27:37