Mémoires — лучший способ вести дневник на Маке

Вспомнил, что до твиттера люди постили ссылки в блоги порциями по несколько штук. Вот, пожалуйста.

Программирование:

*) Как сказали на HN, “I sometimes wonder whether Russ Cox is actually human or is in fact a collective pen name for a group of very talented hackers”. См. количество коммитов в Go, например.

Исторического интереса ссылки:

Go — хороший язык программирования. Сегодня вышла его первая стабильная версия.

Если вы еще не пробовали на нем что-нибудь написать, сейчас самое время. Можете начать с тура по Go.

Гофер и Усяка
Усяка и Гофер (by Alexandra Zakharova, Creative Commons BY-NC-SA 3.0)

Тем, кто будет программировать на нем для веба, возможно, пригодятся мои пакеты:

  • captcha - визуальная и аудио капча. Очень весело было писать этот пакет, особенно код для генерации звука. На трех языках говорит: на английском, русском и китайском. На картинке показывает цифры.
  • authcookie - создание и верификация подписанных куки. Для случаев, когда надо держать пользователей залогиненными.
  • passwordreset - имплементация функции “сбросить забытый пароль”. Генерирует токены, которые надо отослать пользователю, забывшему пароль, чтобы он мог его сбросить.
  • passwordhash - секьюрное “хеширование” паролей на основе PBKDF2.
  • uniuri - правильная генерация рэндомных строк текста, которые подходят для URL. Например, “apHCJBl7L1OmC57n”.
  • blake256 - имплементация хэш-функции BLAKE-256. BLAKE — кандидат в SHA-3, и я надеюсь, он победит. Но пока не победил, лучше не использовать для серьезных вещей.
  • stemmer - cтеммер английских слов на основе алгоритма Porter2. Нормализует слова так, чтобы их можно было найти вне зависимости от окончаний и прочих преобразований. Например, и “delicious”, и “deliciously”, пропущенные через него, дают “delici”.

Я писал в апреле 2010:

Пока для программ на Mac (платформа, на которую я так радостно перешел с Windows) никаких ограничений нет. Но это только пока. С Mac OS X 10.5 приложения можно подписывать сертификатом (как в Windows). Конечно, это служит многим полезным security целям, но появляется еще одна возможность -- выборочный запрет исполнения программ. Что если через несколько лет Mac OS X вообще не будет исполнять неподписанные приложения, как iPhone OS?

Потом были расширения для Сафари.

Сегодня Грубер анонсировал следующую версию Mac OS X:

Users have three choices which type of apps can run on Mountain Lion:

  1. Only those from the App Store
  2. Only those from the App Store or which are signed by a developer ID
  3. Any app, whether signed or unsigned

The default for this setting is, I say, exactly right: the one in the middle, disallowing only unsigned apps.

(выделение мое)

Следующие шаги Apple угадать не сложно.

Постоянные читатели помнят про мои отношения с Fossil. Fossil -- это распределенная система контроля версий со встроенным багтрекером, вики, и просмотрщиком документации; по сути, Git + GitHub в одном исполняемом файле размером примерно в полтора мегабайта, только лучше, потому что тикеты и вики, как и код, распределенные, а не сидящие на одном сервере, а веб-интерфейс доступен даже в офлайне. Fossil написал Ричард Хипп, автор SQLite.

Я часто пользуюсь почти всеми известными DVCS (например, Git для моих пакетов Go потому что goinstall его поддерживает, Mercurial для нескольких проектов и работы над Go), и мои персональные проекты постоянно мигрируют с одной DVCS на другую, но только Fossil мне как родной. Им реально просто и удобно пользоваться, и я на 100% уверен, что информация, лежащая в репозитории не повреждена (привет, Mercurial!).

Конечно, и у Fossil были и есть недостатки. Но на то он и опенсорсный проект (с BSD лицензией, кстати, а не GPL, как почти все остальные), чтобы мы могли их устранять ;-). Пару лет назад, например, я добавил поддержку SSL/TLS.

