Зберігання рядкового секрету у (відкритому) вихідному коді


50

Я закінчив розробляти додаток для Android і маю намір опублікувати його в GPL - я хочу, щоб він був відкритим кодом. Однак природа програми (гри) полягає в тому, що вона задає загадки і відповіді кодується в рядковому ресурсі. Я не можу публікувати відповіді! Мені сказали шукати безпечне зберігання паролів - але я нічого не знайшов.

Чи можна опублікувати мій вихідний код із масивом рядків, прихованим, зашифрованим чи прихованим іншим способом? Може, прочитавши відповіді з Інтернет-бази даних?

Оновлення

Рішення Юваля Філімуса внизу спрацювало. Коли я вперше прочитав це, я все ще не знав, як це зробити. Я знайшов деякі рішення для другого варіанту: зберігання хешованого рішення у джерелі та обчислення хешу щоразу, коли користувач здогадається. Для цього в JavaScript існує бібліотека крипто-js за адресою http://code.google.com/p/crypto-js/ . Для Android використовуйте функцію MessageDigest . Існує програма (на fdroid / github) під назвою HashPass, яка робить це.


11
Цікаво, наскільки це тут; він може бути краще підходить для захисту інформації в будь-якому випадку.
Рафаель

2
@YuvalFilmus Не обманюйте голоси за "гаряче запитання". Але точка взята.
Рафаель

4
Тут відсутня важлива деталь: Ви хочете просто перевірити відповіді користувачів чи хочете також надрукувати правильну відповідь? І чи потрібні вам якісь фузіни, чи є лише чіткий обмежений набір правильних відповідей (що дозволяє вам перевірити відповідь користувача проти цього набору по черзі)?
Гайд

4
Усі відповіді задають питання, яку проблему ви хочете вирішити. Чому ви не можете опублікувати відповіді?
Римоїд

1
Що потрібно, щоб ваш код міг робити з цими рядками? Чи потрібно вміти їх розшифровувати? Або здатне порівняти рядки з ними достатньо?
Девід Шварц

Відповіді:


83

У вас є щонайменше два варіанти, залежно від того, яку проблему ви хочете вирішити.

Якщо ви хочете, щоб невинні читачі вашого коду не отримували відповіді ненавмисно, або ви хоч хочете зробити це трохи складніше, щоб користувачі не спокушалися, ви можете зашифрувати рішення та зберегти ключ як частину коду, можливо результат деяких обчислень (щоб зробити це ще складніше).

Якщо ви хочете перешкодити користувачам отримувати відповідь, ви можете скористатися функцією хешу в односторонньому режимі або в жаргоні комп’ютера . Зберігайте хеш відповіді, і ви можете перевірити правильність відповіді, не виходячи з неї взагалі, не знаходячи її спочатку. Це має той недолік, що важче перевірити відповідь, близьку до правильної відповіді, хоча є деякі рішення навіть для цієї проблеми.


9
Я хотів би додати одне, що якщо вам потрібна ще більша безпека, кожну відповідь, мабуть, слід посолити іншою сіллю. Це дозволяє уникнути нападу словника на всі відповіді відразу. Якщо ви хочете побачити, як це роблять "справжні" криптовалюти, погляньте на систему String-to-Key у OpenPGP .
Псевдонім

1
Зберігання хешів у коді означає, що вся інформація є статичною та сольовою / будь-що інше буде також доступно. Я вважаю, що в результаті було б розумним, якщо простір відповідей буде достатньо великим (наприклад, повний діапазон 32-бітових цілих значень), інакше (тобто у випадку запитань з декількома варіантами) таблиця веселки швидко дасть правильні відповіді.
Олексій Левенков

3
Як зазначає Олексій, якщо ваші можливі входи охоплюють невеликий простір, зберігання відповідей у ​​коді відкриє їх будь-якому визначеному зловмиснику - і я здогадуюсь, що більшість загадок матимуть досить малі простори стану, тому що їх відповіді, як правило, повинні бути або слова, або порівняно невелика кількість. Ви можете хешувати або шифрувати, щоб уникнути невинних помилок, але це не заважає комусь отримати відповідь, хто цього дійсно хоче. (Плюс, вони могли просто запитати когось, хто вже вирішив вашу загадку!)
Кріс Хейз

4
Щоб протистояти тому, що згадує Кріс, ви можете обрати процес хешування, який дуже повільний, скажімо, це займає 100 мс (такий підхід застосовують деякі стандарти ПК). З точки зору користувача це все ще дуже швидко, але перерахування значно ускладнює.
Yuval Filmus

12
@YuvalFilmus Знову ж таки, певною мірою. Якщо ваша загадка закінчується на "Чи злочин був Ян, Джо чи Джейн?" перерахувати це буде дуже просто, навіть якщо ви змусите хеш зайняти повну хвилину. Якщо вся гра не буде написана з цим на увазі, і всі питання є надзвичайно відкритими, це спричинить проблему. Але так, якщо ваші запитання настільки відкриті, що простір штатів достатньо великий, відповіді можна захистити.
Кріс Хейс

