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.
Related
My Requirement:
I have a Azure Storage Account with 2 containers named Normal and Encrypted.
Now a zip file will be uploaded into "Normal" container which I need to encrypt and place it into "Encrypted" Container.
File can be anywhere between 3GB to 5GB.
Currently, I have used AES CBC with padding PKCS7 (I have not used HMAC). and this works fine. But based on some security concerns, we have found that AES CBC does not provide integrity.
Challenges:
As AES GCM is more secure, I am exploring on how can be the bigger files can be encrypted using AES GCM. If we encrypt in chunks, then for each Chunk different Auth Tag is generating. How can this be addressed? as I need to give Key, IV and Auth Tag for decryption team to decrypt it.
Is it good and is it possible to encrypted 5GB files using AES GCM? If so, can anyone help me out with some example code in C# or link to refer?
If AES GCM is not good for this, then how can I implement HMAC to my AES CBC code. As I am working on Azure Blobs, I am using CryptoStream to encrypt and write the content into "Encrypted" container.
AES-GCM will provide the inbuild authentication (integrity) mechanism. But through this mode, we can only encrypted limited content (say up to 1GB).
AES-CBC will support streaming through CryptoStream class and can encrypt the larger files in chunks without any issue. Only Issue with AES-CBC is it doesn't provide integrity. For this we can add some extra logic to implement HMAC though which we can achieve the integrity.
HMAC - Create SHA256 hash of your encrypted content and pass it to Decryption team. Decryption team needs to validate this hash. Only if Hash is matched, decryption team can proceed for decrypting the encrypted content. Through this, decryption team can ensure that encrypted content is not tampered.
One of the highlight point mentioned here is:
The authentication part of GCM (GHASH) is weaker than HMAC, GHASH provides a maximum 128-bit authentication tag, whereas HMAC allows lot longer tags (HMAC-SHA-256 would allow 256-bit authentication tag). In addition, forgery of GHASH tags in some cases is easier than HMAC
Hence, I went with option of AES-CBC with HMAC encryption.
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
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 have a RESTful API containing a URI of /UserService/Register. /UserService/Register takes an XML request such as:
<UserRegistrationRequest>
<Password>password</Password>
<Profile>
<User>
<UserName>username</UserName>
</User>
</Profile>
</UserRegistrationRequest>
I have the following questions given the above scenario:
Is there a way (using C# and .Net 3.5+) of enforcing/validating that clients calling Register are passing a hashed password rather than plaintext? Is leaving the choice of hashing algorithm to be used to the client a good idea?
We could provide a second URI of /UserService/ComputePasswordHash which the client would call before calling /UserService/Register. This has the benefit of ensuring that each password is hashed using the same algorithm. Is there a mechanism within REST to ensure that a client has called one URI before calling another?
Hope I've explained myself ok.
Many thanks in advance for any help.
Passing a hashed password in a REST service isn't more secure than clear password. If the password gets sniffed it doesn't matter if it's hashed or not, it can be used.
Best thing to do is hash the password on server and accept secure connections only (SSL/https)
It's a bad idea to let clients hash passwords themselves. Generally speaking, hashing only password is not very secure: a random salt has to be appended to the password so that same passwords will produce different hash values. With that, client will have to generate salt (preferably using cryptographically secure algorithm), compute hash of a resulting sting (using compliant implementation of a well-known hashing algorithm) and then send three pieces of information back to the server:
Hashing algorithm name
Salt
Hashed password
What if server doesn't have an implementation of a particular hashing algorithm? What if client hashing algorithm produces different results compared to servers' one?
Now back to your questions:
You can enforce password to be sent in Base64 encoding and then check if this string, converted back to byte array, contains non-printable characters, which are very likely to appear in a hash value. Though they might not be there
You can include some kind of token to a response from ComputePasswordHash and then require your clients to pass this token back to Register
Hashing would not be good idea . A more better would be either use SSL or use a subset of it youself using public key encryption api in .NET framework.
You will expose function GetPublicKey() which will return public key through which user will encrypt his password and send it to you. Then use your private key to decrypt it. And check if it correct. RSA or Elliptic curve base public key alogs are very good. Just use 1024bit.
UPDATE:
check this example as well also this from msdn