Я как-то жаловался здесь, что Fossil не поддерживает симлинки. Они важны для некоторых моих мак-проектов -- я храню в репозитории скомпилированные фреймворки (зачем -- отдельный вопрос), а фреймворк в Mac OS X -- это директория, в которой есть несколько ссылок. Пожаловался, и забыл. А потом, когда в начале этого года вернулся к Fossil после путешествий по другим DVCS, все-таки начал работать над поддержкой симлинков. Сделал перерыв на весну и лето, и недавно закончил -- бранч смёрджили в транк (привет русскому языку) и сегодня вышла версия 1.20, в которой симлинки есть (включаются опцией "allow-symlinks").

Вторым пунктом моей жалобы была производительность коммитов и добавления файлов. С тех пор в Fossil заменили код SHA-1 на более скоростной, я улучшил время добавления кучи файлов на ~30% простым патчем. Тем не менее, производительность все равно хуже, чем у идеала -- Git -- но, большое НО, это из-за специальных параноидальных проверок (которые можно отключить, но лучше не надо). Они описаны в этом документе, но я кратко расскажу тут. Во-первых, Fossil кроме высчитывания SHA-1 отдельных файлов еще считает MD5 всех файлов в коммите, а так же самого манифеста коммита (списка файлов с SHA-1 хэшами и разными свойствами, типа тэгов и бранчей). Во-вторых, после дельта-кодирования артефактов, перед тем, как сделать COMMIT транзакции в репозиторий (да, коммиты в Fossil атомарные), Fossil пробует обратно восстановить артефакты и посчитать их контрольную сумму; если получилось, коммит удался. Естественно, все эти действия, хоть и очень быстры, приводят к тому, что производительность коммита -- чуть медленней, чем у Git или Mercurial, которые не делают таких проверок. (Чтобы вы не пугались, я говорю о разнице в полсекунды, а не десятки секунд.) Но именно из-за этих проверок, я могу быть уверен, что история проекта -- именно такая, какая есть, нигде ничего не испорчено.

Еще из хороших фич в версии 1.20: side-by-side diffs (пример) и всякие улучшения security. Полный changelog тут.

В общем, качайте Fossil 1.20. Никаких сложных установок -- всего один исполняемый файл. На сервер тоже устанавливать проще, чем другие VCS, поддерживается даже обычный shared hosting с CGI.

Кстати, почти все опенсорсные проекты на http://www.codingrobots.org теперь хостятся именно Fossil-ом (каждый сайт проекта и есть репозиторий). Мак-юзерам пригодится QLFossil для удобного просмотра репозиториев в Finder.

Допустим, вы живете в каменном веке и изобрели шифр с 8-битным ключом, то есть, всего имеется 28 = 256 комбинаций. Назвали вы его SAES (Stone Age Encryption Standard). Шифр работал отлично, но прогресс не стоит на месте: у людей отросло больше пальцев на руках, они научились быстрее считать, и ваш 8-битный шифр стал не таким надежным, как раньше, потому что подобрать комбинацию из 256 вариантов стало просто. Вы решаете, что нужно сделать 16-битный шифр (216 = 65536 вариантов ключа). SAES себя хорошо зарекомендовал во всех остальных качествах, кроме размера ключа. Почему бы не взять его за основу и просто увеличить размер ключа с 8-ми до 16-ти бит?

Как это сделать? -- думаете вы. Что если взять и зашифровать текст сначала одним 8-битным ключом, например, "A", а потом полученный зашифрованный текст зашифровать еще одним (возможно, другим) 8-битным ключом, например "B"?

  1. ШИФРОВАТЬ("Dear Bob", "A") = "Ynfxr4hf"
  2. ШИФРОВАТЬ("Ynfxr4hf", "B") = "1m6Bp0nh"

Или вот так можно изобразить: EncryptK2(EncryptK1(текст)).

В итоге получится, что шифр у нас один и тот же, но две операции шифрования с 8-битным ключом расширяют размер ключа до 16-ти бит. Да? Назовем его 2SAES.

Как только вы подумали об этом, начался ураган, гром и молния, яркая вспышка и перед вами появились Диффи с Хеллманом, которые изобрели машину времени и путешествуют по всяким векам, предостерегая народ в прошлом от ошибок в криптографии и спрашивая у народа в будущем, как обстоят дела с дискретными логарифмами.

Хеллман и Диффи с машиной времени

