如何使用BouncyCastle执行TLS? [英] How do I do TLS with BouncyCastle?
问题描述
有人知道与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屋!