как цифровой подписи файла в PHP - PullRequest
4 голосов
/ 14 марта 2012

Я создал таблицу user в моей БД с различными столбцами для хранения информации о пользователях.Также я добавил два столбца public_key и private_key .Когда пользователь регистрируется, его информация будет добавлена ​​в таблицу.плюс я использую:

// Create the keypair
$res=openssl_pkey_new();

// Get private key
openssl_pkey_export($res, $privatekey);

// Get public key
$publickey=openssl_pkey_get_details($res);
$publickey=$publickey["key"];

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

Я решил сначала подписать образец файла (msg.txt), чтобы посмотреть, смогу ли я, а затем продолжить.Это выглядит прямо:

openssl_pkcs7_sign("msg.txt", "signed.txt", "signing_cert.pem",
array("private_key.pem", "mypassphrase"),
array()
);

Проблема заключается в следующем: что такое signature_cert.pem и private_key.pem?Я вставил сгенерированный открытый ключ в signature_cert.pem, а закрытый - в private_key.pem, но вижу эту ошибку:

Warning: openssl_pkcs7_sign() [function.openssl-pkcs7-sign]: error getting 
private key in /home/ofathian/public_html/msc/ebook/mine/assymetric-test.php 
on line 40

Любое мнение приветствуется.

Ответы [ 2 ]

6 голосов
/ 16 марта 2012

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

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

псевдокод:

return [input + encrypt(md5(input),private_key)]

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

псевдокод:

explode(input) --> plain_text , signature
if( decrypt(signature,public_key) == md5(plain_text) ) then signature is trusted

Теперь настоящий PHP-код, который у меня естьпротестировано и в настоящее время используется:

function sign($cleartext,$private_key)
{
    $msg_hash = md5($cleartext);
    openssl_private_encrypt($msg_hash, $sig, $private_key);
    $signed_data = $cleartext . "----SIGNATURE:----" . $sig;
    return mysql_real_escape_string($signed_data);
}

function verify($my_signed_data,$public_key)
{
    list($plain_data,$old_sig) = explode("----SIGNATURE:----", $my_signed_data);
    openssl_public_decrypt($old_sig, $decrypted_sig, $public_key);
    $data_hash = md5($plain_data);
    if($decrypted_sig == $data_hash && strlen($data_hash)>0)
        return $plain_data;
    else
        return "ERROR -- untrusted signature";
}
1 голос
/ 14 марта 2012

signature_cert.pem и private_key.pem - это сертификаты, которые вы используете для подписи этого файла.Так что, если они хранятся в БД, вам нужно выгрузить их в файлы с именами signature_cert.pem и private_key.pem соответственно.

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

Если вы записываете эти файлы на жесткий диск из вашей БД, пожалуйста, примите:

  1. НЕ храните его в общедоступной папке (избегайте DOCUMENT_ROOTвременный каталог).Специально для закрытого ключа, чтобы избежать проблем безопасности.
  2. Удалите их, когда вы сделали.

Кроме того, вы могли бы вместо того, чтобы хранить эти сертификаты в БД, хранить их вкакая-то папка для каждого пользователя, чтобы предотвратить дамп в файл при подписании.Конечно, эта папка не должна быть доступна никому.

Дополнительная информация: PHP openssl_pkc7_sign

...