Что означают возвращаемые значения проверки подписи PHP gnupg?


Я хочу проверить подписанный текст pgp на PHP. Следуя документации PHP и ответу на на этот вопрос, я создал простой скрипт для тестирования библиотеки gnupg. Я отправил подписанное электронное письмо между двумя учетными записями электронной почты с помощью Thunderbird с помощью Enigmail - получение Thunderbird показывает, что подпись верна.

В PHP, когда я использую обычный текст электронной почты и открытый ключ отправителя, функция verify() возвращает массив следующим образом:

array(1) {
  [0]=>
  array(5) {
    ["fingerprint"]=>
    string(40) "468F82339FC55DE5CAFD71BB63DD32AE1308A57F"
    ["validity"]=>
    int(0)
    ["timestamp"]=>
    int(1443033896)
    ["status"]=>
    int(0)
    ["summary"]=>
    int(0)
  }
}

Когда я изменяю в подписанном сообщении одно слово, результат меняется кому:

array(1) {
  [0]=>
  array(5) {
    ["fingerprint"]=>
    string(16) "63DD32AE1308A57F"
    ["validity"]=>
    int(0)
    ["timestamp"]=>
    int(0)
    ["status"]=>
    int(117440520)
    ["summary"]=>
    int(4)
  }
}

И, наконец, когда я изменяю много текста или нарушаю подпись, функция возвращает false.

Итак, что означают эти значения массива?

  • Почему validity всегда 0?
  • timestamp значение - это временная метка чего? Время, когда было подписано сообщение?
  • Почему status значение так велико во втором случае? Это просто случайное значение или конкретный код ошибки?
  • То же самое с summary для чего используется значение 4?

Если я хочу просто просто признать если текст подписан правильно или нет, могу ли я просто сравнить возвращенный fingerprint с отпечатком открытого ключа и проверить, равны ли статус и сводка 0?

Author: Community, 2015-09-25

1 answers

В документации GnuPG PHP действительно отсутствует информация. Взглянув на исходный код, руководство и источники GPGME, вы можете получить соответствующую информацию.

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

Действительность

Почему действительность всегда равна 0?

Для проверки validity подпись, вам нужно назначить доверие (чтобы GnuPG мог вычислять цепочку доверия). Действительность определяется в следующих перечислениях GPGME:

/* The available validities for a trust item or key.  */
typedef enum
  {
    GPGME_VALIDITY_UNKNOWN   = 0,
    GPGME_VALIDITY_UNDEFINED = 1,
    GPGME_VALIDITY_NEVER     = 2,
    GPGME_VALIDITY_MARGINAL  = 3,
    GPGME_VALIDITY_FULL      = 4,
    GPGME_VALIDITY_ULTIMATE  = 5
  }
gpgme_validity_t;

Метка времени

Значение временной метки - это временная метка чего? Время, когда было подписано сообщение?

Да, это просто, это отметка времени создания подписи. Имейте в виду, что отметка времени обычно определяется подписывающим лицом и может быть подделана на произвольные даты.

Статус

То же самое с резюме что означает значение 4?

Чтение документации (gpgme_error_t status), похоже, статус определен в gpg-error.h. Это очень длинный список, размещенный в репозитории git GnuPG.

Тем не менее, определенный статус в вашем вопросе не имеет для меня смысла.

Краткое описание

Почему значение статуса так велико во втором случае? Это просто случайное значение или конкретный код ошибки?

Это краткое описание подписи. Опять же, сводка определяется в перечислении GPGME:

/* Flags used for the SUMMARY field in a gpgme_signature_t.  */
typedef enum
  {
    GPGME_SIGSUM_VALID       = 0x0001,  /* The signature is fully valid.  */
    GPGME_SIGSUM_GREEN       = 0x0002,  /* The signature is good.  */
    GPGME_SIGSUM_RED         = 0x0004,  /* The signature is bad.  */
    GPGME_SIGSUM_KEY_REVOKED = 0x0010,  /* One key has been revoked.  */
    GPGME_SIGSUM_KEY_EXPIRED = 0x0020,  /* One key has expired.  */
    GPGME_SIGSUM_SIG_EXPIRED = 0x0040,  /* The signature has expired.  */
    GPGME_SIGSUM_KEY_MISSING = 0x0080,  /* Can't verify: key missing.  */
    GPGME_SIGSUM_CRL_MISSING = 0x0100,  /* CRL not available.  */
    GPGME_SIGSUM_CRL_TOO_OLD = 0x0200,  /* Available CRL is too old.  */
    GPGME_SIGSUM_BAD_POLICY  = 0x0400,  /* A policy was not met.  */
    GPGME_SIGSUM_SYS_ERROR   = 0x0800   /* A system error occured.  */
  }
gpgme_sigsum_t;

Таким образом, вы должны прочитать результат в виде двоичных флагов. Статус 4 указывает на плохую подпись.

Подведение итогов

Первая подпись была сгенерирована несколько дней назад 2015-09-23T18:44:56+00:00 ключом 468F82339FC55DE5CAFD71BB63DD32AE1308A57F и является правильной подписью, но ключ может быть проверен (отсутствует путь доверия).

Вторая подпись, похоже, выдана тем же ключом, но сломана.

Если я хочу просто распознать, правильно ли подписан текст или нет, могу ли я просто сравнить возвращенный отпечаток пальца с отпечатком открытого ключа и проверить, равны ли статус и сводка 0?

Насколько я понимаю, что происходит, вы должны проверить, установлен ли бит 4 summary или нет. Если он установлен, у вас плохая подпись. Не сравнивайте его с 4, но используйте битовую манипуляцию для проверки одного бита:

($summary & 0x04) == 0x04

Если вы не используете флаг web of trust и validity для проверки подписей, сделайте обязательно сравните весь отпечаток пальца со списком надежных ключей.

 1
Author: Jens Erat, 2015-09-26 11:53:29