I'm learning about tokens using .Net Framework. One thing I cannot seem to find is how to create a token with a signature made with JWK. I found plethora of articles explaining how to validate JWT with JWKS, and how to sign JWT with RSA or HMAC.
I tried using libraries like BouncyCastle and jose-jwt, but the format of JWK is encoded differently, and would not be accepted. I successfully created and signed tokens using ssh-keygen RSA keys, but I can't get the CRT variables for decoding from these.
I wish to just take JWK-generated keys and use them, just like I would use the ssh-keygen ones
Related
NOTE: Self signed certificate is installed on my machine.
I have a JWT token, which I am trying to sign using RSA algorithm, I found a library "JOSE" for achieving the same with the below method.
Jose.JWT.Encode(payload, certificate.GetRSAPrivateKey(), JwsAlgorithm.RS256);
After digging into it's "Encode" method, I found that it is using Hashing SHA-256 algorithm in it.
I am looking for a approach where hashing is excluded & directly signed by using RSA .
Any help will be appreciated !
The hash is a security requirement for most if not all signature algorithms. So you cannot exclude it.
You can however use RSA using signatures giving (partial) message recovery (as specified in ISO/IEC 9796-2) , which can return (part of) the message that has been signed. They are generally considered deprecated; if you need less signature overhead then you'd use Elliptic Curve cryptography instead.
However, which of these two you choose doesn't matter, as either one would break the JOSE / JS Web Token protocol you're trying to implement.
I am using a Token based authentication. My web server would generate and encrypt the token. I want the client to decrypt the token to read certain payload information.
What algorithm I should use to achieve this?
In my understanding if I use RSA, I can decrypt in c# using private key whereas the encryption has to happen from other hand so this doesn't fit-in my scenario. Is there any other asymmetric algorithm or ways to achieve this?
Server encrypt - private key.
Client decrypt - public key.
Is there any other asymmetric algorithm or ways to achieve this please suggest.
I want to correct your understanding of asymmetric encryption. Asymmetric encryption allows anyone with the public key to send a secret message to anyone with the private key. Since the public key is public, asymmetric encryption allows many possible senders to send private messages to a few special recipients.
My web server would generate and encrypt the token. I want the client to decrypt the token to read certain payload information.
In that case, with the server sending a secret message to the client, if you are using asymmetric encryption, then the server will encrypt with the public key, and the client will decrypt with the private key.
Server encrypt - private key. Client decrypt - public key.
That is not correct. In asymmetric cryptography, the public key does the encryption and the private key does the decryption.
What you might be thinking about is a digitally signed message. In that case, the sender signs the message with the private key and the receiver verifies the signature with the public key. Digitally signed messages are not secret, though, whereas encrypted messages are secret.
Is there any other asymmetric algorithm or ways to achieve this please suggest.
Since your use case is not entirely clear, I will stop the answer there, and leave it at correcting your understanding of asymmetric encryption. It might be that you need symmetric encryption or a digital signature. I encourage you to ask another, separate StackOverflow question as a follow up to this one.
As a final note, I'll refer you to the Internet Security Glossary. In particular, the section named "$ asymmetric cryptography" has a precise and brief description about how "Asymmetric cryptography can be used to create algorithms for encryption, digital signature, and key agreement."
From your other (unfortunately on hold) question https://stackoverflow.com/questions/49610839/protecting-jwt-signing-and-encryption-c-sharp-solution, it sounds like you require the following:
Send a payload from the server to the client.
Only the client can read the payload, because it is encrypted.
The client can verify who sent the payload, because it is signed.
The recommended approach is to sign-and-then-encrypt. If you are wanting to use asymmetric encryption for both:
use a private to key to sign the payload,
then use a public key to encrypt the signed payload.
I have some data of an X509v3 certificate that is used at a central licensing station. My question is is the following amount of information enough for me to decrypt data using C# code? And additionally, how are the certificate properties imported into a project? Do I have to create a certificate file in order to go on?
Known to me are:
Subject
Serial Number
Issuer
"root-ca"
Public Key Algorithm: "rsaEncryption"
RSA Modulus, 128 bytes
RSA Public Key Exponent
X509v3 Extended Key Usage: "critical"
Signature Algorithm: "md5WithRSAEncryption", followed by 256 untitled bytes
SHA1 Fingerprint
I do not have any certificate file. Excuse me if a similar question has already been answered, unfortunately I wasn't able to find one like mine.
No, your data is not enough. First of all, this is all public data. It doesn't contain a private key. A private key is used for decryption or signature generation. A public key is used for encryption and signature verification.
The .NET API is peculiar in that you can seemingly use a certificate to decrypt. This is not really the case; the certificate and private key pair are seen as one; only if the private key is included then you can actually decrypt. Personally I see this as a minor design mistake.
In principle you could create a certificate given the information. Basically you would have to generate a certificate with the same information and then replace the issuer and signature fields.
This is however not for the weak of heart; I recommend a few years of experience before you even try. If any information is missing from the list above you won't get a valid certificate / signature, and you won't get any warning what is wrong, just a failure. You've got one advantage though; if the signature verifies or fingerprint is identical to the one you've got then you know that you've succeeded.
You would not be able to decrypt of course; the private key would still be missing.
Note that the signature is the 256 untitled bytes.
This information is not enough. This data is a public key to encrypt data.
RSAParameters
I am new to this domain but I was trying to generate a JWT using the JWT nuget package.
My understanding is that you supply a secret key to sign the Token but when I got the token I went to JWT website to test it and the website was able to decode it without me supplying the secret key.
I thought that you generate the token then you sign it and thus prevent anybody from knowing the content of the token unless they have that secret key. Is this not the case?
JSON Web Tokens are an encoded representation of a data structure. It is not required that this encoded data be encrypted, but it is acceptable to do so.
From the definition of Code Signing:
Code signing is the process of digitally signing executables and scripts to confirm the software author and guarantee that the code has not been altered or corrupted since it was signed by use of a cryptographic hash.
A JWT which has been encrypted will typically have two hash values, the first to decrypt the data, the second to validate the code signing. Decoding a non-encrypted JWT is a standardized process, and can be done even if the code sign isn't verified. However, it is recommended not to use any data in a JWT if the code signing hash does not match, as this indicates the data may have been tampered with.
Not all JWT implementations support encryption; notably, there is no encryption support in Microsoft's JWT implementation. https://stackoverflow.com/a/18224381/2495283. Therefore, if you have data which you must ensure remains secret, you should encrypt the data using JWE. The JWT standards documentation shows an example of this process. The data is first encrypted, then the encrypted string and decoding algorithm are sent as the payload of the JWT.
I'm a PHP developer who knows almost nothing about .NET. I've been asked by the .NET guys at work to translate .NET code that decrypts an authentication ticket into PHP so that the PHP code can then set the appropriate session variables for my application to run. Is this even possible? I'm staring at the code and it's baffling me. I'll keep trying if someone can tell me it's not a waste of time for some reason I don't even know. Thanks for any help!
Additional info: Can I even grab the ticket with PHP in the first place?
First off, open your machine.config and add in a machinekey entry. Set the decryption key and validation key according to a randomly generated ones from a machinekey generator for aspnet 2.0.
Be sure to use the default's, ie. AES and SHA1.
Now that you have the AES decrypt key, store it somewhere because you are going to need it on the php side.
In your dot net app, go into the web.config and get the forms auth cookie name, usually something like .ASPXAUTH
Now go to the PHP side. Download and set up an AES encryption library, like this one, http://phpseclib.sourceforge.net/documentation/
Then in PHP you can do something like this (this uses the phpsec lib):
set_include_path(get_include_path() . PATH_SEPARATOR . 'phpseclib');
include('Crypt/AES.php');
$authCookie = $_COOKIE['_ASPXAUTH'];
echo $authCookie;
$aes = new Crypt_AES();
$aes->setKey('BCDCBE123654F3E365C24E0498346EB95226A307857B9BDE8EBA6198ACF7F03C');
echo $aes->decrypt($authCookie);
Now what ends up coming out is going to first be pm + the SHA1 hash + a byte representation of the auth ticket. You must convert the serialized bytes to a string to make it readable. Can someone else iluminate on that last step?
As Gumbo said, you need to take into account the algorithms involved. The asp.net authentication ticket uses:
Create a serialized forms
authentication ticket. A byte array
representation of the ticket is
created.
Sign the forms authentication
ticket. The message authentication
code (MAC) value for the byte array
is computed by using the algorithm
and key specified by the validation
and validationKey attributes of the
machineKey element. By default, the
SHA1 algorithm is used.
Encrypt forms authentication ticket.
The second byte array that has been
created is encrypted by using the
Encrypt method of the
FormsAuthentication class. The
Encrypt method internally uses the
algorithm and key specified by the
decryption and decryptionKey
attributes on the machineKey
element. ASP.NET version 1.1 uses
the 3DES algorithm by default.
ASP.NET version 2.0 uses the
Rinjdael (AES) algorithm by default.
From Microsoft KB
The forms authentication ticket is
used to tell the ASP.NET application
who you are. Thus, ticket is building
block of Forms Authentication's
security.
The ticket is encrypted and signed
using the configuration
element of the server's Machine.config
file. ASP.NET 2.0 uses the
decryptionKey and the new decryption
attribute of the element
to encrypt forms authentication
tickets. The decryption attribute lets
you specify the encryption algorithm
to use. ASP.NET 1.1 and 1.0 use 3DES
encryption, which is not configurable.
Tampering with the ticket value is
determined by a failure to decrypt the
ticket on the server. As a result, the
user will be redirected to the logon
page.
If the application is deployed in a
Web farm, you must make sure that the
configuration files on each server
share the same value for the
validationKey and decryptionKey
attributes in the tag,
which are used for hashing and
decryption of the ticket respectively.
You must do this because you cannot
guarantee which server will handle
successive requests. For more
information about
FormsAuthenticationTicket encryption
and Web farm deployment
considerations, visit the following
MSDN Web site:
So, you can specify what encryption/decryption algorithm to follow and the key. You can use the same decryption logic in PHP.
If you know the decryption algorithm you sure can implement it in PHP.