"Чувак," -- говорят они, -- "мы в 1977 году занимались такой же фигней как ты и придумали атаку "встреча посередине" (meet-in-the-middle). Для нахождения ключей для твоего шифра понадобится не 216 операций, а 29 операций плюс 28 памяти. Нужно сначала зашифровать известный текст всеми возможными 8-битными ключами и сохранить результат, а потом пробовать расшифровывать шифротекст, опять же, 8-битными ключами. Если текст, который мы расшифровали совпадет с одним из тех, что мы зашифровали и сохранили ранее, то мы получим все два ключа."

И начали выдалбливать на большом камне код на Си, чтобы продемонстрировать атаку. (Стоит отметить, что код вы прекрасно понимали, потому что Си был изобретен как раз где-то в каменном веке.)

#include <err.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <openssl/blowfish.h>
#include <openssl/lhash.h>

Это инклюды, которые нам понадобятся. Давай сделаем пару функций для шифрования:

/* Encryption and decryption */

void
cipher(int what, uint8_t *dst, uint8_t *src, uint8_t key)
{
    BF_KEY bk;

    BF_set_key(&bk, 1, &key);
    BF_ecb_encrypt(src, dst, &bk, what);
}

Для примера будем использовать Blowfish с 8-битным ключом, потому что твой SAES в libcrypto еще не добавили. Аргумент what может быть BF_ENCRYPT для шифрования и BF_DECRYPT для расшифровки. Эта функция может шифровать текст длинной только 1 байт.

Теперь выдолбим аналог 2SAES. Для демонстрации атак нам нужно только шифрование:

void
double_encrypt(uint8_t *dst, uint8_t *src, uint8_t key[2])
{
    cipher(BF_ENCRYPT, dst, src, key[0]);
    cipher(BF_ENCRYPT, dst, dst, key[1]);
}

То есть, берем 16-битный (2-байтный) ключ, шифруем текст первыми восемью битами, а результат шифруем вторыми восемью битами.

Приступим к атакам. Это нам пригодится:

/* Attacks */

const char report[]   = "Key: \"%c%c\"\tOperations: %d\n";
const char notfound[] = "No keys founds in %d operations\n";

Итак, брутфорс, простой перебор ключей:

/*
 * Bruteforce attack 
 */

void
bruteforce(uint8_t *plaintext, uint8_t *ciphertext)
{
    uint8_t buf1[8], buf2[8];
    int i, j, op = 0;

    for (i = 0; i < 256; i++) {
        cipher(BF_DECRYPT, buf1, ciphertext, i);
        for (j = 0; j < 256; j++) {
            ++op;
            cipher(BF_DECRYPT, buf2, buf1, j);
            if (memcmp(buf2, plaintext, 8) == 0) {
                printf(report, j, i, op);
                return;
            }
        }
    }
    printf(notfound, op);
}

Нам известны текст и шифротекст (например, мы знаем, что Алиса всегда начинает свои письма с фразы "Hello Bob"). Тупо подбираем первый и второй ключи, расшифровывая текст комбинациями и сравнивая его с оригинальным текстом. Если текст совпал, значит мы нашли ключи. Нам понадобится в худшем случае 65536 вариантов, чтобы найти правильные ключи.

А смотри как делается наша meet-in-the-middle атака. Нам нужно где-то хранить шифротексты -- известный текст, зашифрованный всеми возможными 8-битными ключами. Типа:

  • Ynfxr4hf => A
  • dfRYO1Hi => B
  • ...

и так со всеми 256 ключами.

Давай-ка возьмем OpenSSL-евскую хэш-таблицу, в которую запихаем 28 шифротекстов с соответствующими ключами.

/* 
 * Meet-in-the-middle attack 
 */

/* Hash table of encrypted texts mapped to all possible keys */
typedef struct {
    uint8_t enc[8]; /* encrypted text, hash table key */
    uint8_t key;    /* 8-bit encryption key */
} EK;

/* EK_hash works reliably only if long is 64 bits */
unsigned long EK_hash(const EK *v) { return *(unsigned long *)v->enc; }
static IMPLEMENT_LHASH_HASH_FN(EK_hash, const EK*);

int EK_cmp(const EK *v1, const EK *v2) { return memcmp(v1->enc, v2->enc, 8); }
static IMPLEMENT_LHASH_COMP_FN(EK_cmp, const EK*);

