Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/246.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP中对文件进行数字签名_Php_Digital Signature - Fatal编程技术网

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

如何在PHP中对文件进行数字签名,php,digital-signature,Php,Digital Signature,我在我的数据库中创建了一个user表,其中有不同的列用于保存用户信息。此外,我还添加了两列公钥和私钥。 当用户注册时,他的信息将被插入表中。另外,我正在使用: // Create the keypair $res=openssl_pkey_new(); // Get private key openssl_pkey_export($res, $privatekey); // Get public key $publickey=openssl_pkey_get_details($res); $

我在我的数据库中创建了一个user表,其中有不同的列用于保存用户信息。此外,我还添加了两列公钥私钥。 当用户注册时,他的信息将被插入表中。另外,我正在使用:

// 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

欢迎发表任何意见。

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

您得到的错误是openssl试图加载这些文件,但由于这些文件不存在,因此它声称

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

  • 不要将其存储在任何公共可访问文件夹中(避免文档根目录和临时目录)。专用于私钥,以避免安全问题
  • 完成后将其移除
  • 此外,您可以将这些证书存储在每个用户的某个文件夹中,以避免在签名时转储到文件中,而不是将它们存储在DB中。当然,任何人都不应该访问该文件夹


    更多信息:

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

    数字签名算法的工作原理如下: 首先对纯文本进行散列,然后由用户的私钥对其进行加密,然后生成结果 与纯文本连接

    伪代码:

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

    您认为我将生成的公钥粘贴到signing_cert.pem中,然后将私钥粘贴到private_key.pem中是正确的吗?signing_cert.pem看起来像:-BEGIN public key------zzz…zzz-----END公钥------和private_KEY.pem类似:-BEGIN RSA私钥------..z-----END RSA私钥------在私钥文件中不应该是DSA而不是RSA吗?(数字签名Alg。)如果你粘贴了这些文件,然后检查文件权限(下一次,请在WWW根目录外执行)。不幸的是,我不太了解回答你上一次评论的密钥,不知道是否应该使用DSA,但我已经看到许多用于此目的的RSA签名,因此,它应该与RSA配合使用。我将两者的权限都更改为0777,但没有成功,我建议只返回bool,因为这是函数名所建议的。有趣的是,如果数据中出现
    ----签名:-
    ,该怎么办?