如何使用BouncyCastle执行TLS? [英] How do I do TLS with BouncyCastle?

查看:2507
本文介绍了如何使用BouncyCastle执行TLS?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人知道与BouncyCastle TLS的例子吗?我对在互联网上缺少他们感到惊讶。如果真的没有,让我们收集他们作为答案。

Does anybody know about examples of TLS with BouncyCastle? I was surprised by the lack of them on Internet. If there are really none, let's collect them as answers.

推荐答案

这是一个非常基本的示例,仅使用服务器身份验证和自签名证书。代码基于BC 1.49,大多是leightweight API:

This is a very basic example, with server-only authentication and self-signed cert. The code is based on BC 1.49, mostly leightweight 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(),你只需要写未加密的数据。

You need to use the input and output stream from tlsClient/ServerProtocol to read and write encrypted data (e.g. tlsClientProtocol.getInputStream()). Otherwise, if you used e.g. socket.getOutputStream(), you would just write unencrypted data.

如何实现validateCertificate?我使用自签名证书。这意味着我只是查找他们在钥匙库没有任何证书链。这是我如何创建密钥存储:

How to implement validateCertificate? I am using self-signed certificates. This means I just look them up in the key-store without any certificate chains. This is how I create the key store:

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);
    }
}

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

What is rather confusing, are the three different Certificate classes. You have to convert between them as shown above.

这篇关于如何使用BouncyCastle执行TLS?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