Ключом хэш-таблицы будет шифротекст, а значением -- 8-битный ключ шифрования, чтобы мы могли примерно так спрашивать нашу таблицу: "таблица-таблица, повернись ко мне передом, а к лесу задом, и скажи мне: если у меня есть шифротекст "бла-бла", то каким ключом это было зашифровано?"

Но для начала таблицу надо заполнить, для чего выдолбим такую функцию:

void
encrypt_all_keys(LHASH *h, EK items[], uint8_t *plaintext)
{
    int i;

    for (i = 0; i < 256; i++) {
        items[i].key = i;
        cipher(BF_ENCRYPT, items[i].enc, plaintext, i);
        lh_insert(h, &items[i]);
    }
}

Эта функция будет шифровать заданный текст всеми ключами от 0 до 255 поочередно, поворачивать таблицу к нам передом, а к лесу задом, и запихивать в нее получившиеся шифротексты и соответствующие им ключи.

Приступим непосредственно к атаке:

void
meetinthemiddle(uint8_t *plaintext, uint8_t *ciphertext)
{
    EK items[256], lookup, *found;
    LHASH *h;
    int i;

    if ((h = lh_new(LHASH_HASH_FN(EK_hash),
                    LHASH_COMP_FN(EK_cmp))) == NULL) {
        warn("hash table");
        return;
    }
    encrypt_all_keys(h, items, plaintext);

    for (i = 0; i < 256; i++) {
        cipher(BF_DECRYPT, lookup.enc, ciphertext, i);
        if ((found = lh_retrieve(h, &lookup)) != NULL) {
            printf(report, found->key, i, i+256);
            goto done;
        }
    }
    printf(notfound, i+256);
done:
    lh_free(h);
}

В этой функции мы создаем таблицу и заполняем ее, как описано выше на камне. После чего начинаем полу-брутфорсить: расшифровывать шифротекст всеми ключами от 0 до 255 и спрашивать таблицу, есть ли в ней соответствующий шифротекст с ключом. Если есть -- та-да-м! -- встретились посередине и нашли оба ключа.

(В отчете к i добавляется 256, потому что мы хотим посчитать количество операций, а при заполнении хэш-таблицы мы как раз сделали 256 операций.)

Чтобы проверить, как все это работает, давай выдолбим макрос, который будет измерять, сколько времени затрачивают атаки:

#define MEASURE(x) do {                                          \
    printf("%s\n", #x);                                          \
    clock_t t = clock(); (x);                                    \
    printf("%.3f sec\n\n", (clock()-t)/(double)CLOCKS_PER_SEC);  \
} while (0)

и main, в которой сначала запустим брутфорс, а потом meet-in-the-middle:

int
main()
{
    uint8_t plaintext[8] = "Dear Bob";
    uint8_t key[2] = "Go";
    uint8_t ciphertext[8];

    double_encrypt(ciphertext, plaintext, key);

    MEASURE( bruteforce(plaintext, ciphertext)      );
    MEASURE( meetinthemiddle(plaintext, ciphertext) );

    return 0;
}

Программа шифрует текст "Dear Bob" 16-битным ключом "Go" и запускает атаки, выводя найденный ключ.

Попробуем? Назовем камень, на котором мы выдалбливали код "meet.c", откомпилируем,

$ cc -lcrypto -o meet meet.c

и запустим:

$ ./meet

bruteforce(plaintext, ciphertext)
Key: "Go"       Operations: 28488
1.361 sec

meetinthemiddle(plaintext, ciphertext)
Key: "Go"       Operations: 367
0.018 sec

Йай! Брутфорс занял 1.4 секунды и 28488 операций, а наша крутая атака всего 0.018 секунды и 367 операций (и примерно 256*(8+8) = 4096 байт памяти)!

На этом Диффи с Хеллманом завели Делореан и улетели в будущее узнавать, как там поживают квантовые компьютеры, а в наше время археологи раскопали камень с выбитым кодом и выложили его на гитхаб:

Заодно перевели на современный язык:

