SSL KafkaAdminClient object using java.security.Keystore object - ssl

I need to create kafkaAmdinClient SSL object using java.security.keystore object.
i.e I have to read the keystore and truststire files from database as a clob and get the keystore in java.security.keystore object and use this to create Admin client object.
I am able to create AdminClient object using properties object :
props.put(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG, trustStorePwd);
props.put(SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG, "/ngs/app/bolt_components/kafka_ssl/RN_BC_YELLOWBIRD/client.truststore.jks");
props.put(SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG, keyStorePwd);
kafkaAdminClient = AdminClient.create(props);
But as per requiremtn i should not specify keystore file location. Instead specify keystore object.
KeyStoreDto kDto=KeystoreManager.getKafkaKeyStoreDto(kafkaDto.getKEYSTORE_ID());
java.security.KeyStore keyStore = kDto.getKeyStore();
java.security.KeyStore trustStore = kDto.getTrustStore();
String keyStorePwd=kDto.getKeyStorePassword();
String trustStorePwd=kDto.getTrustStorePassword();
From this i have to use keyStore and trustStore.
Can anyone help me with this.

Kafka does not support ssl using java.security.keystore object.
You can look into SslFactory class at kafka for more information.

Related

using value of variable and string to fetch from terraform data source

I am trying to fetch some certficates from hashicorp vault using tf data source
This is how cert path looks like in vault
serverA:
dev-cert: <base64 encoded cert>
qa-cert: <base64 encoded cert>
test-cert: <base64 encoded cert>
This cert is used in other resource block which works fine as shown below
resource <somegcpresource> <xyz>
{
certificate = base64decode(data.vault_generic_secret.server_cryptoobjects.data["dev-cert"])
}
Can I use a custom env variable to fetch value of certificate like;
certificate = base64decode(data.vault_generic_secret.server_cryptoobjects.data["var.env-cert"])
or a local var to reference the key name from vault datasource like;
certificate = base64decode(data.vault_generic_secret.server_cryptoobjects.data[local.certname])
Yes, the data.vault_generic_secret.server_cryptoobjects.data is an object so you can access its values with their corresponding keys. If you declare a variable env-cert:
variable "env-cert" {
type = string
default = "dev-cert"
}
then you can use it as the key:
certificate = base64decode(data.vault_generic_secret.server_cryptoobjects.data["var.env-cert"])
Yes you can also use a local as the key:
locals {
certname = "dev-cert"
}
certificate = base64decode(data.vault_generic_secret.server_cryptoobjects.data[local.certname])
I would also suggest looking at the Vault PKI secrets engine for your overall use case if you have not already, since this example in the question is using the KV2 secrets engine.

How to create RsaSecurityKey.KeyId with IdentityServer4

I'm using IdentiyServer4 to generate tokens, I'm using the AddDeveloperSigningCredential() method to generate my RSA key with a KeyId.
But, in production, I'm using AddSigningCredential(CreateSigningCredential()), to generate a key like this :
private SigningCredentials CreateSigningCredential()
{
var signinkey = new RsaSecurityKey(RSA.Create());
signinkey.KeyId = "abcdefghijklmnopqrstuvwxyz";//How to generate KeyId ??
var credentials = new SigningCredentials(signinkey,
SecurityAlgorithms.RsaSha256);
return credentials;
}
How can I generate a KeyId? Can I set it to any arbitrary value?
You don't need to set the keyId and also creating the RSA key youself in code, sounds like bad practice. Then you can just as well use the AddDeveloperSigningCredential method.
You can actually look at the source for that method here to see how they do it in code:
https://github.com/DuendeSoftware/IdentityServer/blob/main/src/IdentityServer/Configuration/DependencyInjection/BuilderExtensions/Crypto.cs
But, in production you should generate the key externally and pass it in to IdentityServer, so the key is the same across redeployment/restarts. Otherwise previously issued tokens will not be valid anymore.
You can for example store the key in Azure Key Vault, or using some other configuration/secret system. Or in a database or as a file somewhere.
If you want to create one manually, using OpenSSL, then you can write
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -aes256 -out rsa-private-key.pem

JwtBearer Auth with Azure key vault

I wanted to use Azure Key Vault to store key which will be used to create signature for JwtTokens generated by my API.
For Jwt token authentication I use Microsoft.AspNet.Authentication.JwtBearer and i configured it like that:
app.UseJwtBearerAuthentication(options =>
{
options.TokenValidationParameters.IssuerSigningKey = this.tokenAuthKey;
options.TokenValidationParameters.ValidAudience = this.tokenOptions.Audience;
options.TokenValidationParameters.ValidIssuer = this.tokenOptions.Issuer;
options.TokenValidationParameters.ValidateSignature = true;
options.TokenValidationParameters.ValidateLifetime = false;
options.TokenValidationParameters.ClockSkew = TimeSpan.FromMinutes(0);
});
So, as you see, this configuration requires to provide full key with private part (IssureSigningKey property). It works fine when my key is stored unprotected in xml file, somewhere in file system and I'm just loading it during application startup. However, there is a problem when i try to store my key in Azure Key Vault (AKV). Since AKV only allows to withdraw public part of the key, Im struggling to make it all work together.
I found out that TokenValidationParameters class has delegate property that i can use to provide my own validator method which would use AKV encrypt/decrypt methods to determine if signature is valid.
The problem is I can't determine how to specify my own method that would generate signature part of JWT token, so that configuration of Microsoft.AspNet.Authentication.JwtBearer won't need private key.
My question is: is it possible somehow to specify my own method that creates signature for generated JWT token in JwtBearer configuration or during creation of token using JwtSecurityTokenHandler.CreateToken?

