how to create jwk key for canvas? - jwk

In canvas, in order to have an LTI app authenticate, the site admin has enter the JWK for the remote site. The format of a JWK is well defined:
{
"kty":"RSA",
"kid":"...",
"use":"sig",
"alg":"RS256",
"n":"u6gqiV...",
"e":"AQAB"
}
First, can we use a tool like openssl, create a key, and generate a JWK from that? Currently we are writing code to do this using jose4j but it's not even clear if that is necessary.
second, Canvas is demanding optional fields like kid, alg, and use. We guessed that use should be "sig", we made up kid: "1" and guessed alg: "RS256"
Is there a place that is accessible (ie not behind IMSGlobal's paywall) that defines what this should be? Is it standard or specific to Canvas?

We meet again- been pouring over the LTI specs for months now, and am in the mood to see if I can spare others some headaches.
You may be familiar with validation schemas in which you use an SSL tool to generate a public and private key at the same time, entangled with each other. The public key is used to sign a payload, and since the payload itself is a factor in creating the signature, it cannot be intercepted and maliciously altered without invalidating it. The recipient is given the public key, used to verify that the the payload is clean.
JWK serves the same purpose as a public key. The only difference is, a developer doesn't need to email it to the recipient app's IT team in advance. The recipient of the JWT payload can retrieve it on-demand, all it needs to know is what URI to ask. That means the keys can actually be replaced by the sender without breaking any functionality.
As I mentioned elsewhere, in a bit of a rant more appropriate for this question:
This security step is akin to getting an email from your bank, and rather than click a potentially-spam link therein, you call your bank directly to make sure the email is on the level.
Now the sender's JWKS endpoint doesn't really know ahead of time who's going to reach out to it, and may want to service multiple other entities, so it may actually supply an array of public keys to cover all bases. The recipient of course only cares about the one associated with the payload it just received, so within the JWK signaure is a "kid", that can be matched up to the 'kid' in one of those array elements, affiliated with the relevant key.
How to create a JWK? Go here. Dependencies are listed at the top, and they probably use openssl under the hood.

The JWKs is a method of exchange the public keys between the tool and the platform, and to allow each side to control the rotation of their keys. The format for a JWKs is a managed ietf standard.
LTI 1.3 is based on the OIDC third-party initiation flow, which in-turn is based ontop of OAuth2. However, a full working knowledge of these specifications is not required to integrate your application with LTI 1.3. IMS curates a collection of code examples on github that might help you get started.

Related

Creating a plugin in the provider client

I am looking to create a plugin on yagna where providers will only accept tasks from whitelisted requestors utilizing private/public keys for authentication.
Are there any documentation or how can I go about doing it? Workflow as follows:
Requestor sends task in a specific subnet(do requestors also need a plugin, or are yagna ids unique?)
Providers on that subnet check if it's a whitelisted requestor by checking yagna id or other task information which cannot be faked
I am not entirely sure on how I would format it because I don't know how the system works behind the scenes - so any advice there might be necessary if my workflow is too bad.
It's a nice idea & it's doable.
You can differentiate requestors by their id's. To get the nodes' id (requestor or provider) just run yagna id list (yagna daemon has to be running - yagna service run).
Probably the most challenging part would be to modify ReactToProposal handler of CompositeNegotiator. Current implementation casts Proposal (Demand in this context) into ProposalView. Unfotunatelly at this point requestor_id is lost. For testing purposes you can just filter requestors directly in fn handle() and return Ok(ProposalResponse::RejectProposal {....}) when you want to block a requestor. Your field of interest is msg.demand.issuer_id.
If you want to introduce some kind of public/private key pair functionality, it could achieved by adding custom * demand/offer constraint* that is understood by both your requestor and provider. Unfortunately at this time there is no public documentation on this topic.
Please feel free to reach out if you have further questions.

Webauthn for encryption

We have a project with a PWA where we want to implement client sided encryption. We wanted to use Webauthn as a second-factor in combination with passwords. In the background we use a randomly generated key to encrypt/decrypt the database, which is stored symmetrically encrypted with the password on the server. However I am struggling to find a good way to add encryption to this key with webauthn. My tries so far:
Using raw JS samples from https://webauthn.guide , however I cannot find a part which is always the same and could be used for symmetric encryption/decryption, even the public key changes when logging in with the same USB token multiple times (???)
Using fido2-lib from npm: I couldn't get the sample to work, since the sample is not well documented and pretty long
Using server-sided authentication like spring webauthn, however I do not want the server to know anything about the client.
Any suggestions how I could implement an encryption with webauthn?
The protocol as it stands does not provide generic public key crypto services as far as I am aware. The best you can do is prove that a user is in possession of the private key related to the public key you hold.
You can learn from the following github repo ,it has many Webauthn out of the box examples (see the tech it supports inside)
Here are some samples I found at github https://github.com/OwnID/samples
In addition,I read about FIDO ,Webauthn and passkeys at passkeys.com
Everything about this cool tech is there
Years after this question, the hmac-secret extension has arrived.
This extension binds a secret to a Webauthn credential. This secret can be used to decrypt or encrypt data on client side.
Another approach could be the use of the largeBlob to store a secret generated during the creation ceremony.
Note that the availability of those extensions depends on the authenticator that is used and may fail.

unprotect data with password using .net core DataProtection?

My case is that I want to make the data protected even from people who have access to the back-end (the keys store), so they couldn't read it without the user's (represented by the client app, in my case the browser) assistance.
One option is to have the decryption keys stored on the client and passed with each request which sounds pretty messy to me and i'm not sure I want my keys to wander around the net like this. What I imagine though is that the client will keep some token (it might be a password the user knows) and the decryption can't happen without it.
I thought about using the purpose string for this, I have the feeling it is not a good idea since its main purpose is isolation. On the other hand it is part of the additional authenticated data used for subkey derivation. (based on this article https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/implementation/subkeyderivation?view=aspnetcore-2.1#additional-authenticated-data-and-subkey-derivation).
I came across some examples that create their own symmetric encryption with a lower level classes. (like this post Encrypt and decrypt a string in C#?). Since I'm not an expert in this area I would like to use as much build in classes as possible.
What is the recommended way to achieve what I need with the classes from the Data Protection API? (I'm using .net core 1.1 on Ubuntu)

Where can I find a description of BrowserID local verification

The FAQ recommends I don't do local verification of BrowserID (persona) security assertions, however I've never been good at following instructions.
So... I want to implement local verification anyway. It looks like the only thing the client libraries pass to the server side is a block of encrypted stuff called an "assertion". Presumably it is encrypted or signed using some public key encryption scheme, but I'm having trouble finding any details.
Can anyone explain it, or point me to the details?
The spec is currently not up to date with the latest data format changes, but this Python library has the ability to verify Persona assertions by itself (i.e. not using verifier.login.persona.org):
http://pypi.python.org/pypi/PyBrowserID

Protect public RSA key during transit

*Clarification: My question relates to setting up a "secure" communication channel between two parties where a key (read passphrase) has been agreed upon in the real world. Only using RSA allows for MITM-attacks (if I'm not misstaken), so I was thinking encrypting the public keys with AES (the key that both have agreed upon) before sending them to respective parties *
I'm currently trying to build two applications that talks with eachother. To secure the exchanged messages I was thinking on using RSA where each application has it's own set of keys.
Before communication is started between the two applications they do need to exchange keys. That shouldn't be a problem but I was thinking on using AES to encrypt the public keys before sending them over the internet.
I know what the word public (as in public key) means but I was thinking that this would see to that the right application/computer gets the key and no one else.
So I want to exchange keys and to protect them from MITM attacks.
If anybody could give a better suggestion (I'm using the LibCrypto library btw), I'm all ears.
Thank you.
Best regards
/Tomas Gustavsson
This question shows many misconceptions from your part.
I know what the word public (as in public key) means but I was
thinking that this would see to that the right application/computer
gets the key and no one else.
I think this is the real problem you have and ask.
Which I think is: How can you know that you are using the public key of the entity you actually want to communicate with and not the public key of a malicious entity claiming to be the who you want to communicate with?
This problem is solved in a typical installation by certificates signed by a trusted authority and issued to the specific entity i.e. IP or DNS name.
In your case you haven't given any details of your certificates.
You could just as well manually pre-install them and use them for your secure connections.
If you follow some other plan e.g. symmetric encryption then your would start asking other questions e.g. how do you securely share the secret key etc

Resources