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

发布于 2024-10-16 11:33:11 字数 971 浏览 4 评论 0原文

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

问题是:signing_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

任何意见都表示赞赏。

I made a user table in my DB with different columns for holding users' info. Also I have added two columns public_key and private_key.
When a user registers, his info will be inserted to the table. plus I am using:

// 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"];

to create a random key pair and give it to user so that every user has a key pair.
I want my users to have digital-signature ability, so when they upload a file they sign it.

I decided to sign a sample file(msg.txt) first to see if I can and then proceed. It looks straight forward:

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

The problem is: what are signing_cert.pem and private_key.pem ? I pasted my generated public key in signing_cert.pem and the private one in private_key.pem, but I see this error:

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

Any opinion is appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

西瑶 2024-10-23 11:33:11

我得出的结论是为什么不制作自己的数字签名功能。

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

伪代码:

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";
}

I came to conclusion of why not make my own digital signing function.

digital signing algorithm works like this:
first the plain text is hashed then it is encypted by user's private key, then the result
is concatenated with the plain text.

pseudo code:

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

For verifying: Input is splitted to plain text and signature. then signature is decrypted
using public key. Then the result is compared to the hash of the plain text and if they
are equal it means the signature is verified.

pseudo code:

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

Now the real PHP code which I have tested and currently using:

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";
}
粉红×色少女 2024-10-23 11:33:11

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

您收到的错误是 openssl 尝试加载这些文件,并且由于它们不存在,因此它声称。

如果您将这些文件从数据库写入硬盘,请记住:

  1. 不要将其存储在任何公共可访问文件夹中(避免 DOCUMENT_ROOT 和临时目录)。专门针对私钥,避免安全问题。
  2. 完成后将其删除。

此外,您可以不将这些证书存储在数据库中,而是将它们存储在每个用户的某个文件夹中,以防止在签名时转储到文件中。当然,任何人都不应该访问该文件夹。

更多信息: PHP openssl_pkc7_sign

signing_cert.pem and private_key.pem are the certificates you use to sign that file.
So if you have them stored in DB, you need to dump them to files called signing_cert.pem and private_key.pem respectivelly.

The error you are getting is that openssl tries to load those files, and since they do not exists then it claims.

If you write those files to harddisk from your DB, plase TAKE IN MIND:

  1. Do NOT store it in any public accesible folder (avoid DOCUMENT_ROOT AND temp directory). Specially for the private key to avoid security issues.
  2. Remove them when you've done.

Also, you could, instead of having those certificates in DB, have them stored in some folder for each user, to prevent dumping to a file when signing. Of course, that folder should not be accesible to anyone.

More info: PHP openssl_pkc7_sign

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文