Це перша сторінка, яка відображається через Google, і вразливості безпеки у всіх реалізаціях змушують мене переслідувати, тому я публікую цю інформацію, щоб додати інформацію щодо шифрування для інших, оскільки минуло 7 років від початкової публікації. Я маю ступінь магістра комп’ютерної інженерії і витратив багато часу на вивчення та вивчення криптографії, тому я кидаю два центи, щоб зробити Інтернет безпечнішим місцем.
Також зауважте, що багато можливостей може бути безпечним для даної ситуації, але навіщо їх використовувати та, можливо, випадково помилитися? Використовуйте найсильніші інструменти, які у вас є, якщо у вас немає конкретних причин цього не робити. Загалом, я дуже раджу користуватися бібліотекою та триматися подалі від тонких зернистих деталей, якщо можете.
ОНОВЛЕННЯ 4/5/18: Я переписав деякі частини, щоб зробити їх простішими для розуміння, і змінив рекомендовану бібліотеку з Jasypt на нову бібліотеку Google Tink , я б рекомендував повністю видалити Jasypt з існуючих налаштувань.
Передмова
Я викладу основи безпечної симетричної криптографії нижче та зазначу поширені помилки, які я бачу в Інтернеті, коли люди самостійно реалізовують криптовалюту зі стандартною бібліотекою Java. Якщо ви хочете просто пропустити всі деталі, перейдіть до нової бібліотеки Google, імпортуйте їх у свій проект, і використовуйте режим AES-GCM для всіх своїх шифрувань, і ви будете захищені.
Тепер, якщо ви хочете дізнатися деталі з грізними зернами, як шифрувати в Java, читайте далі :)
Блокувати шифри
Перш за все, потрібно спочатку вибрати симетричний ключ Блок-шифр. Блок-шифр - це функція / програма комп’ютера, що використовується для створення псевдовипадковості. Псевдовипадковість - це підроблена випадковість, що жоден комп'ютер, окрім квантового комп'ютера, не зміг би визначити різницю між ним та реальною випадковістю. Блок-шифр схожий на будівельний блок криптографії, і при використанні в різних режимах чи схемах ми можемо створювати шифрування.
Тепер щодо доступних сьогодні алгоритмів блокових шифрів. Переконайтесь, що НІКОЛИ , повторююсь НІКОЛИ не використовувати DES , я б навіть сказав, що НІКОЛИ не використовуйте 3DES . Єдиний блок-шифр, який навіть випуску NSA Snowden зміг переконатися, чи справді він максимально наближений до псевдо-випадкових - AES 256 . Є також AES 128; різниця полягає в тому, що AES 256 працює в 256-бітних блоках, тоді як AES 128 працює в 128 блоках. Загалом AES 128 вважається безпечним, хоча деякі слабкі місця були виявлені, але 256 є настільки ж надійними.
Веселий факт DES був зламаний АНБ ще тоді, коли він був заснований і фактично зберігав таємницю протягом декількох років. Хоча деякі люди все ще стверджують, що 3DES є безпечним, існує досить багато наукових робіт, які знайшли та проаналізували слабкі місця в 3DES .
Режими шифрування
Шифрування створюється, коли ви берете блок-шифр і використовуєте певну схему, так що випадковість поєднується з ключем для створення чогось оборотного, доки ви знаєте ключ. Це називається режимом шифрування.
Ось приклад режиму шифрування та найпростішого режиму, відомого як ECB, щоб ви могли наочно зрозуміти, що відбувається:
Режими шифрування, які ви побачите найчастіше в Інтернеті, є такими:
CTR ЄС, CBC, GCM
Існують інші режими поза переліченими, і дослідники завжди працюють над новими режимами, щоб поліпшити існуючі проблеми.
Тепер перейдемо до реалізацій і того, що захищено. НІКОЛИ не використовуйте ECB, це погано приховувати повторювані дані, як показав відомий пінгвін Linux .
Під час реалізації в Java зауважте, що якщо ви використовуєте наступний код, режим ECB встановлений за замовчуванням:
Cipher cipher = Cipher.getInstance("AES");
... НЕБЕЗПЕЧНО ЦЕ ВІННОСТІ! і, на жаль, це спостерігається в усьому StackOverflow та в Інтернеті у навчальних посібниках та прикладах.
Нонце і IV
У відповідь на питання, знайдене в режимі ЄЦБ, були створені номенклатури, також відомі як IV. Ідея полягає в тому, що ми створюємо нову випадкову змінну і додаємо її до кожного шифрування, щоб при шифруванні двох однакових повідомлень вони виходили різними. Краса цього полягає в тому, що IV чи ні, це суспільне знання. Це означає, що зловмисник може мати доступ до цього, але поки у них немає вашого ключа, він не може нічого робити з цим знанням.
Поширені проблеми, які я побачу, - це те, що люди встановлять IV як статичне значення, як у тому самому фіксованому значенні у своєму коді. і ось підступ до IV-го моменту, коли ви повторите одне, ви фактично компрометуєте всю безпеку свого шифрування.
Генерація випадкових IV
SecureRandom randomSecureRandom = SecureRandom.getInstance("SHA1PRNG");
byte[] iv = new byte[cipher.getBlockSize()];
randomSecureRandom.nextBytes(iv);
IvParameterSpec ivParams = new IvParameterSpec(iv);
Примітка: SHA1 зламаний, але я не міг знайти, як правильно реалізувати SHA256 в цьому випадку використання, тому якщо хтось захоче зламати тріщину при цьому та оновити, це було б приголомшливо! Також напади SHA1 як і раніше є нетрадиційними, оскільки на величезному скупченні може пройти кілька років. Перегляньте деталі тут.
Впровадження CTR
Для режиму CTR не потрібні прокладки.
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
Впровадження ЦБ
Якщо ви вирішите реалізувати режим CBC, зробіть це з PKCS7Padding наступним чином:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
Уразливість CBC та CTR та чому слід використовувати GCM
Хоча деякі інші режими, такі як CBC та CTR захищені, вони стикаються з проблемою, коли зловмисник може перевернути зашифровані дані, змінюючи його значення при розшифровці. Так, скажімо, ви шифруєте уявне банківське повідомлення "Продай 100", ваше зашифроване повідомлення виглядає таким чином "eu23ng", зловмисник змінює один біт на "eu53ng", і раптом, коли розшифровує ваше повідомлення, воно звучить як "Продай 900".
Щоб уникнути цього більшість Інтернету використовує GCM, і кожного разу, коли ви бачите HTTPS, вони, ймовірно, використовують GCM. GCM підписує зашифроване повідомлення хешем і перевіряє, чи повідомлення не було змінено за допомогою цього підпису.
Я б уникав впровадження GCM через його складність. Вам краще скористатися новою бібліотекою Googles Tink, оскільки тут знову, якщо ви випадково повторите IV, ви компрометуєте ключ у випадку з GCM, що є остаточним недоліком безпеки. Нові дослідники працюють над режимами IV повторного стійкого шифрування, коли навіть якщо ви повторите IV, ключ не загрожує, але це ще має стати основним.
Тепер, якщо ви хочете реалізувати GCM, ось посилання на приємну реалізацію GCM . Однак я не можу забезпечити безпеку або якщо вона належним чином реалізована, але вона знижує основу. Також зауважте, що в GCM немає прокладки.
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
Ключі проти паролів
Ще одна дуже важлива примітка - це те, що якщо мова йде про криптографію, то ключ і пароль - це не одне і те ж. Ключ криптографії повинен мати певну кількість ентропії та випадковості, щоб вважатись безпечною. Ось чому вам потрібно переконатися у використанні належних криптографічних бібліотек для створення ключа для вас.
Отже, у вас дійсно є дві реалізації, які ви можете зробити тут, перше - використовувати код, знайдений у цій потоці StackOverflow для генерації випадкових ключів . Це рішення використовує захищений генератор випадкових чисел для створення ключа з нуля, який ви можете використовувати.
Іншим менш безпечним варіантом є використання, введення користувача, наприклад пароль. Проблему, яку ми обговорювали, полягає в тому, що в паролі недостатньо ентропії, тому нам доведеться використовувати PBKDF2 , алгоритм, який приймає пароль і посилює його. Ось реалізація StackOverflow, яка мені сподобалась . Однак у бібліотеці Google Tink все це вбудовано, і ви повинні цим скористатися.
Android Developers
Одним важливим моментом, на який слід зазначити, є те, що ваш андроїд-код можна реверсувати, і в більшості випадків більшість Java-кодів теж є Це означає, що якщо ви зберігаєте пароль у простому тексті у своєму коді. Хакер може легко отримати його. Зазвичай для цього типу шифрування потрібно використовувати асиметричну криптографію тощо. Це поза межами цієї посади, тому я уникатиму занурення в неї.
Цікаве прочитання з 2013 року : вказує на те, що 88% впроваджень Crypto в Android були виконані неналежно.
Фінальні думки
Ще раз рекомендую уникати прямої використання бібліотеки Java для криптовалюти та використовувати Google Tink , це позбавить вас від головного болю, оскільки вони справді добре виконали всі алгоритми. І навіть тоді переконайтеся, що ви перевіряєте проблеми, що виникають на Github Tink, вразливі місця тут і там.
Якщо у вас є запитання чи відгуки, не соромтесь коментувати! Безпека завжди змінюється, і вам потрібно зробити все можливе, щоб не відставати від неї :)