How to request a digital certificate and use the public key to sign a string?

Asked

Viewed 1,824 times

3

I’m developing a web site for my TCC at php, and I’m at an impasse:

My application will need to request a digital certificate, which may be the file .cer or load from the user’s repository and sign a string unused Java, remote components or ActiveX, everything should be done locally, preferably in JavaScript.

So far so good, I found several materials and guides, but none explained in a clear and direct way how to do the whole process, from request the certificate to, finally, return the signed data.

Does anyone know any api, tutorial or way to solve this problem?

1 answer

2


To apply for the certificate would be this as the extensive answer of that question:

/a/195838/7130

About the signature, you have the function openssl_sign however to do it you need to have access to private key, and through SSL Handshake explained in the link of the issue I posted will not be able to do it.

I have used the following way, encrypt the content and then leave it to the client to decrypt and validate.

Connection Certificate will be available in variable $_SERVER['SSL_CLIENT_CERT'] , and you can use the openssl extension to sign and get public key details, remembering that the private key will be in the user’s possession and is not transferred. See the example implementation below:

<?php
$x509  = $_SERVER['SSL_CLIENT_CERT']
//Obter chave pública
    $pub_key = openssl_pkey_get_public($_SERVER['SSL_CLIENT_CERT']);
    $details = openssl_pkey_get_details($pub_key);
    
//Lendo outros dados do certificado.
        $cert = openssl_x509_read($_SERVER['SSL_CLIENT_CERT']);
        $certData = openssl_x509_parse($cert);
        openssl_x509_free($cert);       

        openssl_x509_export_to_file($x509,'/path/to/client_certificate.cer');
        
        $data  = "String para assinar ";
        
        //Criptografar
        $a_key = openssl_pkey_get_details($pub_key);
        $chunkSize = ceil($a_key['bits'] / 8) - 11;
        $crypttext = "";
        $data = gzcompress($data);
        while ($data) {
            $chunk = substr($data, 0, $chunkSize);
            $data = substr($data, $chunkSize);
            $encrypted = '';
            if (!openssl_public_encrypt($chunk, $encrypted, $pub_key)) {
                die('Failed to encrypt data');
            }
            $crypttext .= $encrypted;
        }
        $crypttext = base64_encode($crypttext); //String criptografada.
        echo $crypttext;
        openssl_pkey_free($pub_key);
        
        //Descriptografar:
        $privateKey = "user.key"; //User private key vc não vai ter acesso à ela.
        $a_key = openssl_pkey_get_details($privateKey);
        $chunkSize = ceil($a_key['bits'] / 8);
        $output = '';
        $encrypted = base64_decode($encrypted);
        while ($encrypted) {
            $chunk = substr($encrypted, 0, $chunkSize);
            $encrypted = substr($encrypted, $chunkSize);
            $decrypted = '';
            if (!openssl_private_decrypt($chunk, $decrypted, $privateKey)) {
                die('Failed to decrypt data');
            }
            $output .= $decrypted;
        }
        openssl_free_key($privateKey);
        echo gzuncompress($output);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.