2013-04-08 2 views
1

Я пытаюсь использовать AESKey, сделанные на JavaCard 2.2.1 в приложении Java Как я сделать AESKEY:AES ключ от JavaCard к Java, шифрования

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

+0

thx для комментария, по какой-то причине .ALG_SECURE_RANDOM всегда сбой. Не знаю, почему еще, у меня есть несколько идей. Посмотрим позже. Это работает для целей тестирования. Найдено решение, см. Сообщение. – denBelg

+0

Обратите внимание, что вы можете ответить на свой вопрос на этом форуме. Это лучше, чем редактирование ответа на вопрос ... –

ответ

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

+0

Thx для изучения моей проблемы. Найден решение, см. Сообщение. – denBelg