java - 如何使用 BouncyCaSTLe 进行 TLS?

标签 java ssl certificate bouncycastle x509

有人知道带有 BouncyCaSTLe 的 TLS 示例吗?我对互联网上缺少它们感到惊讶。如果真的没有,让我们收集它们作为答案。

最佳答案

这是一个非常基本的示例,具有仅服务器身份验证和自签名证书。代码基于 BC 1.49,主要是轻量级 API:

ServerSocket serverSocket = new ServerSocket(SERVER_PORT);
final KeyPair keyPair = ...
final Certificate bcCert = new Certificate(new org.spongycastle.asn1.x509.Certificate[] {
    new X509V3CertificateStrategy().selfSignedCertificateHolder(keyPair).toASN1Structure()}); 
while (true) {
    Socket socket = serverSocket.accept();
    TlsServerProtocol tlsServerProtocol = new TlsServerProtocol(
    socket.getInputStream(), socket.getOutputStream(), secureRandom);
    tlsServerProtocol.accept(new DefaultTlsServer() {
        protected TlsSignerCredentials getRSASignerCredentials() throws IOException {
            return tlsSignerCredentials(context);
        }               
    });      
    new PrintStream(tlsServerProtocol.getOutputStream()).println("Hello TLS");
}

在哪里

private TlsSignerCredentials tlsSignerCredentials(TlsContext context) throws IOException {
    return new DefaultTlsSignerCredentials(context, bcCert,
            PrivateKeyFactory.createKey(keyPair.getPrivate().getEncoded()));                
}

这是客户端代码:

Socket socket = new Socket(<server IP>, SERVER_PORT);
TlsClientProtocol tlsClientProtocol = new TlsClientProtocol(    
    socket.getInputStream(), socket.getOutputStream());
tlsClientProtocol.connect(new DefaultTlsClient() {          
    public TlsAuthentication getAuthentication() throws IOException {
        return new ServerOnlyTlsAuthentication() {                  
            public void notifyServerCertificate(Certificate serverCertificate) throws IOException {
                validateCertificate(serverCertificate);
            }
        };
    }
});
String message = new BufferedReader(
    new InputStreamReader(tlsClientProtocol.getInputStream())).readLine();

您需要使用来自 tlsClient/ServerProtocol 的输入和输出流来读取和写入加密数据(例如 tlsClientProtocol.getInputStream())。否则,如果您使用例如socket.getOutputStream(),你只会写未加密的数据。

如何实现validateCertificate?我正在使用自签名证书。这意味着我只是在没有任何证书链的情况下在 keystore 中查找它们。这就是我创建 keystore 的方式:

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, password);
X509Certificate certificate = ...;
keyStore.setCertificateEntry(alias, certificate);

这是验证:

private void validateCertificate(org.spongycastle.crypto.tls.Certificate cert) throws IOException, CertificateException, KeyStoreException {
    byte[] encoded = cert.getCertificateList()[0].getEncoded();
    java.security.cert.Certificate jsCert = 
        CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(encoded));
    String alias = keyStore.getCertificateAlias(jsCert);
    if(alias == null) {
        throw new IllegalArgumentException("Unknown cert " + jsCert);
    }
}

比较令人困惑的是三个不同的证书类。您必须在它们之间进行转换,如上所示。

关于java - 如何使用 BouncyCaSTLe 进行 TLS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18065170/

相关文章:

google-chrome - 将 SSL 与 MAMP PRO 4 结合使用

php - SSL 上的 fsockopen 在特定主机上不起作用

java - 本地主机上的 SSLPeerUnverifiedException : peer not authenticated with self signed certificates in netbeans 8. 2

tomcat - 使用 key 工具制作 CSR,如何为 tomcat ssl 制作证书?

cryptography - 为什么使用 MD5WithRSA 签名的证书显示 SHA1 指纹?

java - 用 ArrayList 或 TreeSet 优化代码?

java - 如何对用户定义对象的链接列表进行排序?

java - Android 从 URL 设置 ListView 图片

iphone - 将 iPhone 存档交给经销商

java - 如何在java中的不同线程中显示和隐藏一个 View ?