ssl - 如何从 itext bouncycaSTLe tsaclient 建立 ssl 连接

标签 ssl timestamp itext bouncycastle sslhandshakeexception

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

"Received fatal alert: 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连接不上服务器的时候。

最佳答案

我没有准备好来自 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
    }

关于ssl - 如何从 itext bouncycaSTLe tsaclient 建立 ssl 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26523992/

相关文章:

ssl - HttpWebRequest SSL 授权表

mysql - 获取基于同一天(时间戳)的n条数据

Android Webview 使用自签名证书

linux - 无法从 Ubuntu SSH 进入有线 SoC

ssl - 让 EV SSL 证书在 Nginx 上工作的问题

c - 为什么我在获取时间戳时得到负值?

php - 回显时间与 DB : all minutes are the same 中保存的时间不同

c# - 使用 iTextSharp 提取路径和形状

html - 使用 itextsharp 转换为 pdf 时不考虑字体大小和图像大小

java - 使用iTextpdf删除java中的pdf页面