Ошибка дешифрования при хранении ключа в хранилище ключей Java - PullRequest
0 голосов
/ 16 июня 2011

Я создал ключ шифрования с помощью следующего кода:

SecretKeyFactory skFactory = SecretKeyFactory.getInstance("PBEWithSHA1AndDESede");
SecretKey key = skFactory.generateSecret(new PBEKeySpec("<some password>".toCharArray()));

Тогда я использовал ключ для шифрования текста.

Я сохранил этот ключ в хранилище ключей Java и сохранил в FS:

KeyStore ks = KeyStore.getInstance("JCEKS");
ks.setKeyEntry(keyAlias, key ,keyPassword.toCharArray(), null);
FileOutputStream fileOutputStream = new FileOutputStream (keyStorePath);
keyStore.store(fileOutputStream , keyStorePassword.toCharArray());
fileOutputStream.close();

В другом процессе я открываю хранилище ключей и пытаюсь расшифровать некоторый текст:

KeyStore ks2 = KeyStore.getInstance("JCEKS");
ks2.load(new java.io.FileInputStream(keyStorePath), ksPassword.toCharArray());
SecretKeyFactory skFactory2 = SecretKeyFactory.getInstance("PBEWithSHA1AndDESede");
String passForTheKey = ks2.getKey(keyAlias, keyPass.toCharArray()).toString();
KeySpec key = new PBEKeySpec(passForTheKey.toCharArray());
SecretKey sKey2 = skFactory.generateSecret(key);

При попытке расшифровать текст я получаю сообщение об ошибке:

java.security.InvalidKeyException: Given final block not properly padded

Если я пытаюсь использовать ключ, не сохраняя его в хранилище ключей сразу после его создания, процесс расшифровки работает отлично.

Есть идеи?

1 Ответ

0 голосов
/ 16 июня 2011

Вы храните фактический секретный ключ в вашем хранилище ключей (что является нормальным). Однако вы, похоже, пытаетесь прочитать его как пароль для нового ключа, который вы генерируете позже.

Вместо этого:

String passForTheKey = ks2.getKey(keyAlias, keyPass.toCharArray()).toString();
KeySpec key = new PBEKeySpec(passForTheKey.toCharArray());
SecretKey sKey2 = skFactory.generateSecret(key);

используйте это:

SecretKey sKey2 = (SecretKey) ks2.getKey(keyAlias, keyPassword.toCharArray());

То, что вы читаете из хранилища ключей, это сам ключ (как вы его сохранили), а не какой-то пароль. (generateSecret просто сгенерирует новый ключ.)

...