How WCF service and consumer client exchange keys for certificate? - encryption

I read a simplification about how public and private keys work on security.stackexchange.com: How can I explain the concept of public and private keys without technical jargon?.
Whatever I understood from there: private key sat at owner and owner send a encrypted data to some one along with public key. Public key decrypts that data at client side and also encrypt data of client sent to owner. Once the data is encrypted at client side by public key then the same public key can not reused to encrypt that data. Only the owner of the private key can encrypt and decrypt data as many as time.
Am I right whatever I understood?
My question is: how public key is travel from owner side to client side?
Every time the same public key will be sent from server end to client end or ever time the different public key will be send from server end to client end?
#Ewan said as follows:
Client : Sends "Hello"
Server : Here is my public key
Server : Please send your public key
Client : Here is my (encrypted with server public key)public key
Client : Here is an (encrypted with server public key)request
Server : Here is an (encrypted with client public key)response
This raises the following questions at said steps:
When first time client send Hello to server then how hello
will travel to server in encrypted way?
Do not understand why server find his public key?
Why server request client to send his public key?

No you are wrong:
PersonA : creates public and private key pair
PersonA : Sends Public Key(A) to PersonB
PersonB : Encrypts data with Public Key(A)
PersonB : Sends encrypted Data to PersonA
PersonA : Decrypts encrypted Data with Private Key(A)
WCF can be setup to do multiple types of encryption and protocols but essentialy what i think you are asking boils down to
Handshake protocol:
Client : Sends "Hello" (not encrypted)
Server : Here is my public key (ServerPublicKEY = "123")
Server : Please send your public key
Client : Here is my public key (ClientPublicKEY = "ABC")
Client : Here is an (encrypted with ServerPublicKEY)request
Server : Decrypt with server private key and read
Server : Here is an (encrypted with ClientPublicKEY)response
Client : decrypt with client private key
to answer your additional questions
q1: "When first time client send Hello to server then how hello will travel to server in encrypted way?"
a1: It is not encrypted
q2: "Do not understand why server find his public key?"
a2: the server sends a public key so that the client can encrypt messages to send to the server
q3: "Why server request client to send his public key?"
a3: The server needs the clients public key so it can encrypt messages to send to the client

Related

Verify SHA256 signature of received message

I need to verify a SHA256 signature where we receive in every communication the message, signature and public key.
I'm trying to load a public key we receive in an Azure Function (.net core 3.1) into a X509Certificate2 object to be able to verify the signature of a received message and signature.
The following code is used:
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var data = JsonConvert.DeserializeObject<RequestObject>(requestBody);
var keyBytes = Convert.FromBase64String(data.key);
X509Certificate2 cert = new X509Certificate2(keyBytes);
When the last statement fires, the following exception comes up:
at Internal.Cryptography.Pal.CertificatePal.FromBlobOrFile(Byte[] rawData, String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] data)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData)
at leo_signing_library.Function1.<Run>d__0.MoveNext() in
C:\Users\Leo\source\repos\leo-signing-library\Function1.cs:line 30
When running in debug the following error comes up in the debug window:
System.Private.CoreLib: Exception while executing function:
CheckSignature. System.Security.Cryptography.X509Certificates: Geen
overeenkomend object gevonden.
Just for clarity a screenshot of the debug window:
screenshot
I've added the nuget package System.Security.Cryptography.X509Certificates (version 4.3.2), but no effect.
Does anyone know how to overcome this? Or has a working example of verifying a signature based on a public key not stored in the certificate store?
Edit 1:
I'm trying to load the following public key:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1iyta8F+SLHhbfy+f7fL
8LrsS1LKs05UaHm6muOTlzIdSDwo4dNiWg6rbiL2v4IwpglgL8kvbXLZ8Z3/E6Uu
uUi/IW1Hakgx65Qy4LkGxsnZ/jnLu3DxfY9xycMYq9TfNxIIvFPkbEJY/pwGjZ+q
13WegTJG7m+tqf5GbA3xTLz2DSHXPc7y77OnsDawHsOEou9IZZQCdxCg3L186gU4
yj6mC07Eop3lKMjsqNAXdVmnzcUc+PixQFCSjOcL9Fpbq+aHyYW+Pk9h5dWCGGNQ
wixTIJKTeDxAEkbZ2eLuqQZOCNbkHBn9x+IBxeKMmsmRg/J4/QqwCm+t+wd4VNAJ
ewIDAQAB
-----END PUBLIC KEY-----