Для алгоритмов шифрования с нормальным размером ключа такая атака, конечно, не очень практична. Например, чтобы сломать двойной Blowfish, как выше, но, скажем, с двумя 64-битными ключами, нужно 265 операций и 2 эксабайта памяти. Где столько найти-то? (Да и вообще, что за экса такая?) Но знать о такой штуке полезно. Например, 3DES, который делает EncryptK3(DecryptK2(EncryptK1(текст))), хоть и позволяет шифровать с тройным ключом (56*3 = 168 бит), но из-за meet-in-the-middle секьюрность у него 168-56 = 112 бит.

C'est la vie.

Коллаж сделан из фоток с википедии: 1 2 3.

Уважаемая ФСБ,

Microsoft сначала обещала передать вам алгоритмы шифрования, используемые в Skype, а потом опровергла это. Как же так?

Преисполненный чувством патриотизма и любовью к Родине, я не могу не помочь вам. Под прикрытием файрволла, находясь вдали от Родины, я провел опасную операцию по заходу на англоязычную Википедию и достал засекреченную информацию об алгоритмах шифрования во вражеской программе.

Вот они:


С уважением,
Агент 000

P.S. Все, теперь можно расшифровывать все разговоры! Да? ДА???? ДАААА????

Сделал QuickLook плагин для Mac OS X для просмотра картинок в формате WebP и генерации иконок для них.

Скриншот WebP QuickLook в действии. Если вы не видите скриншота, значит а) вы не можете видеть б) ваш браузер не поддерживает WebP.

Скачать и положить в ~/Library/QuickLook (возможно, потребуется перезагрузка, чтобы он заработал).

Исходники

President1

President2

President3

President4

President5

Такое на первое апреля специально не придумаешь. Но раз обещал опубликовать в Comic Sans, публикую: вот полное письмо (сам не читал, многабукв).

Недавно некоторые писатели поставили на паузу любимый сериал, скаченный с торрентов, открыли пиратский Word, и настрочили "Открытое письмо русских и русскоязычных писателей Президенту России Д.А. Медведеву". Коротко, в изложении Экслера, который справедливо назвал их идиотами, в письме написано примерно следующее:

Дядь Дмитрий Натольич! Очень кушать хоцца! Закрой, пожалуйста, все электронные библиотеки, расстреляй тех, кто их содержит, и после этого наступит ЩАСТЕ: все те уроды, которые непонятно за каким бесом скачивают наши книжки в Инете, тут же побегут в магазин и тут же скупят все наши мизерные тиражи. И мы тут же станем богатыми и напишем еще лучше и еще больше про нашу любимую родину.

Проблема в том, что у этих писателей какое-то свое интересное отношение к копирайту (впрочем, как и у многих других правообладателей): им нельзя, а нам можно. Я просто не мог поверить, что эти люди никогда не качали книжки, музыку, фильмы или программы из сети (то, что они называют "пиратством"), никогда не выкладывали в свои чудесные жэжэ чужие картинки или фотографии, и решил проверить, применяют ли они к себе те же стандарты, каких требуют от читателей. Я думаю, пяти лицемерных писателей, которые подписали открытое письмо президенту, достаточно.

Товарищ Трубников Александр, г. Киев. "Вече", "Астрель-СПб, "Эксмо", monfore.

Отсканировал и выложил на рапидшару книжку "Рубящее и колющее оружие Европы". Написал в конце:

Естественно, исключительно в ознакомительных целях. Оценив книгу, Вы должны немедленно стереть этот файл, и приобрести издание в ближайшем букинистическом магазине.

Сашенька, такая надпись не оправдывает твои действия и, по твоему же собственному определению, делает тебя "пиратом", с которыми ты борешься.

(Добавлено 2011-03-27: Саша почуствовал вину, убрал ссылку и написал ругательство. А у меня скриншот-то остался.)

Гражданка Катя Сергеева, писатель, сотрудничает с издательством АСТ, kat-s.

Прямо признается, что качает торренты, и у нее даже есть уважительная причина:

Я качаю фильмы и сериалы. И если бы власти Москвы и других городов следили бы за качеством продукта в магазинах, мне бы не преходилось этого делать. Но увы, поднадоело покупать фильмы низкого качества, чтобы потом искать на торрентах...

Катенька, а ведь у "пиратов" тоже есть уважительная причина: им, например, может не нравится качество печати твоих книжек. Ох, если бы только власти Москвы и других городов следили за этим!

