mostafa/xk6-kafka

Using pfx certs instead of jks in xk6-kafka

luminorena opened this issue · 4 comments

Hi, @mostafa

I have PFX certificates for Kafka (keystore and truststore). Is it possible to use these certs to connect to Kafka with k6 using your library? Previously I had jks certs and everything worked perfectly.

If it is not possible to use pfx certs, should I convert them to jks? The problem is the conversion will use pkcs12, but your library does not work with pkcs12. Or maybe there are some other ways how to convert pfx to jks which will be applicable for your library, aren't they?

And if I create PEM cert, is it possibile to use your library then? I still cannot find any examples with neither pfx nor pem with Kafka.

UPD: I've tried to use test_tls_with_jks.js script to connect to Kafka with pfx but not jks. I have jks keystore type but the certs are in pfx.
As a result, I got this: errors.errorString=&{got invalid magic}

Nevertheless I have converted pfx to jks, connected to Kafka Tool successfully. Then I used this sample script to connect to kafka with k6 (all parameters I got from java keytool):

import { LoadJKS, TLS_1_2 } from "k6/x/kafka";

const keystore = LoadJKS({
path: "fixtures/kafka-keystore.jks",
  password: "password",
  clientCertAlias: "localhost",
  clientKeyAlias: "localhost",
  clientKeyPassword: "password",
  serverCaAlias: "caroot",
});

const truststore = LoadJKS({
  path: "fixtures/kafka-keystore.jks",
  password: "password",
  clientCertAlias: "localhost",
  clientKeyAlias: "localhost",
  clientKeyPassword: "password",
  serverCaAlias: "caroot",
});

const tlsConfig = {
  enableTls: true,
  insecureSkipTlsVerify: false,
  minVersion: TLS_1_2,

  clientCertPem: keystore ["clientCertsPem"][0], 
  clientKeyPem: keystore ["clientKeyPem"],
  serverCaPem: keystore ["serverCaPem"],

  clientCertPem: truststore ["clientCertsPem"][1], 
  clientKeyPem: truststore ["clientKeyPem"],
  serverCaPem: truststore ["serverCaPem"],
};

export default function () {
  console.log(Object.keys(keystore));
  console.log(keystore);
  console.log(Object.keys(truststore));
  console.log(truststore);
  console.log(tlsConfig);
}

and got the error "Failed to decode servers' CA".

But I guess, the problem is I used this command to convert certs:

keytool -importkeystore -srckeystore keystore.pfx -srcstoretype pkcs12 -destkeystore testKeystore.jks -deststoretype JKS

Your library does not support pkcs12 but the error was not about that.

Are there any ways to fix my problem ?

Hey @luminorena,

xk6-kafka supports two formats: JKS with PKCS#8 and PEM. If you have certificates in any other format, they should be converted to either of these. The LoadJKS function is a convenience function to convert JKS files to PEM before being consumed by TLS config. The function extracts the certificates into the same directory as the JKS file. The address of the files are then returned as an object, which in your case is called: truststore. The tlsConfig only supports a single certificate for each of the keys, so if you specify multiple keys, they will be overridden by JS. Also, it is your job to determine the index of the correct client certificate in the clientCertsPem property in truststore and you don't need to specify all.

Hi, @mostafa

I've converted pfx (which is actually the equivalent of PKCS#12) to pem and got two certs as a result - one for keystore and the other for truststore.
You write The tlsConfig only supports a single certificate for each of the keys, so if you specify multiple keys, they will be overridden by JS.

But in your library the certs are divided into several parts depending on the cert inside: clientCersPem, clientKeyPem and serverCaPem.
Is it possible to use only two certs (keystore.pem and truststore.pem) each of which contains all types of necessary certs?

UPD: I remember your library doesn't work with PKCS#12, so I've created PEM. And I don't know if it could work with such a PEM. I can also convert the resulted PEM into pure PKCS8 format, but I'm not sure where to use it to get a working cert.

UPD2: Is there any character escaping in LoadJks function, e.g. should I escape dot somehow or maybe the other characters?

@luminorena

This is the mapping:

  • clientCertsPem => keystore.pem
  • clientKeyPem => keystore.pem
  • serverCaPem => truststore.pem

In your case, the keystore.pem store both the certificate and the private key. So, you must split them before use, see this. Also, PEM is a de facto standard supported by Go and xk6-kafka uses Go standard library to load PEM files.

Many thanks! Everything works now. I see a message in Kafka Tool :)