Почему Java KeyStore не удается загрузить ключ OpenPGP?
Я готов потратить некоторое время на разработку еще одного менеджера лицензий для настольных Java-приложений. После осмотра я обнаружил, что JCPUID от Iakin бесплатен и должен работать на большинстве операционных систем с родными библиотеками, которые я нашел здесь.
Моя идея состоит в том, чтобы сделать два модуля: основное приложение, которое покажет всплывающее окно с идентификатором ЦП и текстовым полем проверки, а также приложение генератора ключей. Пользователь передает идентификатор процессора владельцу кейгена, который возвращает код проверки (сгенерированный с кейгеном) пользователю. После того, как пользователь отправит правильный код подтверждения, файл лицензии с этим кодом будет создан в файловой системе. Каждый раз, когда приложение запускается, оно проверяет наличие и правильность этого файла и после этого загружает основной экран приложения.
Что касается проверки кода, я думаю, что лучшим вариантом будет использование асимметричной криптографии, в частности RSA. Открытый ключ будет встроен в приложение, а секретный - в генератор ключей. Таким образом, CPUID будет передан владельцу генератора ключей и затем подписан с RSA. Эта подпись будет передана обратно пользователю, который проверит ее действительность с помощью встроенного открытого ключа.
Я сгенерировал пары ключей gpg, используя сам инструмент командной строки Kleopatra и gpg Linux. Затем я попытался что-то подписать, используя этот метод:
private byte[] createSignature(byte[] file) {
byte[] signature = null;
try {
java.security.KeyStore keyStoreFile = java.security.KeyStore
.getInstance("PKCS12");
keyStoreFile.load(getClass().getClassLoader().getResourceAsStream("/secret.asc"),
"******".toCharArray());
PrivateKey privateKey = (PrivateKey) keyStoreFile.getKey(
"My Name Here", "******".toCharArray());
Signature dsa = Signature.getInstance("SHA1withRSA");
dsa.initSign(privateKey);
dsa.update(file, 0, file.length);
signature = dsa.sign();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return signature;
}
Но privateKey
инициализация выдает исключение:
java.security.InvalidKeyException: Key must not be null
Я думаю, это из-за неправильного формата экземпляра здесь:
java.security.KeyStore keyStoreFile = java.security.KeyStore
.getInstance("PKCS12");
Я бы хотел знать:
Насколько хорош этот подход вообще?
Какая разница существует между различными форматами ключей OpenPGP и какие из них лучше всего использовать в этом случае? Как узнать формат существующего файла OpenPGP?
1 ответ
Крипто-инфраструктура Java не поддерживает OpenPGP. Ключи X.509, например, в формате PKCS12, несовместимы с OpenPGP - хотя они основаны (в основном) на одних и тех же криптографических алгоритмах.
Либо используйте сертификаты X.509 (вы также можете создать собственный CA для этой цели), либо полагаться на реализацию OpenPGP для Java. Что касается библиотек с открытым исходным кодом, вы можете выбирать между собственной реализацией Java BouncyCastle (лицензия MIT) или интерфейсом GnuPG (GPL) через привязку Java GPGME (LGPL).
BouncyCastle, вероятно, является лучшим способом, так как все, что вам нужно сделать, это добавить еще одну библиотеку Java, а не устанавливать другое программное обеспечение в систему.