如何在PHP中对文件进行数字签名

时间:2012-03-14 18:20:55

标签: php digital-signature

我在我的数据库中创建了一个用户表,其中包含用于保存用户信息的不同列。此外,我添加了两列 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()
);

问题是:visa_cert.pem和private_key.pem是什么?我将生成的公钥粘贴在signing_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 个答案:

答案 0 :(得分:6)

我得出结论为什么不自己做数字签名功能。

数字签名算法的工作方式如下: 首先对纯文本进行哈希处理,然后用户的私钥对其进行加密,然后是结果 与纯文本连接。

伪代码:

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 :(得分:1)

signing_cert.pem和private_key.pem是用于签署该文件的证书。 因此,如果将它们存储在DB中,则需要将它们分别转储到名为signing_cert.pem和private_key.pem的文件中。

您遇到的错误是openssl尝试加载这些文件,因为它们不存在,所以它声称。

如果您从数据库中将这些文件写入硬盘,请执行TAKE IN MIND:

  1. 请勿将其存储在任何公共可访问文件夹中(避免使用DOCUMENT_ROOT和临时目录)。特别为私钥避免安全问题。
  2. 完成后删除它们。
  3. 此外,您可以(而不是在DB中使用这些证书)将它们存储在每个用户的某个文件夹中,以防止在签名时转储到文件。当然,任何人都不应该访问该文件夹。

    更多信息:PHP openssl_pkc7_sign