Twisted SMTP server, adding SSL support, 2 factories?

Having recently asked Twisted mail server with TLS - no portal? It seems I was barking up the wrong tree - so now it seems pertinent and appropriate to ask a fresh, revised question.
So I am trying to extend the basic SMTP server sample found at http://twistedmatrix.com/documents/current/_downloads/emailserver.tac to support SSL connections. I can create an ssl Context Factory as follows (code lifted from my previous efforts:
caCertFile = open("/opt/tesa/etc/certs/CA/cacert.pem","r")
certFile = open("/opt/tesa/etc/certs/server/server.crt","r")
keyFile = open("/opt/tesa/etc/certs/server/server.key","r")
caCertData = caCertFile.read()
pKeyData = keyFile.read()
certData = certFile.read()
caCert = ssl.Certificate.loadPEM(caCertData)
cert = load_certificate(FILETYPE_PEM, certData)
pKey = load_privatekey(FILETYPE_PEM, pKeyData)
sslCtxFactory = ssl.CertificateOptions(privateKey=pKey, certificate=cert, trustRoot=caCert)
So now I have the SMTP Factory from emailserver.tac, and my sslCtxFactory above. In my old code, I created an object of class ESMTP as follows:
myESMTP = ESMTP(contextFactory=sslCtxFactory)
factory = protocol.Factory.forProtocol(lambda: mySMTP(contextFactory=sslCtxFactory))
endpoint = endpoints.TCP4ServerEndpoint(reactor, 8001)
endpoint.listen(factory)
But since this code isn't using a portal etc, then some of the methods/functions in the class definition for ESMTP fail owing to various attributes not being defined (eg self.delivery, self.portal).
So I'm trying to understand how to implement my sslCtxFactory in the mailserver.tac code - while still using a portal / realm as per mailserver.tac, so as to ensure the methods in twisted's ESMTP class don't fail.
But how can I bring these two factories "together"?
Thanks
This looks strange:
myESMTP = ESMTP(contextFactory=sslCtxFactory)
factory = protocol.Factory.forProtocol(lambda: mySMTP(contextFactory=sslCtxFactory))
Instances of the ESMTP class provided by Twisted aren't callable. I think you must have meant something like:
from functools import partial
myESMTP = partial(ESMTP, contextFactory=sslCtxFactory)
factory = protocol.Factory.forProtocol(mySMTP)
Assuming so...
The ESMTP class respects the self.portal attribute for its authentication and authorization behavior. All you need to do is get it set.
SMTPFactory is a factory for SMTP instances that sets the protocol's portal attribute to the value of its own (the factory's) portal attribute. The only trouble is that it makes SMTP instances instead of ESMTP instances.
Fortunately, it (the factory) respects its protocol attribute for the class to instantiate.
If you were to write:
portal = Portal(...)
myESMTP = partial(ESMTP, contextFactory=...)
factory = SMTPFactory.forProtocol(protocol=myESMTP, portal=portal)
then you would have a factory which:
creates instances of ESMTP
passes contextFactory=... to the initializer of ESMTP when instantiating it
sets the portal attribute on the ESMTP instances after it instantiates them, using the value passed in to forProtocol here.

x509Certificate - Save a binary signature in pkcs#7 format (.net c#)

I am signing some data with a self signed X509Certificate in c#. Signature results as a binary byte[]. I want to save this signature to a pkcs#7 format file with extenstion .p7b. When I save this using FileStream as required. It generates an invalid p7b file.
Can anyone help save this signature as a valid external file? Or point out if there is something wrong with the approach?
// EDIT: Adding the code as asked by Eugene Mayevski
// Open Store Location & fetch certificate
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadWrite);
X509Certificate2Collection certifcates = store.Certificates;
X509Certificate2 certificate = certifcates[0];`
// fetch private key
string publicKeyString = certificate.GetPublicKeyString();
RSACryptoServiceProvider privateKey = certificate.PrivateKey as RSACryptoServiceProvider;
// get binary of data & sign it.
byte[] buffer = Encoding.Default.GetBytes("Sample data to sign. Although it would be a document.");
byte[] signature = privateKey.SignData(buffer, new SHA1Managed());
You are not generating a Cryptographic Message Syntax (CMS) message format which is defined in PKCS#7. You generate just the signature, which can be placed in the container format.
To create a CMS formatted message yourself, please take a look at the Microsoft documentation or use the C# version of Bouncy Castle.