28

У вас є два три варіанти:

Відповіді тримайте окремо від решти вихідного коду

Якщо ви хочете, щоб ваш код був відкритим кодом, однак не хочете, щоб відповіді були з відкритим кодом, тоді ви відкриваєте код програми для програми без запитань і відповідей, при цьому питання та відповіді є окремим закритим джерелом "плагін" або файл даних. Ваш додаток для Android об’єднає обоє разом у один додаток.

Відповіді покладіть у свій вихідний код

Крім того, якщо ви вважаєте, що питання та відповіді є основною частиною того, що ви хочете, щоб відкриті джерела ви отримали, тоді ви повинні помістити відповіді у вихідний код, бажано, не заплутаний, щоб інші могли їх читати та змінювати . Обмежування вихідного коду, щоб його неможливо було зрозуміти та змінити, насправді не відповідає принципам відкритого вихідного коду.

Розмістіть відповіді на сервері в Інтернеті

За допомогою обох вищезазначених рішень можливо, хтось, хто завантажив ваш додаток, дізнається відповіді, не відтворюючи вашу програму в будь-якому випадку - незалежно від того, як ви придушуєте / шифруєте свої відповіді, якщо ваша програма може визначити відповідь без додаткової інформації, може людина перевіряє ваш додаток.

Якщо ви дійсно хочете переконатися, що відповіді ніхто не може дізнатися, єдиний реальний варіант - не давати їм відповідей, а додатки викликати веб-службу тощо ... всякий раз, коли вони хочуть дізнатися відповідь. Додаток повинен надсилати відповідь, яку ввійшов користувач, а веб-служба повинна повідомити програмі, чи відповідь є правильною чи ні, таким чином користувач не може сказати, що відповідь, поки не отримає правильну відповідь (короткий веб-служби жорстокого насильства, яку ви можете виявити та захистити від неї).

Якщо ви шукаєте способи придушити свої відповіді, це підказує мені, що ви не хочете, перш за все, відкривати вихідні відповіді, тож варто розглянути перші варіанти.

Якщо вкрай важливо, щоб користувач не зміг знайти відповідь заздалегідь, тоді третій варіант - ваш єдиний реальний вибір, проте я намагаюся придумати сценарій, де для цього варто докласти зусиль, в останню чергу, оскільки це заважає вашим користувачам від використання вашого додатка без підключення до Інтернету.


8
Питання та відповіді навіть не повинні бути плагінами, це може бути простий файл даних. Файли вхідних даних не обов'язково включаються до складу ліцензійного програмного забезпечення та можуть бути охоплені власною окремою ліцензією. Поки ви надаєте (інший) зразок файлу даних для використання з вихідним кодом, ви не перешкоджаєте вільному використанню джерела або програм, зібраних із зазначеного джерела, і, таким чином, не повинні порушувати GPL.
Doktor J

Я не впевнений, що насправді вирішує його проблему - чи відповіді зашифровані та жорстко закодовані в коді чи поширюються як окремий файл, код все ще повинен мати можливість розшифрувати відповіді, тому кожен, хто завантажує його додаток, може робити те, що вихідний код робить, щоб дійти до відповідей. (Якщо вони не хешіруются, як це було запропоновано в іншу відповідь)
Джонні

1
Якщо метою є перевірка відповідей і не вимагає їх відображення, це можна зробити так само, як паролі з одностороннім хешем.
JamesRyan

@ Джустін, дякую за вашу відповідь та ваші коментарі щодо того, чи є це відкритим кодом, цікаві. Я думаю, що приховування відповідей має на меті не приховувати вихідний код або те, як працює програма, а скоріше для збереження цілісності виклику. Як виявляється, криптографія - прекрасний засіб для розповсюдження загадок, не маючи бути там, коли користувач здогадується ("це це, це?")
Ніколи більше

4

Якщо об'єктом є затемнення рядків від випадкового читання вихідного коду, але тримати їх відкритими, щоб інші люди могли легко вносити власні зміни - наприклад, якщо ви публікували джерело в текстовій пригоді та не хотіли, щоб описовий текст з’являвся який би являв собою спойлер, тоді використовуйте щось оборотне, як гниль13.

Насправді, ви можете згнити всі свої файли перекладу і повернути їх на льоту.

Це зберігає відкритий дух. Випадкові "магічні" хеші насправді не сприятливі для програмістів.


4
Пам'ятайте, що багато людей із GeoCaching серед нас читають rot13 майже так само вільно, як оригінал.
йо '

4

Відкритий код вимагає, щоб вихідний код був оприлюднений та доступний, а не дані гри. Таким чином, ви можете легко помістити дані в інший файл, а не публікувати їх. Додайте криптовалюту, якщо ви хочете не допустити випадкового читання файлу. Я сумніваюся, що для вашої програми потрібна сильна криптовалюта.


