I'm sending a PEM-encoded client certificate in a HTTP header via SSL_CLIENT_CERT varialbe from apache2 to jboss5 and in my application I'm reading the value of this header and I try to decode it in java but I get an unsuported encoding exception

java.security.cert.CertificateException: Could not parse certificate: java.io.IOException: Unsupported encoding
    at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:109)

my apache conf:

<VirtualHost *:443>

ServerName a.localhost
ProxyPass / http://b.localhost:8080/
ProxyPassReverse / http://b.localhost:8080/

SSLEngine on
SSLProxyEngine on
SSLProtocol all -SSLv2
SSLOptions +ExportCertData +StdEnvVars
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW

SSLVerifyClient optional
SSLVerifyDepth 1
SSLCertificateFile C:\Users\user\ssh\4pm.si_wildcard.crt
SSLCertificateKeyFile C:\Users\user\ssh\4pm.si_wildcard.key
SSLCACertificateFile C:\Users\user\ssh\ca_cert_bundle.crt
RequestHeader set X-ClientCert %{SSL_CLIENT_CERT}s

ErrorLog "C:/Apps/wamp/logs/4pm-error-ssl.log"
CustomLog "C:/Apps/wamp/logs/4pm-access-ssl.log" common


</VirtualHost>

my java code :

 String certStr = certStr = JSFUtil.getRequest().getHeader("x-clientcert");

 try {
        Certificate cert = CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(certStr.getBytes("UTF-8")));
    } catch (CertificateException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (UnsupportedEncodingException e1) {
        // TODO Auto-generated catch block
                e1.printStackTrace();
            }

Tnx to owlstead for the hint, which drives me to the solution.

The solution for this problem is:

you need those imports:

import java.io.ByteArrayInputStream;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.servlet.http.HttpServletRequest;
import org.jboss.util.Base64;

public static X509Certificate parseCertificate(String _headerName, HttpServletRequest _request) throws CertificateException{

    String certStr = _request.getHeader("x-clientcert");
    //before decoding we need to get rid off the prefix and suffix
    byte [] decoded = Base64.decode(certStr.replaceAll("-----BEGIN CERTIFICATE-----", "").replaceAll("-----END CERTIFICATE-----", ""));

    return (X509Certificate)CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(decoded));
}
有帮助吗?

解决方案

PEM is base 64 encoding with a header and footer line. You cannot just perform character-encoding on the text using UTF-8. You need to decode the PEM itself.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top