Я готов потратить некоторое время на разработку еще одного менеджера лицензий для настольного 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?