1
У якому сенсі ви можете "не публікувати" дані гри? У грі має бути доступ до цих даних, щоб кожен, хто має копію гри, мав копію даних. Це майже саме те, що видавництво: оприлюднення.
Девід Річербі

1
@DavidRicherby Залежить від того, що ви хочете опублікувати та закінчити. Та гра чи ваш двигун, які можна було б використовувати для створення багатьох подібних ігор? Дозволити людям маніпулювати вашою грою, перевіряти код на наявність отворів у безпеці чи просто повторно використовувати компоненти? Якщо ваш інтерфейс настільки простий, як "CSV з q & a + program = гра", я думаю, що можна публікувати лише програму, а не CSV.
Рафаель

1
@Raphael Але розповсюдження гри, яка складається з виконуваного файлу та простого текстового файлу даних, не дозволяє досягти мети зробити секретні відповіді. Якщо ви хочете запропонувати зашифровану версію файлу даних, це добре, доки всі розуміють, що це лише безпека через невідомість (ключ знаходиться в джерелі). Але потім ми потрапляємо у питання, чи непростий текст файлу даних є вихідним кодом у значенні GPL, і в цей момент питання стає питанням інтерпретації GPL, а не інформатикою.
Девід Річербі

@DavidRicherby: Погоджено. Але, хоча IANAL, я дуже сумніваюся, що файл даних, що складається із загадок та їх відповідей, вважатиметься настільки важливою та незамінною частиною програми, що вона не може бути ліцензована окремо - особливо якщо ви включили незашифрований файл зразків даних у розподіл джерела, а також інструкції щодо його зміни та шифрування за потреби, щоб зрозуміти, що кожен, хто має вихідний код, дійсно може створити власні спеціалізовані файли даних та використовувати їх разом із програмою.
Ільмарі Каронен

4

Чому б ви зберігали свої відповіді у вихідному коді GPL, якщо ви не хочете, щоб ваші користувачі знали їх? Навіть якщо вони зараз невідомі або легко скрутні, вони можуть (і, швидше за все, будуть) у майбутньому.

Замість того, щоб зберігати їх у вашому додатку, використовуйте зовнішню базу даних. Створіть невеликий веб-сервіс, який порівнює відповіді з тим, що є у вашій базі даних. Тоді дозвольте вашій програмі зателефонувати в цю веб-службу, коли її потрібно підтвердити. Основна проблема полягає в тому, що, оскільки він вимагає доступу до Інтернету, ви втратите деяку швидкість та потенційну базу користувачів. ваша ліцензія на додаток має застосовуватися лише до самого додатка, а не до веб-сервісу.

Ви також можете просто помістити свої відповіді в невелику базу даних і помістити їх у свою програму. Наскільки мені відомо, GPL застосовується лише до вихідного коду, а не до даних, які зберігає ваш додаток. Я, можливо, помиляюся на цьому.


1
"Наскільки я знаю, GPL застосовується лише до вихідного коду, а не до будь-яких даних, які зберігає ваш додаток". Що ж, GPL говорить: "Ви повинні ліцензувати всю роботу в цілому за цією Ліцензією всім, хто має у своєму розпорядженні копію". Тож ви можете подумати, що нам зараз потрібно вирішити, чи дані є частиною "всієї роботи". Насправді, безумовно, всі обмеження GPL (у тому числі й те) стосуються лише ліцензіатів. І ліцензіарам приємно дотримуватися духу GPL, але їм не потрібно турбуватися про відвідування поліції авторських прав.
Пітер Форд

1

Пам'ятайте, що навіть якщо ви зберігаєте базу даних на віддаленому веб-сервері, базу даних все одно можна дублювати, просто записуючи всі правильні пари ключів / значень, які були помічені. І взагалі кажучи, мобільні додатки повинні намагатися не допускати помилок або перестати функціонувати, оскільки мережа працює (використовуйте повідомлення в черзі та "оновлюйте, коли зможете").

Тож якщо ви хочете локальну базу даних, але вам не подобається ідея її кричущо розшифровуватись, ви можете використовувати фільтр розквіту (щоб уникнути розмови з мережею чи великої розшифрованої бази даних локально). Ось як працювали перевірки орфографії, коли простору пам’яті було дуже мало.

Отже, якщо ви додаєте пари запитань / відповідей у ​​фільтр на зразок:

Hash (NormalizeString (Question [n])) + Hash (NormalizeString (Відповідь [n]))

Якщо ви запитаєте, чи є "Капітолій Вірджинії? Річмонд" у наборі, він або відповість "точно ні", або "майже напевно так". Якщо у вас занадто багато помилкових позитивних даних, збільште базу даних.

У вас може бути величезна база даних у крихітному просторі, припускаючи, що користувач буде писати запитання та відповіді саме так, як ви очікуєте. Збереження бази даних мало допомагає в оновленнях, оскільки їх, мабуть, доведеться переносити через бездротові мережі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.