Гражданка Бош Диана Борисовна, писатель, издательство "Эксмо", diana-bosch.

Дианочка любит гимнастику, а особенно, в исполнении Тони Литтла, и даже знает, где скачать его видеокурс:

PS: Я нашла, где скачать тренировки Тони Литтла в Сети. Если кому надо - кину ссылки в личку.

Но, конечно же, она не пират! Нет, она бы с удовольствием купила кассету:

Но если вам повезет, и вы купите кассету - ну а вдруг!!! - плиз, не забудьте про меня. Напишите мне, где этот магазин, и если не в Москве, то можно ли заказать почтой. Я с удовольствием куплю диск в хорошем качестве.

Твои читатели, Диана, тоже наверное бы купили твою книжку в хорошем качестве. После того, как скачают электронную, конечно.

(Добавлено 2011-03-31: И Дианочке стало стыдно: она отредактировала пост и удалила все комментарии, в которых ее просят ссылку и она пишет "отправила". А скриншот у меня, конечно, остался.)

Гражданка Мария Гинзбург, "Эксмо", "Лениздат", "Геликон Плюс" (фантастический журнал Б. Стругацкого "Полдень, 21 век", morraine_z.

Машеньке муж хочет купить электронную читалку. Зачем? Чтобы денег не тратить на покупку книжек:

А сколько будут суммарно стоить все те книги, которые вы мне нарекомендовали? А закачивать тексты и бесплатно можно, как я понимаю.

Пратчета, Машенька, по вашему стандарту, читать бесплатно можно только в библиотеке — копирайт еще не закончился.

Товарищ Корнев Павел Николаевич, писатель (сотрудничает с изд-вом "Альфа-книга"), paul-kornev.

Павлик, кроме выкладывания роликов, права, на которые принадлежат, например MTV, сам открыто призывает своих читателей пользоваться "пиратскими библиотеками":

P.S. Те, кто не ищут лёгких путей, могут зарегистрироваться на неназываемой пиратской библиотеке, принести ей существенную пользу и скачать текст бесплатно.

И правильно, Павлик. Только зачем тогда с ними бороться?

Я не хочу сказать, что все подписавшие открытое письмо писатели, делают такие вещи (там даже есть по крайней мере один, у которого две винды не пиратские). Но все-таки, товарищи писатели! Да, с развитием интернета, авторское право стало каким-то странным, неестественным понятием. Плохо, что люди не получают денежку за свои труды, плохо. Виноваты в этом ли пираты? Неизвестно. Хорошо или плохо, что информация нынче так распространяется? Покажет история. Тема сложная. Но пока, по крайней мере, не надо требовать от людей соблюдения таких стандартов, каких вы сами не придерживаетесь. Не надо лицемерия, ок?

Добавлено 2011-03-29: Прислали по почте:

На группе почитателей Удовиченко во вконтакте [автор открытого письма — ДЧ] выложены две песни Арии. Подозреваю не совсем легально залитые туда. Она администратор группы и ни чего не предпринимает, чтобы их удалить.

Cathodique отправляется в Корзину

Cathodique больше нет. Покупатели программы получат Minitube бесплатно.

Объяснение:

Dear Cathodique customer,

As you might already know, Cathodique (YouTube player for Mac) stopped working due to changes on YouTube side. The first time this happened, we quickly updated the program to make it work. Unfortunately, YouTube doesn't provide H.264 videos via their API, so we had to reverse-engineer changes to their website to get videos, emulating browser behavior. This process required a lot of energy and effort, which we could use to write more useful software instead of rushing to reverse-engineer the website every time there's a change on YouTube.

That's why we stopped developing Cathodique, and will be focusing on other projects. But there's good news too: we arranged a deal with Flavio Tordini, creator of Minitube: he was kind enough to offer every paid Cathodique customer a Minitube license for free.

Basically, Minitube is Cathodique with many more features. Not only you won't be left without standalone YouTube player, you'll get a better player. [... information on how to receive license ...].

You can download the program from Minitube website.

Thank you for being our customer!

Май 2012

Пн Вт Ср Чт Пт Сб Вс
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      

Архив по месяцам

Проектики

Mac diary

Mac journal software

Language Burger Games