.NetCore 2.2: How to get a private key of a certificate?

for the implementation of an API I use, I need to provide a certificate, which consists of 2 byte arrays one for the public key and the other one for private key.
My initial idea was to do this with X509Certificate object of .Net. But I am struggling to get the private key bytes.
var certificate = new X509Certificate2("testCert.pfx", password, X509KeyStorageFlags.Exportable);
byte[] myPublicKey = certificate.GetRawCertData();
byte[] privateKey = ???
I've tried to export the key, but I can't export the private key standalone.
And:
certificate.PrivateKey.ToXmlString(true);
is not available on a Ubuntu System :-(
Do you have any ideas, how to get the private bytes from certificates?
May be X509Certificate2 is not the best solution for this...
Use an approrpiate method of these X509Certificate2 extension methods:
GetRSAPrivateKey(X509Certificate2) -- for RSA keys
GetDSAPrivateKey(X509Certificate2) -- for DSA keys
GetECDsaPrivateKey(X509Certificate2) -- for EC keys
Extension method you need to use depends on asymmtric key algorithm.

Send a private key with JWT

Can I use JWT to exchange a private key ?
I must use this private key to decrypt earlier encrypted data. I use TLS to exchange information between the server and client. Is secure ? It is a valid idea to exchange the key ?
Example:
Header
{
"alg": "HS256",
"typ": "JWT"
}
Payload
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"private_key": Base64(generated private key)
}
Signature
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
passphrase
)
When a secured communication is established, each stakeholder generates/has its own private key. Only public keys are exchanged. Private key exchange should be prevented.
Anyway, if you you really need to send a private key through the JWT format, then you should read about the JSON Web Key (JWK) specification (RFC7517) section 7.
The process is quite simple: create a JWE with the JWK as payload and mandatory headers plus the (optional) cty header parameter with value jwk+json.
Example:
JWE Header:
{
"alg":"A256KW",
"enc":"A256GCM",
"cty":"jwk+json"
}
JWE Payload (the JWK):
{
"kty":"oct",
"alg":"A128KW",
"k":"GawgguFyGrWKav7AX4VKUg"
}

push data from server to client with specified Id signalR

I received data from different server to my Hub class. Each data has its own ID. Whenever data comes to the server hub, it push my data to the client. This is like job progress.
I want to send each ID to the client with unique hub id., How do I filter the message from the server? I used in this way Clients.Client("ID1").send(data); Or I have to specify in caller property? Anyone can help me.
With Regards,
Shanthini
You can use ConnectionId to identify the client.
When new client is connected, store ConnectionId somewhere so that you can use it later to identify the client.
public class MyHub : Hub
{
public override Task OnConnected()
{
var connectionId = Context.ConnectionId;
// store connectionId somewhere
return base.OnConnected();
}
}
To send data to the client, identify it by ConnectionId:
public void SendNewData(string connectionId, object data)
{
var Context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
Context.Clients.Client(connectionId).send(data);
}
If you need to identify clients by some other ID, then you should store relationship between your ID and ConnectionId.

SignalR - Getting a connection id on server-side during negotiate request

SignalR's negotiate calls returns a connection id. Is there a way to get connection id on server side when negotiate request has been called?
Is there a server side event that I can subscribe to when connection id has been generated?
If you are using a PersistentConnection you can override the
ProcessRequestAsync(HostContext context)
method and get the connectionId value from the IResponse property of the HostContext.
Another way would be to use the DependecyResolver to provide your own implementation of IConnectionIdFactory that raises an event before returning the connectionId string.
If you are using SignalR Hub, you can listen to the connect event then grab Context.ConnectionId. E.g.
public override Task OnConnected()
{
return Clients.All.joined(Context.ConnectionId, DateTime.Now.ToString());
}
See https://github.com/SignalR/SignalR/wiki/Hubs for more.
string connectionID = Context.ConnectionId;

Resources