Генерировать лицензионный ключ разумной длины с асимметричным шифрованием?
Я смотрел на это весь день. Я, вероятно, должен был уйти от этого несколько часов назад; Я мог бы упустить что-то очевидное в этой точке.
Короткая версия: есть ли способ генерировать и сваривать асимметрично зашифрованный хеш с разумным количеством однозначных, читаемых человеком символов?
Длинная версия:
Я хочу создать лицензионные ключи для моего программного обеспечения. Я хотел бы, чтобы эти ключи были разумной длины (25–36 символов) и легко читались и вводились человеком (поэтому избегайте неоднозначных символов, таких как число 0 и заглавная буква O).
Наконец, - и это, кажется, самое главное - я действительно хотел бы использовать асимметричное шифрование, чтобы затруднить генерацию новых ключей.
У меня есть общий подход: объединить мою информацию (имя пользователя, версию продукта, соль) в строку и сгенерировать из нее хеш SHA1(), а затем зашифровать хеш своим личным ключом. На клиенте создайте хеш SHA1() из той же информации, затем расшифруйте лицензию с помощью открытого ключа и посмотрите, есть ли совпадение.
Поскольку это приложение для Mac, я посмотрел на AquaticPrime, но он генерирует относительно большой файл лицензии, а не строку. Я могу работать с этим, если нужно, но как пользователь мне очень нравится удобство лицензионного ключа, который я могу читать и распечатывать.
Я также посмотрел на CocoaFob, который генерирует ключ, но он настолько длинный, что я все равно хотел бы доставить его в виде файла.
Некоторое время я дурачился с OpenSSL, но не смог придумать ничего разумного.
Итак... я что-то упускаю здесь очевидное? Есть ли способ сгенерировать и свести асимметрично зашифрованный хеш к разумному количеству однозначных, читаемых человеком символов?
Я открыт для покупки решения. Но я работаю на разных платформах, поэтому хочу что-то портативное. Все, на что я смотрел до сих пор, зависело от платформы.
Большое, большое спасибо за решение!
PS - Да, я знаю, что он все еще будет взломан. Я пытаюсь придумать что-то разумное, что, как пользователь, я все равно нахожу дружелюбным.
5 ответов
К сожалению нет. Если вы сделаете его короче, вы потеряете информацию и не сможете восстановить исходный хеш.
Тем не менее, вот пара вещей, которые вы можете попробовать:
- Используйте base32. Сопоставьте его со всеми доступными буквами алфавита, которые не являются двусмысленными. (0vsO и т. Д.)
- Используйте DSA, он более компактен, чем RSA.
- Сокращение вашего ввода (например, усечение хэша sha1 или использование вместо него md5) может также сделать вывод короче.
Обращайтесь с каждым символом SHA1 как с шестнадцатеричным, возможно, отбрасывайте ненужное форматирование (тире или скобки), используйте некоторое сопоставление массива для преобразования 0-9A-F, как, скажем, AP, в некоторый случайный порядок, используйте его как введенный вами "человеческий" текст. MD5 даст вам 32 символа или еще несколько для SHA1. Распакуйте символы обратно в строку / байты SHA1/MD5 и продолжайте оттуда.
Лучшим методом, основанным на сигнатурах, для создания коротких лицензионных ключей в настоящее время, по-видимому, является схема подписи Бонэ-Линн-Шахама, хотя она довольно недавняя (не так много обзоров) и не реализована в обычных инструментах шифрования.
Вот способ сделать это с помощью общих openssl и bash:
openssl ecparam -genkey -name sect113r1 -out private.key # generate the private key (store it on your server)
openssl ec hist-in private.key -pubout -out public.key # generate a public key (store it in the client software)
# generate a random one time activation userID or a hardware-based one here (CLIENT SIDE)
user_id="unique_on_the_fly_generated_user_ID" # send the user ID to the server for license generation
signature=""
return_value=0
while [[ $return_value == 0 ]]
do
signature=$(echo "$user_id" | openssl dgst -sign private.key | base64 > signature.txt) # generate a user licence
echo "$signature" | egrep -q 'O|l|/|\+|=' # check for ambiguous chars
return_value=$?
done
echo "$signature" | base64 -d > signature.txt # send the signature/license to the client
openssl dgst -verify public.key -signature signature.txt # verify signature (CLIENT SIDE)
Обратите внимание, что вы по-прежнему получаете подпись / лицензионный ключ длиной 48 символов (плюс общий символ "M" заголовка, который вы можете избежать отправки). Насколько я знаю, вы не можете генерировать более короткие подписи с openssl в данный момент.
Я не буду отвечать по части шифрования, но то, что я начал делать при регистрации интерфейсов, это проверка буфера обмена на наличие текста при поднятии интерфейса. Если в буфере обмена присутствует текст, отсканируйте его, чтобы узнать, скопировал ли пользователь откуда-либо свои регистрационные данные (электронная почта, веб-страница и т. Д.), И если вы найдете информацию, которая может быть вашей регистрационной информацией / ключами, предварительно заполните регистрацию. интерфейс с ним.
Также неплохо показать небольшое предупреждение на интерфейсе, указывающее, что информация была успешно удалена из буфера обмена (или нет!), Чтобы пользователь знал, что произошло или не произошло.
Я бы рассмотрел алгоритм MD5. Он широко реализован и будет генерировать 32-символьную буквенно-цифровую строку независимо от размера ввода. Примените алгоритм к вашему хешу SHA1, и это может быть то, что вы ищете.