1

我正在尝试通过 HTTPS 连接使用 itext tsaclient 时间戳,当 tsaclient 尝试建立与服务器的连接时,我在登录时遇到了连接问题。通过 whireshark 分析我收到的流量

“收到致命警报:bad_certificate”

关键是我可以建立连接,但不能从 tsaclient,

//Preparing keystore with Private Key
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
KeyStore ks = KeyStore.getInstance("pkcs12", provider.getName());
ks.load(new FileInputStream(Constantes.CERT), Constantes.PASS_CERT.toCharArray());
String alias = (String)ks.aliases().nextElement();
PrivateKey pk = (PrivateKey) ks.getKey(alias, Constantes.PASS_CERT.toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);

//Adding Server public key to the keystore ks
FileInputStream is = new FileInputStream(new File(Constantes.SERVER_CERT_CER));
CertificateFactory cf = CertificateFactory.getInstance("X.509");
java.security.cert.X509Certificate cert = (X509Certificate) cf.generateCertificate(is); 
ks.setCertificateEntry("alias", cert);

//Preparing SSL Context
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, "pass".toCharArray());

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);

SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers(),tmf.getTrustManagers(), new SecureRandom());
SSLSocketFactory sf = ctx.getSocketFactory();

URL url = new URL("https://...");
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(sf);
conn.setConnectTimeout(0);
conn.connect(); 

//Until here the connection is OK, "Certificate Verify" say whireshark

//Preparing TSA Client and Sign
ExternalDigest digest = new BouncyCastleDigest();
TSAClient tsaClient = new TSAClientBouncyCastle("https://...");

ExternalSignature es = new PrivateKeySignature(pk,"SHA-1","BC");
MakeSignature.signDetached(appearance, digest, es, chain, null, null, tsaClient, 0, CryptoStandard.CMS);

当我无法连接服务器时,正是在 MakeSignature 时刻。

4

1 回答 1

0

我没有准备好来自 TSAClient 的连接,现在我已经正确实现了客户端。

//Preparing keystore with my Private Key and Server Certificate
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);     
ks = KeyStore.getInstance("pkcs12", provider.getName()); //public static KeyStore ks;
ks.load(new FileInputStream(Constantes.CERT), Constantes.PASS_CERT.toCharArray());      
String alias = (String)ks.aliases().nextElement();
PrivateKey pk = (PrivateKey) ks.getKey(alias, Constantes.PASS_CERT.toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);


FileInputStream is = new FileInputStream(new File(Constantes.SERVER_CERT_CER));
CertificateFactory cf = CertificateFactory.getInstance("X.509");
java.security.cert.X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
ks.setCertificateEntry("alias_server_cert", cert);


//Making TSA and Sign    
ExternalDigest digest = new BouncyCastleDigest();
TSAClient tsaClient = new Sellado("https://url");

//Digital signature
ExternalSignature es = new PrivateKeySignature(pk,"SHA-1","BC");
        MakeSignature.signDetached(appearance,digest,es,chain,null,null,tsaClient,0,CryptoStandard.CMS);

TSAClient“Sellado”基于 TSAClientBouncycastle,使用 SSL 上下文更改下一个类。

public class Sellado implements TSAClient{

//Code  

protected byte[] getTSAResponse(byte[] requestBytes)
     throws IOException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyStoreException, KeyManagementException
  {

 //Preparing SSL Context

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(EmpadronamientoI.ks, "pass".toCharArray());

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(EmpadronamientoI.ks);

SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers(),tmf.getTrustManagers(), new SecureRandom());
SSLSocketFactory sf = ctx.getSocketFactory();

URL url = new URL(this.tsaURL);
HttpsURLConnection tsaconn = (HttpsURLConnection)url.openConnection();
tsaconn.setSSLSocketFactory(sf);
tsaconn.setConnectTimeout(0);

tsaconn.setDoInput(true);
tsaconn.setDoOutput(true);
tsaconn.setUseCaches(false);
tsaconn.setRequestProperty("Content-Type", "application/timestamp-query");
tsaconn.setRequestProperty("Content-Transfer-Encoding", "binary");

try{
    tsaconn.connect();
        }
catch (IOException ioe) 
    {
           throw new IOException(MessageLocalization.getComposedMessage("failed.to.get.tsa.response.from.1", new Object[] { this.tsaURL }));
         }


 OutputStream out = tsaconn.getOutputStream();
 out.write(requestBytes);
 out.close();


 InputStream inp = tsaconn.getInputStream();
 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 byte[] buffer = new byte['?'];
 int bytesRead = 0;
 while ((bytesRead = inp.read(buffer, 0, buffer.length)) >= 0) {
  baos.write(buffer, 0, bytesRead);
    }

 byte[] respBytes = baos.toByteArray();

String encoding = tsaconn.getContentEncoding();
if ((encoding != null) && (encoding.equalsIgnoreCase("base64"))) {
   respBytes = Base64.decode(new String(respBytes));
 }

return respBytes;
   }
    //Code
    }
于 2015-11-04T00:54:45.730 回答